|
David Haley wrote:
But, in general, I would say that the stack has a return address, saying where to resume execution, which is a different from knowing "who" called you. That implies to me that the "who" is some kind of object, as opposed to simply a point of execution.
Cheers David,The call frame typically contains additional caller context (over and above the list of incoming argument references), and that caller context typically includes the calling object's identity or handle, and possibly a return address (among other things).
But I didn't suggest using the return address or instruction pointer in my discussion of how Lua might implement "self" references in function bodies. -- I mentioned that the call frame typically contains a reference / identity / handle of the calling object that Lua might use. Thus, in your example ...
function foo(a) -- 'a' is an Account object a.deposit(5) end The return address, as far as 'deposit' is concerned, points to the instruction after the a.deposit(5) statement (which would be a return, I suppose). The return address, for 'deposit', is not the table 'a'.
... the call frame for the call to deposit already contains the identity (object/table reference) of "a" (over and above any arguments that also get pushed on the stack). That is, your "a" Account object is the *immediate* (or nested) caller of the deposit method; as an object, "a" is calling one of its own methods. -- function foo, therefore, is not the immediate caller of deposit (and so the instruction pointer into foo plays no role in identifying "self" withing the body of a's deposit method).
Instead, the call frame for deposit would contain the reference to immediate caller "a" regardless of whether "a" is passed as an extra argument (hence, why bother with any "hidden" argument implementation). The presence of the immediate caller's identity is generally in the call frame whether or not you are using a traditional "function" or an "OO method" type call.
And therefore within the body of the deposit function / method, any reference to "self" could be implemented as a reference to the immediate caller "a" stored in the call frame -- i.e. without the need to use self arguments in the call or self parameters in the definition.
This, again, is roughly similar to the implementation of explicitly defined local variables, which are not found in the argument list on the stack, but they are (in typical implementations) found in the larger call frame on the stack. C allocates so-called automatic local variables in the call frame this way, if memory serves me well, over and above any incoming arguments. And since "self" in Lua is just a special local variable, it doesn't need to be implemented as a hidden argument. (Notwithstanding that we might be able to use meta tables to redefine "self" as "foo" -- regardless, the semantics of self do not require "hidden" argument implementations or colon syntax.)
Therefore, because "self" refers to the immediate object/table caller, the reference should be readily available in the call frame (even in a computed object case), and no colon operator would be needed to signal the interpreter to look for "hidden" arguments.
At least that's my (hopefully) educated assessment of a colon-free syntax alternative.
// Brian