lua-users home
lua-l archive

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


The problem with inside-out objects is the susceptibility to weak- table-based cycles. I gather those are being addressed in 5.2, but I don't know at what cost. Certainly it is easier to reason about the connection graph using tables in a more traditional fashion. Furthermore, private keys remain eligible for all of the other Lua mechanisms like metamethods -- for example, we can continue to use __index for inheritance rather than also using it for data hiding.

Also note that your inside-out version is much the same as my version without the label construct but with private keys. Both change the way one does field access away from the standard dot notation.

Mark

On Dec 17, 2008, at 6:26 PM, David Manura wrote:

On Wed, Dec 17, 2008 at 4:33 PM, Mark Hamburg wrote:
So, now we can write:
      label _angle, _radius
      function Point( x, y )
              return {
                      _angle = math.atan2( y, x ),
                      _radius = math.sqrt( y * y + x * x ),
                      coordinates = function( self )
return self._radius * math.cos( self._angle
), self._radius * math.sin( self._angle )
                      end
              }
      end

You can achieve a similar effect with "inside-out objects"[1-2] via
Lua's support for weak keys.  Example:

local radius = setmetatable({}, {__mode = 'k'})
local angle  = setmetatable({}, {__mode = 'k'})

local function Point(x,y)
 local self = {}
 angle [self] = math.atan2(y,x)
 radius[self] = math.sqrt(y*y + x*x)
 function self:coordinates()
   return radius[self] * math.cos( angle[self] ),
            radius[self] * math.sin( angle[self] )
 end
 return self
end

This is at a cost of one table per attribute per class rather than one
table per object.

Also, since radius and angle are lexical variables, means of
compile-time detection of undefined variables[3] can detect
mispellings[2].  For example, "radus[self]" shows up as an access to
the global "radus" in a "luac -p -l example.lua | grep ETGLOBAL".