lua-users home
lua-l archive

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


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