lua-users home
lua-l archive

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


Mike Pall wrote:
...
The reason is that 'local by default' does not mix well with
lexical scoping. The languages that use this either do not
have proper lexical scoping (and thus don't have the problem)
or need some ugly workarounds. It's a common language design
mistake (IMHO).

Proper lexical scoping really requires that you have a choice
between mutating a binding (assignment) and creating a new
binding (declaration). Alas, the 'local by default' rule mixes
them and makes an assignment do both. Consequently you cannot
modify a variable in an outer scope with a simple assignment
(because that would create a new local variable with the same
name).

I long ago made my peace with this issue in working with Javascript. I agree with the above analysis that making the rule be local-by-default would be a mistake. My concern has always been that having a default rule at all is very error prone. Writing this function:

    function foo(bar)
        a = bar + 12
        return a + 5
    end

works as intended. But my intent here was actually to have a local variable 'a' store an intermediate result. But all is well for now, the error is benign. Then I write another function:

    function baz(blah)
        a = blah + 6
        return a +4
    end

My intent is the same, I am storing an intermediate value in 'a'. But everything still works just fine. Now I change foo():

    function foo(bar)
        a = bar + 12
        b = baz(bar)
        return a + b
    end

and everything falls apart. The global 'a' got changed as a side effect of the call to baz() and the value returned from foo is wrong. This is very difficult to track down because I am a naive script author and I actually don't even know that there is such a thing as local! And even if I do, the fact that everything works without error until I make this small change makes it very hard to debug.

It seems like the solution is to not have any default at all. You would have a 'global' keyword to declare a global variable. That way, the above example would give errors on the first assignment to 'a'. I would see the mistake and add a 'local' keyword and all would be well.

Even without getting rid of the global-by-default rule, a global keyword would help with making the code more clear. It would enable the writing of a lint program for Lua which could warn of undeclared globals. You could add a global keyword and get rid of the warning. In the runtime, this keyword would be a nop. This lint facility could even be easily added to the lua compiler as a command line flag.

Just something to think about...

--
chris marrin                    "As a general rule,don't solve puzzles
chris@marrin.com                 that open portals to Hell" ,,.