lua-users home
lua-l archive

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

On Tue, Jul 3, 2018 at 10:26 PM, Egor Skriptunoff <> wrote:

Let me start (n+1)-th thread about "global by default" feature of Lua.
My suggestion is to replace "global by default" approach with "nothing by default" by introducing special syntax for accessing global variables:
$print("Hello world")    -- ok
print("Hello world")     -- syntax error: referencing undeclared variable "print"
_G.print("Hello world")  -- syntax error: referencing undeclared variable "_G"
"$" is not a part of an identifier.
"$" is a lexem (for example, there could be a space between "$" and global variable name).
"$" is absolutely the same as "_ENV." but is more comfortable to use.
Why do we need this?
"$globalvar" notation introduces two separate namespaces: one for globals and one for locals/upvalues.
As a result of this separation, most of variable name typos will be detected at compile time.
Although global name typos will not be detected ($math.sin -> $moth.sin), the most of identifiers in properly-written Lua programs are locals.
Currently, writing Lua programs without "global-nil-alarmer" (such as "strict.lua") is practically impossible (because typos in local variable names are silently converted to globals).
"$print" contains more symbols than "print", and you have to press SHIFT on your keyboard to type "$", but this is not a drawback.
Instead, there is a point in it: users would have to pay attention to slow global access.
More finger moves = more CPU time to access.
So, we are adding "ergonomical motivation" to cache globals in Lua programs :-)
Polluting of global namespace is already discouraged in Lua, so introducing "$" prefix for globals is the next step in that direction.
It is a polite way to say: "use globals only when they are really needed".
The "$globalvar" notation will solve problem with globals occasionally shadowed out by locals or upvalues:
local function sort_desc(table)
   table.sort(table, function(a, b) return a>b end)  -- very popular newcomers' mistake
The "$globalvar" notation will make the difference between "monkey-patch-friendly code" and "monkey-patch-unfriendly code" more easy to see.
BTW, "_ENV" could be removed from Lua as "$" could do the same (with some modifications in the parser to interpret "$" either as "_ENV." or as "_ENV"):
$print()           -- instead of print()
$.print()          -- instead of print()
local env = $      -- instead of local env = _ENV
$[key] = value     -- instead of _ENV[key] = value
function sndbx($)  -- instead of function sndbx(_ENV)

What are your thoughts on this?

I'm just now reading about Lua in Garry's Mod and it seems to me they've "polluted" the global space with this thing called an API. I don't know anything about the details yet but it looks pretty handy. Tee hee. All joking aside, I avoid using global but I "don't know why" (do I dare conjure C++ namespaces in the discussion?). Personally, if I wanted a way of not typing 'local' all the time, I would prefer to see a keyword at the top of a file such as "$LOCAL_DEFAULT" and then have to type 'global' to alter the scope, but I suspect has already thought things like that through and rejected the idea. A nice use case for LHR's lptoken.

I'm not fond of _javascript_ scope shenanigans. I think simple (explicit) is good in scope declaration and strict is our friend; though I don't often use strict and suffer the consequences.


-- Egor