[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: More functional thoughts (Was: vectors and Lua)
- From: RLake@...
- Date: Mon, 30 Jun 2003 12:04:50 -0500
Mark Hamburg escribió:
> One problem with this approach is that it is less "natural" than the
value
> semantics version. For example, a lot more people would probably be
> comfortable writing:
> position.x = PinToGrid( position.x )
> Than writing:
> position = postion:setX( PinToGrid( position.x ) )
> Even without the direct assignment, you'd probably get lots of people
> writing and then debugging:
> position:setX( PinToGrid( position.x ) )
Wouldn't it be more natural to write the following?
pinned = PinXtoGrid(position)
This is basically the same semantics issue as you have with gsub. If
you're used to mutable strings, you are perhaps tempted to write:
string.gsub(name, "%l", string.upper)
instead of
name = string.gsub(name, "%l", string.upper)
but I haven't seen much chatter about that on this list, so I assume that
it is not much of a problem.
By analogy, I suppose the primitive could be:
pinned = vector.vsub(position, "@x", vector.PinToGrid)
or some such.
Actually, that could be cool:
pinned = vector.vsub(position, ".", vector.PinToGrid)
------ Re: temporary objects
It is certainly the case that temporary objects mount up. One solution can
be found in the functional implementation of tuples, using functional
composition to avoid creating temporary objects.
ej: (as before)
function vector(_x, _y, _z) return function(fn) return fn(_x, _y, _z)
end end
-- and now:
function vunpack(_x, _y, _z) return _x, _y, _z end
function scaleBy(q)
return function(_x, _y, _z) return q * _x, q * _y, q * _z end
end
function subtractPoint(v)
local x, y, z = v(vunpack)
return function(_x, _y, _z) return _x - x, _y - y, _z - z end
end
function addPoint(v)
local x, y, z = v(vunpack)
return function(_x, _y, _z) return _x + x, _y + y, _z + z end
end
function rotateBy(theta)
local sintheta, costheta = math.sin(theta), math.cos(theta)
return function(_x, _y, _z)
return _x * costheta - _y * sintheta, _x * sintheta + _y * costheta,
_z
end
end
-- from which we can compose:
function transform(centre, expand, theta)
local a, r, sc, s = addPoint(centre), rotateBy(theta),
scaleBy(expand), subtractPoint(centre)
return function(_x, _y, _z) return a(r(sc(s(_x, _y, _z)))) end
end
> centre = vector(2, 2, 2)
> point = vector(3, 3, 7)
> xform = transform(centre, 2, math.pi / 4)
> =point(xform)
2 4.8284271247462 12
> =gcinfo()
32 38
> for i = 1, 100000 do point(xform) end
> =gcinfo()
33 38
I accept that it takes a while to get the hang of this sort of thing.
With an explict compose operator, the syntax is a lot cleaner:
xform = addpoint(centre)