[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: __method metamethod
- From: Coda Highland <chighland@...>
- Date: Fri, 19 Jul 2013 17:59:37 -0700
On Fri, Jul 19, 2013 at 5:51 PM, Coda Highland <chighland@gmail.com> wrote:
> On Fri, Jul 19, 2013 at 5:31 PM, Greg Fitzgerald <garious@gmail.com> wrote:
>> On Fri, Jul 19, 2013 at 4:02 PM, Javier Guerra Giraldez
>> <javier@guerrag.com> wrote:
>>> local f = o:m
>>>
>>> as syntax sugar to:
>>>
>>> local f = function(...) return o.m(o, ...) end
>>
>> That would be a good addition too.
>>
>>
>>> i think it's better than Greg's proposal because it doesn't magically
>>> changes the meaning of an existing operator (dot)
>>
>> That's not exactly fair. It magically changes the dot operator in the
>> same way the __index metamethod magically changes the dot operator.
>> Both are tucked under the hood. From the user's perspective, the same
>> code could have just as easily been written with no metamethods at
>> all:
>>
>> local funcs = {
>> inc = function(self)
>> self.a = self.a + 1
>> return self
>> end
>> }
>>
>> local function new(t)
>> local o = t or {a = 0}
>> for k,f in pairs(funcs) do
>> o[k] = function(...) return f(o, ...) end
>> end
>> return o
>> end
>>
>> assert(new().inc().inc().inc().a == 3)
>>
>>
>> Using the __index metamethod is a handy way of exposing a Lua library
>> with the familiar syntax of JavaScript, Python, Java, etc. Using this
>> proposed __method metamethod is a technique for getting that syntax
>> without the performance regression.
>>
>> -Greg
>>
>
> Overloading : to work when not coupled with a parameter list is the
> better solution. It's still important to be able to access the unbound
> version of the method, so you want x.y to still return the unbound
> version, and you don't want to overload the behavior of . any more
> than it already is. Meanwhile, : without a parameter list is currently
> a syntax error, so adding it would cause no incompatibilities and
> minimal overhead (there would still be a __method dispatch on a:b()
> where there wasn't one before, but that overhead can be brought down
> to just a single comparison by requiring that __method be defined on
> the metatable already when setmetatable is called).
>
> That said... I'm not convinced that it would be anything more than
> syntactic sugar. Adding "bound functions" that aren't closures to the
> language... well, I can see how it could be done with less overhead
> than defining a closure, but would it actually make a substantive
> difference, and could it be done CLEANLY?
>
> It sounds to me like this is the time to put one's money where one's
> mouth is and put together a patch so that it can be tested instead of
> merely speculated upon.
>
> /s/ Adam
Upon further reflection, I think __method may not even be necessary.
The proposal seems to say that "local x = y:z" ought to mean "local x
= getmetatable(y).__method(y,z)", analogous to how "local x = y.z"
means "local x = getmetatable(y).__index(y,z)".
But instead, "local x = y:z" could be defined to have behavior
equivalent to "local x = function(...) return
getmetatable(y).__index(y,z)(y, ...) end". (I say "equivalent" because
of course it could be generating a special bound-function object
instead of a closure.) This avoids the need to create a new metatable
entry or new dispatch rules, and it makes "a:b()" perform exactly the
way it already does.
I'm still not convinced that this is NECESSARY, but if it were to be
implemented, I think this would be best.
/s/ Adam