lua-users home
lua-l archive

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

Eero Pajarre:
> Btw. I became curious about what Peter had suggested year ago. I think
> that what he wanted (protected datatypes in Lua)...

Do you mean the idea of making true Abstract Types by hiding the
internals with some sort of locked tags as a key? Ie:
- tags (which are only meant to be creatable by "newtag") became a core type
   to prevent faking them.
- to change the tag of an object required having access to the original tag
   as a key [eg, settag(obj,new_tag,old_tag)].
- to get at the internals of the object also required the key [eg,
   rawget(obj, index, tag)].

If so, you've got a good memory! I didn't think at the time that anybody
even noticed the suggestion.

> ...might be implementable with closures. Create an object which has its
> internals in a closure, which can only be accessed by the interface
> functions, hmmm, I don't know if there are any holes here.

I'm having trouble trying to imagine a way to get the same functionality
(which doesn't mean it can't be done of course!). As an example, let's try
to implement complex numbers as an abstract type. With the tag-key method we

  -- A new tag as a key,  inaccessible to external functions.
  local k = newtag()

  -- Note that changing the basic tag-type should disable normal indexing,
  -- so "a=complex(1,2); print(a.real)" will generate an indexing error.

  function complex(r,i) -- constructor
    local c = {real=r, imag=i}

    -- Note that no 3rd argument (key) is needed to change the tag
    -- since 'c' is initially untagged.
    return settag(c,%k)

  function cadd(a,b)
    local r, i, c

    -- need the key to get the internals.
    r = rawget(a,"real",%k) + rawget(b,"real",%k)
    i = rawget(a,"imag",%k) + rawget(b,"imag",%k)

    return complex(r,i)

x = complex(1,2)
y = complex(3,4)
z = cadd(x,y)

print(x.real) -- generates an error. The internals of the table are
protected by the tag.

Björn De Meyer:
>> ...might be implementable with closures
> You mean something like this?
> myobject = {};
> function myobject:init()
>   local x , y , w , h,  string = 5, 5, 20, 10, "Hello"
>   -- the "private" variables of the object
>   self.getx = (function(self) return x; end)
>   -- Add a get method
>   self.setx =
>   ( function(self, val)
>       if val < 0 then
>         print("X must be greater than 0")
>         else x = val;
>       end
>     end
>   )
>   -- And add a set method.
>   self.print =
>   ( function(self)
>       print(x,y,h,w,string);
>     end
>   )
> end

This seems to create a set of functions for every object instance!

I can see I need to research the implications of the new "setglobals",
lexical scope, and metatables.

As a general question...

What did people generally use (a) upvalues and (b) tag methods for?

What were the forces / desires that have generated the new (a) setglobals
(b) lexical scope and (c) metatables... and how well are they achieving
those goals?

Peter Hill.