Say No to global-by-default (summary of the discussion)

classic Classic list List threaded Threaded
34 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Say No to global-by-default (summary of the discussion)

Egor Skriptunoff-2
Hi!

Last time I proposed "$" prefix because some programming languages (Perl, bash, PHP) have variable names prefixed with "$".
But it seems some people dislike any similarities with Perl :-)
"$" was also criticized because it requires pressing SHIFT on a keyboard, and programmers are usually lazy (laziness is the first great virtue of a programmer, according to Larry Wall)
Ok, let's stop talking about Perl  :-)
 
This time I show another possible prefix: the backslash.
Backslash is not used in Lua syntax (except inside quoted strings), so why not?
Anyway, the choice of prefix ("$", "@", "\",...) or postfix or another syntactical way is pure aesthetic/bikeshedding; it doesn't actually affect my suggestion.
 
My suggestion is the following:
 
   A programmer must explicitly (by means of special syntax) say to compiler whether each variable reference is global or not.
 
The following examples assume globals are prefixed with backslash, and locals/upvalues are not prefixed:
 
   print"Hello"                  -- error: unknown local/upvalue "print"
 
   \print"Hello"                 -- ok
 
   function print()              -- error: unknown local/upvalue "print"
   end
 
   function \print()             -- ok
   end
 
   local func1
   function func1()              -- ok
   end
 
   local function \func2()       -- error: global identifier in local definition
   end
 
   function math.atan2 (y, x)    -- error: unknown local/upvalue "math"
   end
 
   function \math.atan2 (y, x)   -- ok
   end
 
   \math.atan2 = \math.atan      -- ok
 
   local \bit32 = {}             -- error: global identifier in local definition
 
   local function func3( \x )    -- error: global identifier in local definition
   end
 
 
Q#1:
How this would be useful?
 
A:
1) All typos in locals/upvalues would be detected at compile time.
2) Globals would never be occasionally shadowed out by locals.
 
 
Q#2:
I want to see how my old scripts would look in globals-backslashed style.
 
A:
There is a convertor from "source text" to "globals-backslashed source text":
https://gist.github.com/Egor-Skriptunoff/c2d1bd8b5348ab3ed59991a9dda7ed5c
 
 
Q#3:
This suggestion may be useful only for those who write long Lua scripts where locals/upvalues are accessed much more frequently than globals.
But I use Lua for writing config/embedded/DSL scripts (short scripts working with API exposed to Lua as global variables/functions), so I almost never use local variables.
Or maybe I simply want to write small quick-and-dirty Lua program to execute it only once in my life.
Or probably I use Lua in REPL sessions.
The "globals-backslashed" suggestion would inconvenience me.
 
A:
Globals-backslashed style should be optional.
Lua should accept both formats of source text: old style and globals-backslashed style.
I suggest both these formats to coexist in all future versions of Lua.
Support of old style should never be dropped.
So, if you don't have benefits from globals-backslashed style - just don't use it.
 
We already have two formats of Lua chunks: "source text" and "bytecode".
There are absolutely no problems with mixing different formats in a single project: "source text" chunks can require/dofile/dostring "bytecode" chunks and vice versa.
Actually, I suggest to add the third format: "globals-backslashed source text".
The chunk loader (load/lua_load) can auto-detect new type of chunk: if chunk doesn't start with "\27" and does contain at least one identifier prefixed with backslash then it's of type "globals-backslashed source text".
 
This way, introducing of globals-backslashed style would not break compatibility with existing code (and with existing habits of Lua users).
 
 
Q#4:
Now whenever I look at Lua code the first thing I have to do is figure out if it is genuine Lua, or backslashed-Lua.
 
A:
If your eyes made incorrect decision about whether the source is genuine or backslashed, and you add some modifications to this source, you would be informed at compile time.
This mistake would never go to runtime.
Anyway, you could convert any script to your favorite style before modifying it.
 
 
Q#5:
Is it natural to introduce syntactical difference in Lua between globals access and locals access?
 
