Global Declaration Questions

609 views
Skip to first unread message

Eleanor Bartle

unread,
Jun 20, 2025, 7:00:10 PMJun 20
to lu...@googlegroups.com
I have questions about the upcoming global declarations feature in Lua 5.5. 

The manual says that every chunk is loaded in the context of an implicit `global *`, but that this is voided in the context of any explicit global declaration. Does this also apply to explicit `global *`? That is, if that's the first line of a chunk but further down that chunk an inner scope begins with `global print`, will I be able to access `io` within that scope?

Are successive declarations additive or subtractive? That is, if I have `global print` and then `global io` in an enclosed scope, is that legal? Or does the first one have to be `global print, io`, and the second one removes `print` from the environment? Right now it seems like successive declarations are additive unless the preceding one is `*` or the following one is `none`, which seems inconsistent to me.

There is now a way to make globals locally immutable, which I support. Will there be a way to extend this immutability to namespace fields? `global io <const>` prevents a program from overwriting the entire `io` namespace, but not from overwriting individual functions within that namespace: `io.write = -- ...` is still allowed. (Yes, metatables can make the entire namespace immutable, but the point is this doesn't apply per scope like `global <const>` does.)

I look forward to clarification.
Eleanor

Sainan

unread,
Jun 20, 2025, 8:02:13 PMJun 20
to lu...@googlegroups.com
> Are successive declarations additive [...]

Easily answered by the "try it and see" principle.

Test 1, without outer 'global *':

local function f()
global a
print("hi") -- error: variable 'print' not declared
end
f()

Test 2, with outer 'global *':

global *
local function f()
global a
print("hi")
end
f() --> hi

-- Sainan

eugeny gladkih

unread,
Jun 20, 2025, 8:15:08 PMJun 20
to lu...@googlegroups.com
seems to be weird a lot. :(
> --
> You received this message because you are subscribed to the Google Groups "lua-l" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to lua-l+un...@googlegroups.com.
> To view this discussion visit https://groups.google.com/d/msgid/lua-l/AXfbeNooamIJ2XGL_wr0Jnbbzeyg24oIFNXaIurdfQpXHv2AmaJU_rqn0H2KC7HuuBiKDCdT93c_Jhty706scGYRb-ztIUrwPFLI_MzzcfY%3D%40calamity.inc.
>


--
Yours sincerely, Eugeny.


Eleanor Bartle

unread,
Jun 20, 2025, 9:51:09 PMJun 20
to lua-l
I agree, it does be weird a lot. Compare with `_ENV`, where semantics is functionally indistinguishable from a `local _ENV = _G` at the top of the chunk. I don't like this special case.

blog...@gmail.com

unread,
Jun 21, 2025, 12:06:38 AMJun 21
to lua-l
global very difficult construction
Example codes, Try to understand what's going on here without running the code :D
Try to guess which code here works and which doesn't and why :D

```
x = 5
global <const> x
global *
global x

x=x+1
print(x)
```

```
local x = 5
global <const> x
global *
global x

x=x+1
print(x)
```

```
x = 5
global <const> x
global *

x=x+1
print(x)
```

```
x = 5
global <const> x
global x

x=x+1
print(x)
```

It may be useful, but I don't see any obvious application for it yet, yes, you can easily make everything constant or hide everything. But that was possible before.
Constants can now be made undoable for explicitly defined global variables, I don't know why yet.

If we ever mention global for a variable, we must write global * to reopen other global variables (for now)
For example this dont work, becouse now print() not visible

```
global x
x = 10
print(x+10)
```

need this

```
global x
global *
x = 10
print(x+10)
```
I know I'm writing weird stuff here, but people will write it and not understand what's going on. I guarantee it :D

And also, purely intuitively, I want to write like this

```
global x = 10
```

But you can't do that
I see little benefit from an explicit global, but I think we are in for problems with it, not technical problems, but human problems.
The Lua language is notable for being easy to write and easy to read, but these constructions

```
global <contst> x  global *
```

Looks like C++ :(

There are many elegant, beautiful technical solutions in Lua, usually these are elegant small bricks that can be surprisingly flexibly assembled with each other into something complex, almost anything. But here, in my opinion, more and more inelegant solutions appear in the language, but simply situational ones, not bricks from which you can assemble anything, but simply head-on solutions, and semantically complex ones at that. As for me, if global exists, it would look better as just the opposite of local.

```
local x = 5 
global x = 5
```

And constants and closed would be special words that could only follow the words local or global explicitly

```
local const x = 5 
local close x = 5
local blabl x = 5
const x = 5 -- error
close x = 5 -- error
global const *
global const x
global close x
```

 Instead of <close> <const> <blabla>

Don't judge me too harshly, I just expressed my thoughts.
I love lua I'm just maybe not used to some things yet :)
Or I don't understand the original idea hehe
суббота, 21 июня 2025 г. в 04:51:09 UTC+3, Eleanor Bartle:

Andrey Dobrovolsky

unread,
Jun 25, 2025, 2:06:03 PMJun 25
to lu...@googlegroups.com
Greetings!

Of course it would be interesting to read the section about the
"global" keyword in the forthcoming documentation. Still looks like
possible use of "global" in some future caller code will not be able
to interfere with the called code even if the latter was written in
the pre-global epoch.

One fancy use of the "global" may be preventing an accidental use of
any free names in some chunk/block with the help of
global _ENV
declaration. After such a declaration any free name use leads to the
lua: t.lua:7: _ENV is global when accessing variable 'xyz'
error.
Still such an inhibitor may be faked with the local _ENV

local _ENV_BUF = _ENV
global _ENV
-- no free names here
local _ENV = _ENV_BUF
-- welcome free names

Usefulness is suspicious, still ...

Best regards for Lua lovers and makers!

сб, 21 черв. 2025 р. о 07:06 blog...@gmail.com <blog...@gmail.com> пише:
> To view this discussion visit https://groups.google.com/d/msgid/lua-l/21781416-2123-4d9b-9e5b-13b513b15234n%40googlegroups.com.

Roberto Ierusalimschy

unread,
Jun 25, 2025, 3:18:00 PMJun 25
to 'Sainan' via lua-l
> > Are successive declarations additive [...]
>
> Easily answered by the "try it and see" principle.
>
> [...]

Or reading the available documentation...

-- Roberto

Eleanor Bartle

unread,
Jun 25, 2025, 7:29:24 PMJun 25
to lua-l
I read the available documentation. I failed to come up with a single consistent rule that encapsulates the documented behaviour. There were too many special cases to accommodate short of just memorising them.

Many features of Lua are initially alien, but eventually come to feel natural and intuitive with time and practice; I don't think this feature ever will. It has too many exceptions to its rules. I don't like accidental globals either, but I really don't think this is the solution. It doesn't feel Lua-like at all.

Robert Leduc

unread,
Jun 25, 2025, 9:02:35 PMJun 25
to lu...@googlegroups.com

By "available documentation", are we taking about https://www.lua.org/pil/14.2.html?

-- Robert

blog...@gmail.com

unread,
Jun 25, 2025, 11:51:40 PMJun 25
to lua-l
>By "available documentation", are we taking about https://www.lua.org/pil/14.2.html?

If someone need read latest documentation for lua5.5 and global

```
cd lua/manual/
cat manual.of | ./2html > lua5.5-reference.html
firefox lua5.5-reference.html
```
But in HTML page you see "Lua5.4 Reference Manual" not 5.5 :) But this manual contains infrormation about global from 5.5 :)

Judging by this discussion, many still do not quite understand the reason for adding globals and the general concept of why it is needed. And for now they perceive it as something alien hehe ::)

