Egor Skriptunoff
2018-07-04 05:26:18 UTC
Hi!
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?
1)
"$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).
2)
"$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
:-)
3)
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".
4)
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
end
5)
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?
-- Egor
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?
1)
"$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).
2)
"$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
:-)
3)
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".
4)
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
end
5)
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?
-- Egor