[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Colon Operator: Superfluous Syntax?
- From: Brian Hagerty <Brian.Hagerty@...>
- Date: Thu, 15 Mar 2007 02:31:43 -0700
David Haley wrote:
> I agree that you could conceivably detect the use of 'self' in a
> function definition and deduce that there is a hidden
parameter, thereby
> obviating the need for the colon in the function definition.
>
> However I'm not sure how this would work for calling methods.
If I were
> to write,
>
> a.deposit(3)
>
> How does Lua know that deposit is a "method" and therefore
the call
> should be translated to a.deposit(a,3)? That would entail
tables storing
> not only the functions, but also extra data about the
functions, like
> "this one is a method", "this one isn't". And it would also
entail
> checking that meta-datum every time you call a function.
> ...
> How would you solve this problem? That is, how would you tell
whether or
> not a dot-syntax call should pass the table along as a first
argument?
That's an excellent question ... The short answer is that Lua
doesn't need to translate to a.deposit(a,3), nor does Lua need
to sore any extra information to say "this is a method".
Long answer:
Actually, the implementation would be very clean (probably no
change to any table or function meta data at all). The key is
not to think of "self" as a *parameter* in the function
definition or as an extra *argument* in a function call.
That parameter/argument syntax is just a leftover mindset from
traditional function-oriented languages. We tend to think the
only way to transmit information is via the function
*arguments*. Not that we get rid of that, because we still need
it for "proper" parameters/arguments -- but we don't need it for
"hidden" parameters or "translated" arguments.
In practice, the typical implementation of function calls,
including in Lua, is to push a "call frame" (caller context and
meta data) on to the stack *before* pushing the list of proper
arguments. That "call frame" always has a reference to the
caller (so that when return is called in the function the
computer knows where or to whom to return).
So the information about "who called this function/method" is
already available in the call frame (and already available in
Lua's function call implementation). -- No "self" argument needs
to be stuffed as an argument in the call(), or listed as a
formal parameter in the definition, or treated as a "hidden"
parameter.
Instead, the mere use of "self" in a function body would refer
to the self/caller already found in the call frame, not to an
argument in the stack of arguments. So the only real difference
is that a classic (non-OO) function does not refer to a "self"
object, whereas an OO-like method does refer to a self object.
"Self" (the caller) is already found in the call frame, and is
not needed in the argument stack.
This is basically how all local variables (non arguments) are
handled -- i.e. local variable (non arguments) are not found in
the argument stack, they are found in the call frame. Since
self is just a special local variable, it does not need to be
defined in a parameter list at definition time, nor does it need
to be pushed on the argument stack at call time to be available
at runtime.
Here's a quick summary: When a function body references self, it
looks for it in the call frame (where the caller is always
referenced), not in the argument stack. If you don't reference
self, you're a classic "function"; if you do reference self,
you're an OO "method".
// Brian