A:
Global objects are usually either Lua standard libraries or API provided by host application.
In other words, globals are created not by you, semantics of global objects is fixed and documented.
On the opposite, locals/upvalues in your scripts are created by you, their semantic is 100% under your control.
This semantical gap between globals and locals deserves explicit syntactical distinction.
 
The other reason why globals are special:
Globals have very wide scope (all the files in your project), so values of globals may be modified by external functions invoked from your script.
On the opposite, locals/upvalues are always under control of your script.
So, the leading backslash acts like warning indicator: "be careful, this variable is not under your control, it may have changed its value inexpectingly"
For example, this syntactical warning would help you to pay more attention to compatibility of your script with monkey-patching.
 
 
Q#6:
To solve the problem of typos Lua already does provide some abilities such as setting metatable on _G or setting _ENV=nil.
 
A:
The only thing we could do in Lua 5.3 is various forms of "runtime alarmer".
A runtime alarmer defers error detection to runtime (which is bad) and couldn't guarantee 100% coverage (what about typos in inactive "if" branches?).
IMO, the problem "the compiler silently ignores all variable name typos" does worth introducing some minor changes in the language to solve it.
It's the expectation of many programmers that a compiler should check for misspelled identifiers and warn the user at compile time.
The silence of the compiler is "just an invitation to bugs due to spelling mistakes", as Axel said.
 
 
Q#7:
This is not really necessary, just use luacheck systematically to find typos and inadvertant globals.
Or use special IDE (ZBS) that highlights all global access.
Or write your own static analyzer that get pedantic about unknown global access.

A:
IMO checking for misspelled variable names is quite important to be inside Lua core.
 
 
Q#8:
The distinction between compile-time and run-time is illusory in any interpreted language that offers a function like "load".
 
A:
Most of mistakes are located in usual hand-written code which is accessible for static code analysis.
Scripts being generated on-the-fly are definitely not the main subject to linting.
But anyway, globals-backslasing-style could be used in "load"-ed code to help reducing error-detection-delay.
 
 
Q#9:
I am not a believer in Hungarian notation. Making it part of any language is the silliest thing I could think about.
 
A:
The "Hungarian notation" is just an instrument, it is not a subject to believe or afraid of.
Actually, "Hungarian notation" is one of possible ways to split namespace.
Splitting a namespace might be good or bad, it depends.
IMO, splitting variable namespace into two: globals and locals, would be good in Lua.
 
 
Q#10:
Understanding and debugging someone else's code is a PITA in any language, period.
No amount of special symbols on global variables is going to change that.
 
A:
IMO, splitting variable namespace would help to make understanding of other people's code a bit easier.
 
 
Q#11:
Give me as few restrictions as possible on identifiers and if I feel I need a naming scheme, I can create one myself.
 
A:
No, you can't, because the compiler wouldn't be aware of the naming scheme "created" by you.
For example, if globals in your naming scheme are started with "g_", the compiler wouldn't be able to find your mistake in "local g_var" (global identifier is used for local var).
The compiler also wouldn't be able to detect misspelled local variable name due to "globals-by-default" rule is active despite of your imaginary namespace.
You do need the assistance of the compiler.  That means you need special syntax.
 
 
Q#12:
There is another way to make global access explicit: declaring necessery globals with new statement: "global table, math, print"
 
A:
I don't like the idea that the line where global identifier is used may be far away from the line where it is declared.
Prefixing is more simple, obvious and easy-to-read way.
Prefixing also solves the problem of globals accidentally shadowed out by locals with the same name.
 
 
Q#13:
What modifications should be done in Lua core to implement globals-backslashed style?
 
A:
The modifications required are surprisingly small enough (for an experimental feature of Lua):
1) Backslash-prefixed variable reference should be converted to a field of _ENV table.
2) Variable reference without backslash should generate an error if there is no such local/upvalue.
3) Auto-detection of "globals-backslashed source text" chunk format actually doesn't require two-pass compiler.
If the format of current chunk is not known yet, and the first global variable reference whithout a backslash is occured, a deferred error should be created whithout stopping the compilation.
When first identifier with a backslash is occured (this means the chunk format is detected now: "globals-backslashed"), the error previously saved should be generated.