четверг, 26 июня 2025 г. в 04:02:35 UTC+3, Robert Leduc:

Roberto Ierusalimschy

unread,
Jun 26, 2025, 2:28:25 PMJun 26
to lu...@googlegroups.com
> I read the available documentation. I failed to come up with a single
> consistent rule that encapsulates the documented behaviour. There were too
> many special cases to accommodate short of just memorising them.

Let us assume we know how local declarations work in Lua. Global
declarations have the same behavior, with two new rules:

- global * declares as global all names without an explicit declaration
at that point.

- There is an implicit 'global *' at the start of each chunk;
this implicit declaration becomes void inside the scope of any
other global declaration.

-- Roberto

Andrey Dobrovolsky

unread,
Jun 26, 2025, 3:58:38 PMJun 26
to lu...@googlegroups.com
Unfortunately github.com/lua/lua is missing luac.c. Is it possible to
add it to the directory?

-- Andrew

чт, 26 черв. 2025 р. о 21:28 Roberto Ierusalimschy
<rob...@inf.puc-rio.br> пише:
> --
> You received this message because you are subscribed to the Google Groups "lua-l" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to lua-l+un...@googlegroups.com.
> To view this discussion visit https://groups.google.com/d/msgid/lua-l/20250626182817.GA63575%40arraial.inf.puc-rio.br.

