lua-users home
lua-l archive

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


Node  = class{}
function Node:new()
  ...
Leave = class{}:is_a(Node)
function Leave:new()
  Node.new(self)
  ...

So I guess in that case, one shall detect that caller in frame shall be
set to self and not Node. But this may be a little late to detect from a
parser point of view. Then would you prefer such syntax?

Node = class{}
function Node.new()
  ...
Leave = class{}.is_a(Node)
function Leave.new()
  Node:new()
  ...

It is maybe closer to C++/Java habits, but it becomes very disturbing to
the current lua users... So what is the best, let newcomers be used to :
or
spoil lua code base? I don't know how much bugs are occurring because of
using ':' instead of '.' or the opposite and how late they are detected.
I guess a syntax change would only have a chance to be accepted if it
gives huge performance improvments or if it is a huge source of bugs
even for trained programmers. 

By the way, couldn't we add a ruby like syntax sugar '@' for self.? 
It is very addicting to ruby users... and I understand that this is
appreciable conciseness.

-----Original Message-----
From: lua-bounces@bazar2.conectiva.com.br
[mailto:lua-bounces@bazar2.conectiva.com.br] On Behalf Of Brian Hagerty
Sent: Thursday, March 15, 2007 10:32 AM
To: Lua list
Subject: Re: Colon Operator: Superfluous Syntax?

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