> My suggestion is to replace "global by default" approach with "nothing by default" by introducing special syntax for accessing global variables:
While the desire to do away with implicit globals is perfectly understandable and probably shared by many users of Lua, the proposal introduces strong incompatibilities. The $ prefix seems, to me, like an ugly wart purely aesthetically, plus on some keyboards fetching the dollar sign can be complicated.
But perhaps there is no need to reinvent the wheel in this area.
A popular family of programming languages, BASIC, stared off with implicit declaration of variables. Later at some point it was realised that the implicit declaration was problematic, and the OPTION EXPLICIT statement was added t the language. It was opt-in originally. In some later derivatives such as Visual Basic, it works as follows:
If OPTION EXPLICIT ON/OFF is present in a module, then it controls the declaration mode in that module.
Otherwise, it is controlled in "project settings" or "command line".
Now, Lua is not BASIC, but I suggest that the following scheme might work:
1. Any Lua state has an explicit/implicit global declaration setting. The default 'explcit' vs 'implicit' is a constant chosen when compiling the Lua engine, with 'implicit' by default, so that existing code is fully unaffected by this.
2. The global declaration setting can be changed through C API. It is debatable whether an equivalent of the API should be available in the Lua land.
3. Any API, C or Lua, that allows loading/compiling a Lua chunk gets an optional parameter that controls the global declaration mode while compiling that chunk.If the declaration mode argument is specified, it overrides the Lua state's declaration setting, while compiling that chunk. Otherwise the Lua state's setting applies.
4. It is debatable whether the declaration mode parameter should have a flag such as "make this the default declaration mode when that chunk loads further chunks".
5. A new statement is provided so that the global declaration mode can be specified within a Lua chunk (similar to OPTION EXPLICIT in BASIC). If it is present, it overrides the effective declaration mode within the chunk (when compiling the rest of the chunk). It is debatable whether this statement needs to be scoped, and whether it can be specified multiple times within a chunk, and whether it could be inherited by chunks loaded from this chunk (c.f. #4).
6. A new statement is provided to declare globals.
7. During compilation, when the effective declaration mode is explicit, and an identifier is encountered that has not been declared previously as a global or as a local, a compile time error is raised.
Today, syntax like "not local something" is ill-formed.
8. The new statement "not local = explicit" sets the explicit global declaration mode. I further suggest that 'explicit' in that statement should not by itself be a reserved keyword outside the statement.
9. The new statement "not local = implicit" sets the
global declaration mode. I further suggest that '
' in that statement should not by itself be a reserved keyword outside the statement.
10. The new statement "not local foo, bar, etc" declares foo, bar, etc as global variables. Note it is only a declaration, it does not initialise the global variables in any way.
With this syntax, globals would be slightly more verbose to declare than locals, which I think is a good thing. Other than this, once declared, they would not be any different from today's globals in use.
This proposal is fully backward compatible as far as I can tell, and it allows both opt-in and opt-out for implementations.