-- Egor
Reply | Threaded
Open this post in threaded view
|

Re: Say No to global-by-default (summary of the discussion)

Dirk Laurie-2
2018-07-17 22:37 GMT+02:00 Egor Skriptunoff <[hidden email]>:

> My suggestion is the following:
>
>    A programmer must explicitly (by means of special syntax) say to compiler
> whether each variable reference is global or not.

It would annoy me.

I write many functions like the following:

function fun(_ENV)
  return x^2+y+2<=r^2
end

Tihs proposal will break my programs by forcing me to write that second line as

  return \x^2+\y+2<=\r^2

One should not fight one's favorite programming language, but instead
turn its peculiarities into features.

Please fork Lua, call your version Луна and leave contented Lua lovers in peace.

Reply | Threaded
Open this post in threaded view
|

Re: Say No to global-by-default (summary of the discussion)

Viacheslav Usov
In reply to this post by Egor Skriptunoff-2
On Tue, Jul 17, 2018 at 10:38 PM Egor Skriptunoff <[hidden email]> wrote:

Q#9: 
I am not a believer in Hungarian notation. Making it part of any language is the silliest thing I could think about.
 
A:
The "Hungarian notation" is just an instrument, it is not a subject to believe or afraid of.
Actually, "Hungarian notation" is one of possible ways to split namespace.
Splitting a namespace might be good or bad, it depends.
IMO, splitting variable namespace into two: globals and locals, would be good in Lua.
 
Q#11:
Give me as few restrictions as possible on identifiers and if I feel I need a naming scheme, I can create one myself.
 
A:
No, you can't, because the compiler wouldn't be aware of the naming scheme "created" by you.
For example, if globals in your naming scheme are started with "g_", the compiler wouldn't be able to find your mistake in "local g_var" (global identifier is used for local var).
The compiler also wouldn't be able to detect misspelled local variable name due to "globals-by-default" rule is active despite of your imaginary namespace.
You do need the assistance of the compiler.  That means you need special syntax.

This is all wide off the mark. After a variable is declared, I do not need any "assistance". I do not want the "kind" of declaration to be piggy-backed on a pattern in the declared identifier, either.

If I want to declare something as "global", I want to use a syntax that is not intrinsic to the declared name.

As soon as every variable needs to be declared (within the scope where it is used), one will have to misspell identifiers consistently to avoid compile-time errors. That is a whole new ball game for Lua.

Your proposal, on the other hand, does nothing to deal with misspelled globals: one can happily write \print(), \pront() and \prunt(), \because() \everything() \goes() \after() \the() \magic() \slash() 

Cheers,
V.
Reply | Threaded
Open this post in threaded view
|

Re: Say No to global-by-default (summary of the discussion)

Egor Skriptunoff-2
In reply to this post by Dirk Laurie-2
On Wed, Jul 18, 2018 at 12:16 AM, Dirk Laurie wrote:
I write many functions like the following:

function fun(_ENV)
  return x^2+y+2<=r^2
end

Tihs proposal will break my programs by forcing me to write that second line as

  return \x^2+\y+2<=\r^2


This new feature is optional, so it can not break any of your programs.
Lua stay 100% compatible with all your old code (and with your habit to use _ENV in every function).

As I said in Question#3 (please re-read it), this new source format is not suitable for all situations.
If it is useful - use it.
If it isn't useful - don't use it.
Your attitude is quite egoistic: you are requesting that all Lua features would be useful for you.
While lots of users would have benefits from "backslashed style", you could ignore its existence if you want.

Let me repeat it once more: the feature being discussed DOES NOT BREAK ANYTHING.

Reply | Threaded
Open this post in threaded view
|

Re: Say No to global-by-default (summary of the discussion)

Luiz Henrique de Figueiredo
If you really want to play with this idea, here is a patch for Lua 5.3.5:

