lua-users home
lua-l archive

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


In scripts intended to be compiled, a global keyword together perhaps with
checking the global environment in which the script was being compiled would
resolve most of the need for lint tools such as the one we've built
internally. (The reason to think about checking the global environment is
that you probably don't want to start all scripts with "global require" or
maybe you do...)

On the other hand, for interactive coding, one probably needs a
global-by-default option unless pre-existing globals are considered valid.
Otherwise executing the following chunks in sequence:

Chunk 1:
    global foo = "Hello"

Chunk 2:
    print( foo )

Will fail because foo won't be defined as a global in the second chunk and
you would probably throw your machine against the wall if you had to type:

    global foo; print( foo )

Just to print the value of foo.

Mark

on 8/5/05 9:23 AM, Chris Marrin at chris@marrin.com wrote:

> 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...