Andrew Starks

unread,
Jun 26, 2025, 4:10:45 PMJun 26
to lu...@googlegroups.com
When covering the basic definition, I also think that the behavior of `global <const> * --- everything is read only` is worth noting.

In particular, this example from the manual gave me pause:
     global X
     global<const> *
     print(math.pi)   -- Ok, 'print' and 'math' are read-only
     X = 1            -- Ok, declared as read-write
     Y = 1            -- Error, Y is read-only

FWIW, I really appreciate the addition of global. While there are certainly examples of code that might cause head scratching, things seem clear and predictable when global is used as intended.

That said, the most subtle part for me was understanding that global affects what you’re allowed to access, not what is actually global. For example:

```
global pcall
pcall (print, "this is an error") -- error
global *
print("this is not an error") -- just fine
```
It is kind of weird, but it works and probably gives benefits to validation tools and the interpreter? My only observation is that in most use cases, you just want to prevent the addition of *more* globals. So probably what you want is something that doesn't wipe out the standard library and also prevents you from adding globals accidentally. I don't see how that is easily done from what I've read.

I can't compile Lua 5.4 right now, so I'm not able to double check any of this. My apologies if I'm getting something wrong.

-- Andrew Starks


Roberto Ierusalimschy

unread,
Jun 26, 2025, 5:09:26 PMJun 26
to lu...@googlegroups.com
> When covering the basic definition, I also think that the behavior of
> `global <const> * --- everything is read only` is worth noting.

<const> is completely ortogonal to the other rules. You look for the
declaration of a name. Once you find it, if it has <const>, then
the variable is read-only.


> In particular, this example from the manual gave me pause:
>
> global X
> global<const> *
> print(math.pi) -- Ok, 'print' and 'math' are read-only
> X = 1 -- Ok, declared as read-write
> Y = 1 -- Error, Y is read-only

The first rule is this:

- global * declares as global all names without an explicit declaration
at that point.

So, 'global<const> *' will declare 'Y', 'math', and 'print', which don't
have any explicit declaration at that point. 'X' already has an explicit
declaration, so it is not affected by 'global<const> *'.

-- Roberto

Roberto Ierusalimschy

unread,
Jun 26, 2025, 5:14:11 PMJun 26
to lu...@googlegroups.com
> [...]
> My only observation is that in most use cases,
> you just want to prevent the addition of *more* globals. So probably what
> you want is something that doesn't wipe out the standard library and also
> prevents you from adding globals accidentally. I don't see how that is
> easily done from what I've read.

Just adding 'global <const> *' in the head of your chunk gives exactly
what you want: You can access all the standard library but it prevents
you from adding globals accidentally.

-- Roberto

Eleanor Bartle

unread,
Jun 26, 2025, 6:17:56 PMJun 26
to lua-l
One more question: under the old scheme, a global access uses the value of _ENV that's in scope at that moment. What value of _ENV does a global declaration use? For instance, let's say we have
----
global io, math

local function f (_ENV)
  io.write(math.sin(3))
end
----
If the value of _ENV passed to f redefines or removes io and math, does f still use the old values? Does the _ENV passed to f have any effect at all?

David Sicilia

unread,
Jun 26, 2025, 6:37:37 PMJun 26
to lu...@googlegroups.com

----
global io, math

local function f (_ENV)
  io.write(math.sin(3))
end
----

That’s a good question as to what that should do… or even more so, what if there is a third free variable inside the function, Y… is that allowed.  Regardless of what it does, it seems destined to be confusing.

Maybe instead of calling the new keyword “global” it should have been called “free”, since it seems like its job is just to determine which free names are allowed to be used, though please correct me if I’m wrong.

--
You received this message because you are subscribed to the Google Groups "lua-l" group.
To unsubscribe from this group and stop receiving emails from it, send an email to lua-l+un...@googlegroups.com.

Sainan

unread,
Jun 26, 2025, 6:53:15 PMJun 26
to lu...@googlegroups.com
Shouldn't it be 'global * <const>' instead of 'global <const> *' ?

-- Sainan

Andrey Dobrovolsky