diff llex.c noglobal/llex.c
547a548
> #include "proxy.c"

diff lparser.c noglobal/lparser.c
284c284,286
<         if (var->k == VVOID)  /* not found? */
---
>         if (var->k == VVOID)  /* not found? */ {
>           luaX_syntaxerror(fs->ls,
>               luaO_pushfstring(fs->ls->L,"undeclared global " LUA_QL("%s"),getstr(n)));
285a288
>       }

% cat test.lua
\a=3
\print(\a)
\print(a)

% cat proxy.c
/*
* proxy.c
* lexer proxy for Lua parser -- implements '\' -> '_ENV.'
* Luiz Henrique de Figueiredo <[hidden email]>
* This code is hereby placed in the public domain.
* Add <<#include "proxy.c">> just before the definition of luaX_next in llex.c
*/

static int nexttoken(LexState *ls, SemInfo *seminfo)
{
        static int state=0;
        int t;
        if (state==0) {
                t=llex(ls,seminfo);
                if (t=='\\') {
                        state=1;
                        seminfo->ts=ls->envn;
                        t=TK_NAME;
                }
                return t;
        } else {
                state=0;
                return '.';
        }
        return t;
}

#define llex nexttoken

Reply | Threaded
Open this post in threaded view
|

Re: Say No to global-by-default (summary of the discussion)

Lorenzo Donati-3
In reply to this post by Egor Skriptunoff-2
On 17/07/2018 22:37, Egor Skriptunoff wrote:

> Hi!
>
> Last time I proposed "$" prefix because some programming languages (Perl,
> bash, PHP) have variable names prefixed with "$".
> But it seems some people dislike any similarities with Perl :-)
> "$" was also criticized because it requires pressing SHIFT on a keyboard,
> and programmers are usually lazy (laziness is the first great virtue of a
> programmer, according to Larry Wall)
> Ok, let's stop talking about Perl  :-)
>
> This time I show another possible prefix: the backslash.
> Backslash is not used in Lua syntax (except inside quoted strings), so why
> not?

[snip]

> -- Egor
>

TL;DR

Sorry if my answer doesn't cover all the details you covered.

I don't agree and that's why. To me it all boils down to two annoying
aspects of what Lua would become with your proposal:

1. I really don't like optional syntax just to avoid "spelling
mistakes". One of the benefit of Lua vs. Java and C++ is its small
"human-memory footprint": I don't have to remember lots of details just
to understand code *written by others*.

I might not use the "backslash notation" in my code, so I could forget
about it, then I find some nice snippets of code from other people and
then it takes much longer to decode or to integrate in my code base (and
I'm no longer a professional developer, I imagine the nightmare of
integrating two pieces of code with same "semantics" but different
apparent syntax).

2. Worse still: I hate sigils on var names. It's a sort of dumbed-down
namespace functionality and to my "parser mind" is extremely distracting
(that's the same with MS hungarian notation, but I grew used to that in
my occasional incursions in Windows API).

I would rather like a more full-fledged namespace functionality that
didn't occur run-time penalties (like table access does), but I'm not
sure how this would impact the size of Lua (and its overall usefulness
could be debatable).

Moreover, anytime I see a non-alphnum symbol my mind tends to interpret
it as an operator. It's not a matter of laziness in writing, but again,
it is distracting when *reading* (especially debugging code) and it
slows me down.

I am used to prefixes a la LaTeX, but then my mind is switched to
"markup language" mode, and anyway, I don't like LaTeX syntax too much
On the other hand I understand that in a substantially declarative
language where code is mainly plain text interspersed with
formatting/structuring commands keywords with sigils make sense, because
they help you locate markup more easily in a sea of text (and they are
lighter than HTML/XML tags). But I'm digressing.

Bottom line: your proposal would make my Lua experience more painful
I chose Lua as my main language years ago over Python as it was
lightweight and its syntax was clean and easy to remember, even If I had
to cope with it's lack of officially endorsed standard libraries; yes
lots of high-quality one-man efforts, but these tend to be abandoned on
the long run, especially if they are "hobby-projects".

