lua-users home
lua-l archive

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


OK, my S/0.02 worth.

It took me a few minutes to see the problem with local bar = function ...
and you're quite right, that's a bugtrap.

And I agree that making the function local is *probably* what the author
would have wanted.

Nonetheless, I don't like the idea of having one default for function and a
different default for variables. Furthermore, one notes that it is
apparently possible to put

local a = 7

at the top level of a file (or chunk) making it local for the duration of
the chunk.

It therefore seems reasonable to me to add the syntax:

local function f(args) body

which would mean exactly the same as

local f
f = function(args) body

I would also argue for the syntactic inclusion of

global v = 7

and

global function g(args) body

in parallel, in case (a) someone wants to make a point or (b) some day the
default scope changes.

Rici.

PS: I'm not actually crazy about changing the default scope to the minimum
scope. I'd rather have the default changed to "chunk local". In this case,
both the local and global modifiers would be required, and it would open
the opportunity to allow the option of strict declarations.
-----------------------------------------------------------
Hi,

with the implementation of full featured lexical scoping in Lua 4.1
I would suggest a change in the semantics of the function statement:

  A function statement with a single identifier as the functions
  name makes the name implicitly local.  That is:

    function name(...

  has the semantic of

    local name
    name = function(...

  The semantics with complex names (x.name etc) stays the same.



The reason I suggest this change is that the current behavior is not
what you would normally expect.  Namely:

  function foo()
    ...
    function bar()
       ...
       bar()
       ...
    end
    ...
    bar()
    ...
  end

While this works as expected, bar becomes a global function and this
is not what you would expect.  It may result in hard to find bugs when
i.e. foo or bar call a function that itself creates a helper function
named bar.  When trying to work around this problem, people may try
this:

  function foo()
    ...
    local bar = function()
       ...
       bar()
       ...
     end
     ...
     bar()
     ...
  end

But this will _not_ work: The local bar will not be visible while the
initialization expression is evaluated so the first (recursive) call
to bar will use the global variable bar while the later call will take
the local bar.  The real solution to this problem is:

  function foo()
    ...
    local bar
    function bar()
      ...
      bar()
      ...
    end
    ...
    bar()
    ...
  end

And IMHO this is what should be the default.  I can't think of very
much cases where you really want a nested function statement to create
a global function.



Now, what about function statements in the top level chunk (main) and
how to define global functions?  One may be tempted to restrict my
proposed change to nested functions.  But I would not do so because
of three reasons: first, by making top level functions local too means
that each file by default will have it's own namespace for functions.
You have to perform explicit actions to export a function.  Second,
access to locals is faster than access to globals.  And at last,
restricting the local behavior to nested functions make the rules
non-uniform, more complicated, and may give other problems.

So, how do you create global functions?  Two methods; either use the
normal assignment syntax:

  foo = function()
    ...
  end

or, what I would prefer, introduce a global variable named 'global'
that holds the global table (global=globals(), exported by baselib)
and then write:

  function global.foo()
    ...
  end

That way you immediately see which functions are local and which are
global.



So, what do you think about this proposal?  Discussion opened :-)

Ciao, ET.