unread,
Jun 27, 2025, 7:24:46 AMJun 27
to lu...@googlegroups.com
Possible use of <const> both as pre-modifier and post-modifier for
regular global variables looks convenient. One can choose the prefered
form.
Sadly * as a "global" argument can be combined only with a
pre-modifier form of <const>. Looks slightly une[pected.

-- Andrew

пт, 27 черв. 2025 р. о 01:53 'Sainan' via lua-l <lu...@googlegroups.com> пише:
>
> Shouldn't it be 'global * <const>' instead of 'global <const> *' ?
>
> -- Sainan
>
> --
> You received this message because you are subscribed to the Google Groups "lua-l" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to lua-l+un...@googlegroups.com.
> To view this discussion visit https://groups.google.com/d/msgid/lua-l/YNraqKzdBvX2gR0W6uJ0hEciW5D3tGFxtZWbHrrkG6Kb8_qUT6wx06c4M_aD66M91PbnzrdkoP9AOBvUbgpLOeuJ3eawkh_Ldm7u3e0_xfw%3D%40calamity.inc.

Roberto Ierusalimschy

unread,
Jun 27, 2025, 1:53:27 PMJun 27
to lu...@googlegroups.com
> Possible use of <const> both as pre-modifier and post-modifier for
> regular global variables looks convenient. One can choose the prefered
> form.
> Sadly * as a "global" argument can be combined only with a
> pre-modifier form of <const>. Looks slightly une[pected.

A pre-modifier applies to all names in the list, a post-modifier applies
only to its attached name. For '*', we thought just the "for all" form
would be enough; we can change that later.

-- Roberto

Roberto Ierusalimschy

unread,
Jun 27, 2025, 2:16:00 PMJun 27
to lu...@googlegroups.com
> local function f (_ENV)
> io.write(math.sin(3))
> end
> ----
>
> That’s a good question as to what that should do… or even more so, what if
> there is a third free variable inside the function, Y… is that allowed.
> Regardless of what it does, it seems destined to be confusing.

_ENV and global are independent. Once a name is determined to be a
global, it is translated to _ENV.name and everything goes exactly as
before.

(A detail is that "global _ENV" makes all globals unusable, as _ENV
would be translated to _ENV._ENV, which would have to be translated
to _ENV._ENV._ENV, and so on.)


> Maybe instead of calling the new keyword “global” it should have been
> called “free”, since it seems like its job is just to determine which free
> names are allowed to be used, though please correct me if I’m wrong.

You are correct in that "global" controls only which names are allowed
to be used. The manual explains that:

Note that, for global variables, the effect of any declaration is only
syntactical:

global X <const>, _G
X = 1 -- ERROR
_ENV.X = 1 -- Ok
_G.print(X) -- Ok
foo() -- 'foo' can freely change any global

But they are used to denote global variables, so the name "global".
And it is debatable whether a name is still free after being declared
as a global.

-- Roberto

Andrey Dobrovolsky

unread,
Jun 27, 2025, 3:42:58 PMJun 27
to lu...@googlegroups.com
> Or reading the available documentation...
>
> -- Roberto

Really nice advice :-) An attentive refman reader will notice the
comprehensive description of new attributes syntax abilities and read
that

-- snip --
All chunks start with an implicit declaration global *, which declares
all free names as global variables; this preambular declaration becomes
void inside the scope of any other global declaration
-- snip --

For me personally the puzzle of an actual state of the "global" domain
is solved easily when I imagine the parser's table of globals (name
and attribute) and remember the simple rule
-- adding any named variable to the table removes the field "*"
All the rest are simply cumulative.

Just 2 cents as an alternative for "global" or "free" : how about "extern"?

-- Andrew

пт, 27 черв. 2025 р. о 21:16 Roberto Ierusalimschy
<rob...@inf.puc-rio.br> пише:
> --
> You received this message because you are subscribed to the Google Groups "lua-l" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to lua-l+un...@googlegroups.com.
> To view this discussion visit https://groups.google.com/d/msgid/lua-l/20250627181554.GC13845%40arraial.inf.puc-rio.br.

Eleanor Bartle

unread,
Jun 27, 2025, 6:58:01 PMJun 27
to lu...@googlegroups.com
So, if I understand correctly, for a user to find the binding of a free name, they search backward and outward through enclosing scopes:
- Once to see if the name appears in a local or explicit global declaration
If it doesn't:
- Twice to see if there is an enclosing global * declaration, counting an implicit one at the very outside if there are no global declarations encountered
If one is not found, error. If one is:
- Thrice to find a binding for _ENV, counting one at the very outside (unconditionally) binding to the global environment
Then look up the name in that table.

If I have this right, I really don't like it. It's tantalisingly similar to the rules for _ENV, but the interplay is far from intuitive, and that one exception sticks in my craw. Now a declaration of an unrelated name can affect the legality of a free name, and there's more context to keep track of.