I ended-up rolling my own (yep, substandard and not really complete, but
good for my own use cases, and I can find a bug in them in a breeze),
sometimes adapting code from others. This latter part is important: my
efforts would have been much greater in understanding other people's
code if the syntax had been more complex.


my 2 EURocent;

Cheers!

-- Lorenzo






Reply | Threaded
Open this post in threaded view
|

Re: Say No to global-by-default (summary of the discussion)

Dirk Laurie-2
In reply to this post by Egor Skriptunoff-2
2018-07-17 23:51 GMT+02:00 Egor Skriptunoff <[hidden email]>:

> On Wed, Jul 18, 2018 at 12:16 AM, Dirk Laurie wrote:
>>
>> I write many functions like the following:
>>
>> function fun(_ENV)
>>   return x^2+y+2<=r^2
>> end
>>
>> Tihs proposal will break my programs by forcing me to write that second
>> line as
>>
>>   return \x^2+\y+2<=\r^2
>>
>
> This new feature is optional, so it can not break any of your programs.

This is not obvious from the formulation

"A programmer must explicitly (by means of special syntax) say to
compiler whether each variable reference is global or not."

past which I did not read. If the proposal had been:

"A programmer may request the compiler to enforce the specification
(by means of special syntax) whether a variable reference is global or
not."

it would have been obvious that the feature is optional.

Reply | Threaded
Open this post in threaded view
|

Re: Say No to global-by-default (summary of the discussion)

Dirk Laurie-2
In reply to this post by Lorenzo Donati-3
2018-07-18 11:55 GMT+02:00 Lorenzo Donati <[hidden email]>:
> On 17/07/2018 22:37, Egor Skriptunoff wrote:

> I chose Lua as my main language years ago over Python as it was lightweight
> and its syntax was clean and easy to remember,

Exactly my reasons.

Reply | Threaded
Open this post in threaded view
|

Re: Say No to global-by-default (summary of the discussion)

Dirk Laurie-2
In reply to this post by Luiz Henrique de Figueiredo
2018-07-18 2:55 GMT+02:00 Luiz Henrique de Figueiredo <[hidden email]>:
> If you really want to play with this idea, here is a patch for Lua 5.3.5:

This version forces the user to backslash all globals, including the
system libraries, breaking almost all existing programs.

It does not comply with the OP's claim that

"This new feature is optional, so it can not break any of your programs."

However, if the proposal is to be marketed as an optional power patch,
of the existence of which those that do not read the appropriate page on
the Lua Users' Wiki need not even know, there is no possible objection
that can be brought against it.

Reply | Threaded
Open this post in threaded view
|

Re: Say No to global-by-default (summary of the discussion)

Luiz Henrique de Figueiredo
> This version forces the user to backslash all globals, including the
> system libraries, breaking almost all existing programs.

Indeed. My point was just that "global by default" is enforced at
exactly one point in the parser. See
http://lua-users.org/lists/lua-l/2006-10/msg00206.html for a better
solution that can support multiple policies (but note that the source
has changed slightly since then).

Reply | Threaded
Open this post in threaded view
|

Re: Say No to global-by-default (summary of the discussion)

Egor Skriptunoff-2
In reply to this post by Luiz Henrique de Figueiredo
On Wed, Jul 18, 2018 at 3:55 AM, Luiz Henrique de Figueiredo wrote:
If you really want to play with this idea, here is a patch for Lua 5.3.5:


