lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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)