(Yes, I know the interpreter itself doesn't work as described. I'm talking about how the user builds an understanding of the program, which is just as important.)

Gé Weijers

unread,
Jun 27, 2025, 8:27:06 PMJun 27
to lu...@googlegroups.com


On Sat, Jun 28, 2025 at 12:58 AM Eleanor Bartle <essenc...@gmail.com> wrote:
[...] 
If I have this right, I really don't like it. It's tantalisingly similar to the rules for _ENV, but the interplay is far from intuitive, and that one exception sticks in my craw. Now a declaration of an unrelated name can affect the legality of a free name, and there's more context to keep track of.

You can make an unreadable mess with any feature in a programming language. I would typically only use this at the top of a module to list the global names I need, something like:

global <const> print, require, string, table, io, math

This would catch a variable name typo at compile time, and stop any inadvertent modification of the global environment. Yes, you can utterly confuse the reader of your code by redefining _ENV all over the place and using 'global' injudiciously, but you can also just not do that.

Adding 'global' declarations to your code does not seem to change the runtime behavior of that code if I understand the feature correctly, it just causes compile time errors if you use an undeclared 'free' name or attempt to write to a 'free' name that is declared '<const>'. You can ignore 'global' while trying to understand the code.


--

Andrey Dobrovolsky

unread,
Jun 27, 2025, 10:35:36 PMJun 27
to lu...@googlegroups.com
Eleanor Bartle wrote:
> - Twice to see if there is an enclosing global * declaration,
> counting an implicit one at the very outside if there are no
> global declarations encountered

No, " global * " declaration is effective only as the last one. Any
additional consequent global declarations of the named variables
simply wipes it out.
It may be said that every named variable has precedence over * argument.

сб, 28 черв. 2025 р. о 03:27 Gé Weijers <g...@weijers.org> пише:
> --
> You received this message because you are subscribed to the Google Groups "lua-l" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to lua-l+un...@googlegroups.com.
> To view this discussion visit https://groups.google.com/d/msgid/lua-l/CAGj8prjb%2BsaoC0bwwbjZn-7ZVhfGqv78nfngvBPn%3D6SbFYgP%2BA%40mail.gmail.com.

Eleanor Bartle

unread,
Jun 28, 2025, 12:14:31 AMJun 28
to lu...@googlegroups.com
> No, " global * " declaration is effective only as the last one. Any
> additional consequent global declarations of the named variables
> simply wipes it out.
> It may be said that every named variable has precedence over * argument.

That's the thing though, it doesn't. Look at the second message in this thread:

> Test 1, without outer 'global *':

> local function f()
> global a
> print("hi") -- error: variable 'print' not declared
> end
> f()

> Test 2, with outer 'global *':

> global *
> local function f()
> global a
> print("hi")
> end
> f() --> hi

This is my objection: the "obvious" way that it should work is not the way that it works, and can't be the way that it works with the desired semantics. It's an inherently counterintuitive feature.

Andrey Dobrovolsky

unread,
Jun 28, 2025, 2:41:47 AMJun 28
to lu...@googlegroups.com
сб, 28 черв. 2025 р. о 07:14 Eleanor Bartle <essenc...@gmail.com> пише:
>
> That's the thing though, it doesn't. Look at the second message in this thread:

Oh, You are right, it means that only the initial implicit "global *"
is wipeable. The manual "global *" declarations are also cumulative
like others. Maybe making all "global *" declarations wipeable will
make code more understandable?

сб, 28 черв. 2025 р. о 07:14 Eleanor Bartle <essenc...@gmail.com> пише:
> --
> You received this message because you are subscribed to the Google Groups "lua-l" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to lua-l+un...@googlegroups.com.
> To view this discussion visit https://groups.google.com/d/msgid/lua-l/CAJ16UafgdP6uoVeUzAkb%3DXU%2B44bnfncW9a%3DxN-NT4mrxCc%2B4ig%40mail.gmail.com.

Andrey Dobrovolsky

unread,
Jun 28, 2025, 3:16:33 AMJun 28
to lu...@googlegroups.com
Comparing "global" declarations with switch(), "global *" plays the
role of "default:". And if it is simply cumulative then we obtain an
equivalent to the switch() having its "default:" somewhere a couple of
functions upper. Probably this is how the misleading may occur.

сб, 28 черв. 2025 р. о 09:41 Andrey Dobrovolsky
<andrey.dobro...@gmail.com> пише:

Scott Morgan

unread,
Jun 28, 2025, 7:19:49 AMJun 28
to lu...@googlegroups.com
On 28/06/2025 07:41, Andrey Dobrovolsky wrote:
> Oh, You are right, it means that only the initial implicit "global *"
> is wipeable. The manual "global *" declarations are also cumulative
> like others. Maybe making all "global *" declarations wipeable will
> make code more understandable?

I think that's what wass throwing my understanding. It seemed like each
`global` declaration was going to override all previous ones for that
scope. Instead, except for the implicit one, they build up?

I presume, in everyday use, most people would just stick a `global
<const> *` at the top of the script and drop in any app related global
declaration as needed after that.

One question I've not seen mentioned in my (quick) reading of the new
manual on github: When is global access checked? At compile time or run
time?

Scott

Viacheslav Usov

unread,
Jun 29, 2025, 6:01:15 PMJun 29
to lu...@googlegroups.com, lu...@googlegroups.com
In all versions of Lua, the compiler always knows the list of accessible locals in every scope. An interesting event occurs when it encounters something that syntactically looks like a variable access but the name is not an accessible local. In previous versions, it decides it is a global and converts this to a lookup in a local table _ENV. In the new version, it now also has a list of permissible global names in each scope. So if the name is permissible, it proceeds as before; otherwise it is a compilation error.

Much has been discussed about this in the past. Sadly, some of the most opinionated debaters won’t be able to comment on that anymore. My opinion is that this is a step in the right direction, but possibly too small a step. There was a proposal here wherein each block statement (function body, etc) is optionally decorated with a list of explicitly permissible external names, whatever they be. It seems conceptually simpler to enumerate all the external dependencies at the entry of a block rather than letting them scatter within the block, leading to confusion demonstrated in this thread that they would somehow override each other. And it seems rational to regard outer locals, which can be numerous, on an equal footing with globals. Could this be given another thought?

Cheers,
V.

Roberto Ierusalimschy

unread,
Jun 30, 2025, 9:57:46 AMJun 30
to lu...@googlegroups.com
> Comparing "global" declarations with switch(), "global *" plays the
> role of "default:". And if it is simply cumulative then we obtain an
> equivalent to the switch() having its "default:" somewhere a couple of
> functions upper. Probably this is how the misleading may occur.

That is a nice example of what Gé said, "You can make an unreadable
mess with any feature in a programming language." Many languages
allow a 'default' anywhere in a switch; nonetheless, we always use it
as the last option and keep everybody happy. People don't waste time
arguing

Similarly, it would be strange to allow 'global <const> *' (one of the
most interesting uses of the new global) and not to allow 'global *'.
So, you can write 'global *'; but you don't have to.

I see three kinds of chunks:

- It doesn't use any 'global' declaration; everything is as before.

- It starts with 'global <const> *', and then declares only the globals
it has to write, probably near the point of writing.

- It uses only named global declarations, naming all globals it uses.
It probably starts with some named declaration, to make it clear that
there is no "global by default".

But each one is free to do otherwise.

-- Roberto

Scott Morgan

unread,
Jun 30, 2025, 10:27:00 AMJun 30
to lu...@googlegroups.com
On 26/06/2025 19:28, Roberto Ierusalimschy wrote:
> Let us assume we know how local declarations work in Lua. Global
> declarations have the same behavior, with two new rules:
>
> - global * declares as global all names without an explicit declaration
> at that point.
>
> - There is an implicit 'global *' at the start of each chunk;
> this implicit declaration becomes void inside the scope of any
> other global declaration.

Just playing with the beta now. It all makes sense, as you say, but why
don't you allow assignment on global declaration, like you do with local?

e.g.

global <const> X = 123


I don't think it's a deal breaker, but it seems like an odd omission.

Scott

blog...@gmail.com

unread,
Jul 1, 2025, 11:01:14 AMJul 1
to lua-l
One moment, Im can make this

```
global <const> math
```

But not can this

```
global <const> math.pi -- syntax error
```

Good idea fast and simple make all globals as constatan! But if im write

```
global const math,print
math.pi = 42 -- yes table math is constant but Im no have way for set pi as constant
print(math.pi)
```
Im get 42, how me use `global` make `math.pi` as constatnt? If Im need global constant in table?

And yes this

```
global <const> name = "root"
```

looks good, but not working :)




понедельник, 30 июня 2025 г. в 17:27:00 UTC+3, Scott Morgan:

Steven

unread,
Jul 2, 2025, 10:17:52 AMJul 2
to lua-l
Can you clarify that all of this is correct?

1. The first purpose of _ENV is to allow the host to control which globals are available to the script, e.g. for restricting functionality or sandboxing like pico8 does
2. The second purpose of _ENV is to allow meta reflection of globals at runtime by the scripter, e.g. enumerating them, printing their names, modifying them, etc.
3. The new global keyword is meant to enable the author of the script to avoid accidentally creating or modifying globals because he forgot the local keyword

Is this how both _ENV and the global keyword work together? Am I wrong at any part? Or am I missing anything?

Anyway I bought your 3rd edition PIL book Roberto about 10 years ago, and just this week bought the 4th edition, and it's great as usual. But wondering if I should have waited for a 5th edition for 5.5 if it would be released soon :)

Roberto Ierusalimschy

unread,
Jul 2, 2025, 11:07:26 AMJul 2
to lu...@googlegroups.com
> Can you clarify that all of this is correct?
>
> 1. The first purpose of _ENV is to allow the host to control which globals
> are available to the script, e.g. for restricting functionality or
> sandboxing like pico8 does
> 2. The second purpose of _ENV is to allow meta reflection of globals at
> runtime by the scripter, e.g. enumerating them, printing their names,
> modifying them, etc.
> 3. The new global keyword is meant to enable the author of the script to
> avoid accidentally creating or modifying globals because he forgot the
> local keyword
>
> Is this how both _ENV and the global keyword work together? Am I wrong at
> any part? Or am I missing anything?

Yes for 1 and 3. (I would change "the first purpose" to "a relevant
purpose" and "is meant to enable" to "enables"). Item 2 is debatable:
You can do all that with _G, which is much simpler than _ENV.

-- Roberto

Steven

unread,
Jul 2, 2025, 11:30:09 AMJul 2
to lua-l
> 3. The new global keyword is meant to enable the author of the script to
> avoid accidentally creating or modifying globals because he forgot the
> local keyword

I would change "is meant to enable" to "enables"

-- Roberto

Then what are other purposes of the new global keyword? I can't imagine any beyond this one. Except of course using const to make globals read-only.

Steven

unread,
Jul 4, 2025, 1:59:11 PMJul 4
to lua-l
Maybe I missed it somewhere in this thread or another thread, though I tried to do my due diligence and read quite a lot, including the whole manual section about global, several times.

But I'm utterly confused as to the rationale behind introducing the new global keyword instead of just making good use of _ENV (or _G) to accomplish apparently all the same things.

Gé Weijers

unread,
Jul 5, 2025, 6:33:32 AMJul 5
to lu...@googlegroups.com
On Fri, Jul 4, 2025 at 10:59 AM Steven <sbde...@gmail.com> wrote:
Maybe I missed it somewhere in this thread or another thread, though I tried to do my due diligence and read quite a lot, including the whole manual section about global, several times.

But I'm utterly confused as to the rationale behind introducing the new global keyword instead of just making good use of _ENV (or _G) to accomplish apparently all the same things.


I can't speak for the Lua team on the rationale for adding 'global', but I've been trying it out and I like it, it catches typos and some errors.

The 'global' keyword is used to specify which global variables can be read and possibly written. The check is done at compile time, so a mistake (e.g. typo) is caught before the program even runs. You can do something similar using a proxy object and metatables, but the check is at runtime and it introduces overhead. A typo in a variable name also isn't caught until the program execution hits the offending code that contains it, which could be after the program ships to a customer.

Adding or removing 'global' uses to or from a program does not change the execution one bit if the checks pass.


--

Steven

unread,
Jul 5, 2025, 12:17:46 PMJul 5
to lu...@googlegroups.com
Ah, compile time, now it all makes sense. Yeah I like this feature now. Thanks.

--
You received this message because you are subscribed to the Google Groups "lua-l" group.
To unsubscribe from this group and stop receiving emails from it, send an email to lua-l+un...@googlegroups.com.

Steven

unread,
Jul 5, 2025, 1:51:47 PMJul 5
to lu...@googlegroups.com
Is it possible to disable all globals using the new global keyword?

The best I can think of is global _ where _ is just not a valid key in _ENV (or does globals use <global env> aka LUA_RIDX_GLOBALS?).

But that feels weird to write, since there's technically a chance _ is a valid key (e.g. underscore-js).

Andrey Dobrovolsky

unread,
Jul 5, 2025, 2:15:44 PMJul 5
to lu...@googlegroups.com
> Is it possible to disable all globals using the new global keyword?

I've tried something of that kind with the help of "global _ENV".
Still we can read in the refman:
However, you
should not define _ENV as a global variable, otherwise _ENV.var would
translate to _ENV._ENV.var and so on, in an infinite loop.
So we can not be sure this trick will remain legal ))