Thanks, it works as intended!
(Error message for "local \x" is not nice, but that's a nitpicking.)

Could you please make a patch to be able to load both "no-global" and "yes-global" scripts on the same VM (with auto-detection of the script type, according to Q#3 and Q#13) ?
So that it would be possible "to use" no-global Lua, not only "to play" with it.

Reply | Threaded
Open this post in threaded view
|

Re: Say No to global-by-default (summary of the discussion)

Thomas Jericke
In reply to this post by Egor Skriptunoff-2
> Globals-backslashed style should be optional.
And then you have to convert code parts when you move them between files
of a single code base.

While I would like to have nothing by default, I don't like this
solution at all. It changes every single access to globals.
Also while it solves typos when accessing locals the compiler still
doesn't check any access of globals when using \.

Roberto once suggested that globals have to be declared as well. So you
have to declare which globals you want to use, and if you declare no
globals at all, Lua would act like it does now (allow any access).

I have some ideas that something like a compiler pragma or a declaration
block would work nicely. But they are just random ideas. I think others
have suggested this already. Something like

local print = print
local t = {}
table.insert(t, 1) -- OK
local do - -"do local" would be less yoda speak but I think that is
already valid syntax
     print "hello" -- OK
     table.insert(t, 1) -- error table isn't local
end
table.insert(t, 1) -- OK

--
Thomas

Reply | Threaded
Open this post in threaded view
|

Re: Say No to global-by-default (summary of the discussion)

Luiz Henrique de Figueiredo
> Roberto once suggested that globals have to be declared as well. So you have
> to declare which globals you want to use, and if you declare no globals at
> all, Lua would act like it does now (allow any access).

See also http://lua-users.org/lists/lua-l/2006-10/msg00206.html

Reply | Threaded
Open this post in threaded view
|

Re: Say No to global-by-default (summary of the discussion)

Thomas Jericke
Am 19.07.2018 um 15:37 schrieb Luiz Henrique de Figueiredo:
Roberto once suggested that globals have to be declared as well. So you have
to declare which globals you want to use, and if you declare no globals at
all, Lua would act like it does now (allow any access).
See also http://lua-users.org/lists/lua-l/2006-10/msg00206.html

That is quite interesting. But this solution (if I understand it correctly) depends on a Lua function declared somewhere else. So Lua files now depend on each other at parse time. Currently you can parse each Lua file by itself. We actually use that feature to load pre-compiled scripts to embedded systems at runtime.
--
Thomas

Reply | Threaded
Open this post in threaded view
|

Re: Say No to global-by-default (summary of the discussion)

szbnwer@gmail.com
hi there! :)

i think there is no optional feature in a language when anyone needs
to use and modify others' codes as well. this would make mess with
those options, but i wouldnt like to see prefixes all around in the
other case as if it wouldnt be optional. lua is the most aesthetic
language ive ever seen, and the most loved by me just as well :)

please dont take this too much personally but i was so much happy when
ive seen a lua'ish way for everything that could be achieved by this,
and hoped this proposal gone with that :D (the same happens to me
kinda often :D )

bests for every1! :)

Reply | Threaded
Open this post in threaded view
|

Re: Say No to global-by-default (summary of the discussion)

Luiz Henrique de Figueiredo
In reply to this post by Thomas Jericke
> See also http://lua-users.org/lists/lua-l/2006-10/msg00206.html
>
> That is quite interesting. But this solution (if I understand it correctly)
> depends on a Lua function declared somewhere else. So Lua files now depend
> on each other at parse time. Currently you can parse each Lua file by
> itself.

That code was just a prof-of-concept to show a general solution. You
can simplify it a lot by freezing a specific policy into the parser,
as I did earlier in this thread, raising an error for untagged
globals. You'd have a modified Lua interpreter but it would be uniform
for all your scripts.

Reply | Threaded
Open this post in threaded view
|

Re: Say No to global-by-default (summary of the discussion)

Egor Skriptunoff-2
In reply to this post by Dirk Laurie-2

Dirk, I have a surprise for you: you are among the people who would have benefits from introducing "\" syntax for globals; you just didn't realize it yet.
 
Your favorite trick with "function(_ENV)" is quite dangerous.
What would happen if some local in outer lexical scope has the same name as one of your globals?
 
   local x
   ...
   local function fun(_ENV)
     return x^2 + y^2 <= r^2
   end
 
Where "x" value would be actually read from: "_ENV.x" or upvalue "x"?
 
