lua-users home
lua-l archive

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




RLake@oxfam.org.uk escribió una vez:
> >
> > As I understand it from the correspondence (and no doubt Edgar will
correct
> > me if I'm wrong), in his unified methods implementation,
> >
> > a:foo(x)
> >
> > is "syntactic sugar" for:
> >
> > methods(a).foo(a,x)
> >
> > where methods(a) is some sort of metamethod, I would guess.

y replicó Edgar Toernig <froese@gmx.de>:

> It's a low level function that extracts the associated method table
> that _each_ object has (it's a field in the low level data structures).
> You can set it with methods(x, table).


> > (Or perhaps it works recursively, which might be cool if confusing.)

> Of course.  methods(methods(x)) works well and is actually used in Sol's
> class system:

Umm, that's iteratively, not recursively. But it's still cool :-)

> methods(x) is the "class table" that describes what can be done with x.
> method(method(x)) is the "super class table" that describes what can be
> done with "class tables" (creating instances and subclasses, perform
> inheritance, ...).  And the "super class table" itself is a regular table
> with no fancy features so methods(methods(methods(x))) is the same as
> methods({}).  Confusing, isn't it ;-)

Yup, a little. I would have thought that methods(methods(methods(x))) would
be the same as methods(methods(x)), but that's probably because I'm
thinking in another language. (that is, if classes are themselves
first-class objects then the class of any class should be Class, and
therefore the class of Class is Class, so you should reach a fixed point in
the iteration.)

What I meant by recursive was the method(x) might itself be a method so one
could define an object which represented class tables in some other manner
(perhaps computing them on the fly) using the unified method equivalent of
a getclassmethod tag method.

> > Another alternative would be for
> >
> > a:foo
> >
> > to be "syntactic sugar" for:
> >
> > curry1(methods(a), a)
> >
> > where curry1 is a language primitive

> Actually, the ':' is the low level primitive to access the method table.
> Where a.x access field x from a, a:x access field x from methods(a).  So
> this is valid:

> a:x = a:x + 1
> a:x:y.z = 42
> a:x = function(...)...end
> function a:x(...)...end

> The syntactic sugar comes in when a:x is used as for a function call.
> In that case, a self is automagically added as the first argument.  To
call
> a method without inserting the object as arg1 you have to use
parenthesis.

I'm not sure that I'm crazy about that. But I understand the motivation. I
assume that when you say "you have to use parenthesis", you mean something
like:

(a:x)(b, c)


> >[...]
> > a<<x>>         is defined as  getmethod_event(a, x)
> > a<<x>> = v     is defined as  setmethod_event(a, v, x)
> >
> > Taking this additional step makes the optimisation referred to above a
> > little harder to do, since we can no longer rely on a->x returning a
curry.

> Actually, for Sol's first version I really started to introduce a
> getmethod and setmethod event for this (and indexmethod and newmethod).
> Put I dropped it pretty fast.  While it allows you to differentiate how
> the access to a table is done it introduces much too much complications
> and inconsistencies.

Interesting... I'll have to think about it some more...

> You get all these fancy features with a 3 level architecture as described
> above (object, class table, super class table).  When you try to read a:x
> you check the gettable and index methods for a's method table; it's a
> regular table after all, so why not check it's index/gettable method
> when a field is requested?  So a:x invokes Super.index(a,x) if x is not
> present (Super is the super class table) or even Super.gettable(a,x)
> for every x if Super.gettable is present. [1]

That makes sense. In fact, I have somewhere kicking about some C code which
pretty well does that without altering the grammar of Lua (however without
altering the grammar of Lua you can't divide namespaces, so it's really
only practical for userdata).

The catch is the "automagic" of a:x(..) which is pragmatic but a bit odd.
The solution I presented is probably more complicated to implement
efficiently, but involves less magic. Or at least different magic. Anyway,
it was neither an implementation nor a fully-thought-out concept, just an
idea so I won't argue for it.

Have you looked at NewtonScript at all? Or even AppleScript? (AppleScript
is/was(?) one of the great undersold ideas that came out of that benighted
company; NewtonScript has its own charm, too.) Much earlier than Chash, and
in common I think with some other OO implementations, NewtonScript
implemented a really interesting method/field inheritance structure which
allowed one to build up individual and idiosyncratic objects without
incurring huge overheads (particularly memory, given the context in which
it was intended to run).

R.