сб, 5 лип. 2025 р. о 20:51 Steven <sbde...@gmail.com> пише:
> To view this discussion visit https://groups.google.com/d/msgid/lua-l/CACeWA3i7tGnCixMWgDcvodPA2Xyu%3DykeghZ-QZEbEMUZVrXYeA%40mail.gmail.com.

Sainan

unread,
Jul 5, 2025, 6:23:35 PMJul 5
to lu...@googlegroups.com
> Is it possible to disable all globals using the new global keyword?

global m6eq6wu5tiu5rjsgsufgayjpu19ktevgqma20u7ja69g9k1x6ptnfiqcqqt6q77y3zc8ddwylo83vs2sdyvd1lx8daoslehk6d1ofrc43sxvlgp9ks3ylccfmz9x3y5q

Generated by a fair dice roll, guaranteed to be random. :^)

-- Sainan

David Sicilia

unread,
Jul 5, 2025, 7:16:10 PMJul 5
to lu...@googlegroups.com
Not sure if this possible, but I would guess that the following should disable all global access:

global global

My reasoning there would be that the presence of the global keyword should make global into a keyword while simultaneously restricting globals to “global” which will not be allowed to be written since it is then a keyword.  But I’m sure I’m going wrong somewhere :-)

--
You received this message because you are subscribed to the Google Groups "lua-l" group.
To unsubscribe from this group and stop receiving emails from it, send an email to lua-l+un...@googlegroups.com.

Eleanor Bartle

unread,
Jul 5, 2025, 7:57:18 PMJul 5
to lua-l
I saw "global none" used for this purpose in the doc examples, but not itself mentioned explicitly in the docs; do not depend on it.

Andrey Dobrovolsky

unread,
Jul 5, 2025, 9:03:23 PMJul 5
to lu...@googlegroups.com
Declaring "global none" doesn't guarantee you from accidentally
declaring "global another_one" somewhere else and doesn't prevent
successful usage of the "another_one" variable. I think the
declaration "global _ENV" is more restrictive, I've failed trying to
override/bypass it. Maybe someone else will succeed.

нд, 6 лип. 2025 р. о 02:57 Eleanor Bartle <essenc...@gmail.com> пише:
> To view this discussion visit https://groups.google.com/d/msgid/lua-l/309e12af-dec3-465e-b2b3-a30636bcaadan%40googlegroups.com.

Scott Morgan

unread,
Jul 5, 2025, 10:36:54 PMJul 5
to lu...@googlegroups.com
On 06/07/2025 00:15, David Sicilia wrote:
> Not sure if this possible, but I would guess that the following should
> disable all global access:
>
> global global
>
> My reasoning there would be that the presence of the global keyword
> should make global into a keyword while simultaneously restricting
> globals to “global” which will not be allowed to be written since it is
> then a keyword.  But I’m sure I’m going wrong somewhere :-)

Seeing as we already have 'global *', perhaps we could have 'global -'
or 'global ~'

Scott

Roberto Ierusalimschy

unread,
Jul 7, 2025, 2:12:54 PMJul 7
to lu...@googlegroups.com
> Not sure if this possible, but I would guess that the following should
> disable all global access:
>
> global global

In the future 'global' will become a true reserved word and this
syntax will raise an error. (You can bring that future by undefining
LUA_COMPAT_GLOBAL in luaconf.h.)

$ lua
Lua 5.5.0 Copyright (C) 1994-2025 Lua.org, PUC-Rio
> global global
stdin:1: <name> expected near 'global'

-- Roberto

Roberto Ierusalimschy

unread,
Jul 7, 2025, 3:03:29 PMJul 7
to lu...@googlegroups.com
> I saw "global none" used for this purpose in the doc examples, but not
> itself mentioned explicitly in the docs; do not depend on it.

There is nothing special about "global none". It is just a convention
that works as long as you don't use 'none' as a global name in that
chunk. (A simple "find" can ensure that.)

It seems clear and quite safe for non-adversarious errors. For complete
control, you should set _ENV to something different from the global
table.

-- Roberto
Reply all
Reply to author
Forward
0 new messages