This is a hard-to-find mistake.
The solution is to use "\" to explicitly claim that you want "x" from "_ENV", not from an accidental upvalue.
It's possible that the upvalue doesn't exist for now, but might be added in the future, and you would probably not notice this mistake (if not protected by "\" syntax).
 
IMO, "\" syntax is quite a good suggestion.
You just have to spend some time and mental efforts to create new habit.

Reply | Threaded
Open this post in threaded view
|

Re: Say No to global-by-default (summary of the discussion)

Marc Balmer


Am 21.07.2018 um 09:51 schrieb Egor Skriptunoff <[hidden email]>:


Dirk, I have a surprise for you: you are among the people who would have benefits from introducing "\" syntax for globals; you just didn't realize it yet.
 
Your favorite trick with "function(_ENV)" is quite dangerous.
What would happen if some local in outer lexical scope has the same name as one of your globals?
 
   local x
   ...
   local function fun(_ENV)
     return x^2 + y^2 <= r^2
   end
 
Where "x" value would be actually read from: "_ENV.x" or upvalue "x"?

The language definition is crystal clear in this regard.  It would (and does) take the upvalue x, not _ENV.x.

 
This is a hard-to-find mistake.
The solution is to use "\" to explicitly claim that you want "x" from "_ENV", not from an accidental upvalue.
It's possible that the upvalue doesn't exist for now, but might be added in the future, and you would probably not notice this mistake (if not protected by "\" syntax).
 
IMO, "\" syntax is quite a good suggestion.
You just have to spend some time and mental efforts to create new habit.

It clutters the source code and makes it harder to read, imo.




Reply | Threaded
Open this post in threaded view
|

Re: Say No to global-by-default (summary of the discussion)

Thomas Jericke
In reply to this post by Luiz Henrique de Figueiredo
Am 20.07.2018 um 20:42 schrieb Luiz Henrique de Figueiredo:
See also http://lua-users.org/lists/lua-l/2006-10/msg00206.html

That is quite interesting. But this solution (if I understand it correctly)
depends on a Lua function declared somewhere else. So Lua files now depend
on each other at parse time. Currently you can parse each Lua file by
itself.
That code was just a prof-of-concept to show a general solution. You
can simplify it a lot by freezing a specific policy into the parser,
as I did earlier in this thread, raising an error for untagged
globals. You'd have a modified Lua interpreter but it would be uniform
for all your scripts.

I will consider it if I ever embedd another version of Lua (I am currently at 5.2). The thing is, I try to stay as close to vanilla Lua as possible.
So I am almost as conservative in adding extra features as the Lua team is ;-)
--
Thomas

Reply | Threaded
Open this post in threaded view
|

Re: Say No to global-by-default (summary of the discussion)

Dirk Laurie-2
In reply to this post by Egor Skriptunoff-2
2018-07-21 9:51 GMT+02:00 Egor Skriptunoff <[hidden email]>:
>

> Your favorite trick with "function(_ENV)" is quite dangerous.
> What would happen if some local in outer lexical scope has the same name as
> one of your globals?
>
>    local x
>    ...
>    local function fun(_ENV)
>      return x^2 + y^2 <= r^2
>    end
>
> Where "x" value would be actually read from: "_ENV.x" or upvalue "x"?
>
> This is a hard-to-find mistake.

Oh, I have three other favorite tricks.

I call it first one "semi-global variables". All upvalues that are intended to
have scope of the entire file are collected near the top of the program
with no initializer. They tend to have fairly long, descriptive names,
not just 'x'.

I call the second one "local closures". All my functions that use upvalues
needed only by themselves sit inside a do..end block in which those upvalues
are declared.

I call the third one "logical blocks". If half a page of code deserves a
comment describing what it does, one might as well put that comment
on the rest of a line starting with "do".

The result is that seeing 'local' at a place where I can't see the start of its
scope makes my eyes hurt as much as a backslash or other sigil will hurt
Marc's eyes.

I realize that these habits betray my Algol/Pascal programming past,
but at least they cost nothing.

12