[ANN] Lua 5.4.0 (alpha-rc1) now available

classic Classic list List threaded Threaded
86 messages Options
12345
Reply | Threaded
Open this post in threaded view
|

Re: [ANN] Lua 5.4.0 (alpha-rc1) now available

Philippe Verdy


Le mar. 4 juin 2019 à 23:27, Lorenzo Donati <[hidden email]> a écrit :
Compare:
local < toclose, static,
   nice, helpful, wonderful > resource = ....
vs.
local @toclose @static
   @nice @helpful @wonderful resource = ....

In the first case the possibility to introduce spaces "inside" the angle
brackets could be a source of confusion, too (not to mention spaces at
commas in different coding styles). And maybe also could render the
grammar ambiguous.

That last claim is dubious: whitespaces (spaces, tabs, newlines) do not play any role in th Lua syntax, except being explicit token separators (but they don't generate any token by themselves that can be significant in the syntax). Their coding style also does not matter (and various programmers have their own preferences for their projects).

---

Lua also allows the explicit separator ";" as a syntaxically-significant token, for separating statements that must not be merged into a single statement (for currying function calls).

The ";" token is currently useful only *before* expression-statements, and everywhere else are just no-op statements. There's currently no use at all of ";" **inside** statements (including inside expressions), because it unconditionally terminates the current statement before it but does not change its meaning or parsing rules.  In all other cases, the ";" may be dropped.

The ";" is just a mark detected internally by the parser as a "look-ahead" token, needed by the parser to solve a shift/reduce ambiguity when parsing statements (in that case the parser uses the "shift" action if the next token is not a ";" without ever needing to rollback because it will never use the "reduce" action; but if the next token is a ";" the current statement will be reduced, without that ";"). The ";" token is not reduced by itself inside any statement, except for the empty statement construct (which is a no-op, then silently discarded).

The ";" token may not occur at all before some other tokens that cannot be the start a statement or a part of a compound statement construct (notably the ";" cannot occur before operators, including "or", "and", "not", but also before symbols like "+", "-", "*", "/" or "^") .

So when you terminate any statement with a ";" before some reserved keyword (like "begin", "end", "for", "do", "else", "while", "repeat", "until", "return", "function", or "local"), this is intepreted as an additional no-op statement, after the first statement, parsed and reduced before parsing all further tokens (either "end", "until", "else" for some complex statement constructs, or other tokens marking the start of a new statement).


Reply | Threaded
Open this post in threaded view
|

Re: [ANN] Lua 5.4.0 (alpha-rc1) now available

Egor Skriptunoff-2
In reply to this post by Patrick Donnelly


On Wed, Jun 5, 2019 at 9:02 PM Patrick Donnelly wrote:
> > I thought I'd also share that another useful local qualifier would be
> > <static>. This would be a variable scoped as normal but is initialized
> > once when the surrounding closure is created. i.e.:
> >
> > function foo(...)
> >  local <static> cache = {}
> > end
> >
> > is syntactic sugar for:
> >
> > do
> >  local cache = {}
> >  function foo(...)
> >  end
> > end
> >
>
> What happens if I do:
>
> function foo(…)
>  print(cache)
>  local <static> cache = “something”
>  cache = cache .. ”.”
> end
>
> foo()
> foo()
>
> I prefer the traditional Lua idiom because it is more explicit.

I suppose the cache variable would not be in scope at the point of
"print(cache)" which makes the "syntactic sugar" analogy weaker. This
can be caught during parsing pretty easily. The other thing to
consider is access to locals to the function by the expression
assigning to the static variable. e.g.

function foo(a)
  local <static> cache = a
end

^ That should clearly be invalid code and the compiler should complain
appropriately. OTOH, having access to upvalues to foo should be
acceptable:

local _ENV = {}
function foo(a)
  local <static> rab = _ENV.bar
end

^ OK.




How the following code should be interpreted?

   local function foo(x)
      print(y)                -- is it global y or static y?
      local <static> y = {x}  -- is it global x or syntax error "local x is not accessible in static definition"?
      ...
   end
 
Reply | Threaded
Open this post in threaded view
|

Re: [ANN] Lua 5.4.0 (alpha-rc1) now available

Coda Highland

On Fri, Jun 7, 2019 at 1:15 AM Egor Skriptunoff <[hidden email]> wrote:

How the following code should be interpreted?

   local function foo(x)
      print(y)                -- is it global y or static y?
      local <static> y = {x}  -- is it global x or syntax error "local x is not accessible in static definition"?
      ...
   end

Discounting the details of translating this into normal Lua code, the first question is easy: the only consistent answer is that it would be global y, because the static y isn't in scope yet.

The second question is harder, but there are two additional options you haven't listed.

A third option that would be consistent with how it's done in C and C++: the first time foo() is called, y is initialized with a table containing the parameter passed to the function. Subsequent calls skip over the initialization (because it's already initialized) and proceed with the next line of code.

A fourth option would be that every time the line executes it overwrites the previous value of y with a table containing the parameter passed to the function. This isn't especially useful, to be fair, but it would be consistent; if this isn't the behavior you want, then you write it differently, perhaps:

local <static> y
if y == nil then 
  y = {x}
else
  -- what goes here depends on what you're trying to do
end

As I said at the beginning, the real challenge of this is in defining how it would be translated into Lua code without it. I think the best way to accomplish it would be to rename the static variable into a dedicated label at parse time. Since the Lua documentation says that identifiers starting with an underscore followed by uppercase letters are reserved, then I would suggest _STATIC_y.

The actual bytecode compiler wouldn't need this step, as it shouldn't have a problem distinguishing between the distinct upvalues.

/s/ Adam


Reply | Threaded
Open this post in threaded view
|

Re: [ANN] Lua 5.4.0 (alpha-rc1) now available

szbnwer@gmail.com
hi there! :)

Egor & Coda:
i think `local <static> y = y or {x}` would/should/could(?) keep
`{x}`, as i would interpret it as `y` will be there in the next call
from the previous one, otherwise, as it is, its always overwrite `y`,
that contains the stuff from the previous round (in my
interpretation...)

(ps.: sry for the poor linkage to the history of the messages, but i
use the dummy variant of gmail, where i can only top post, throw away
the original, or copy-paste whatever, and i also only have the last
msg, so i dont even know if i should name anyone else around this sub-
and/or offtopic... and im also too lazy and busy to invest more
efforts :D )

bests! :)

Reply | Threaded
Open this post in threaded view
|

Re: [ANN] Lua 5.4.0 (alpha-rc1) now available

Coda Highland


On Fri, Jun 7, 2019 at 3:02 PM [hidden email] <[hidden email]> wrote:
hi there! :)

Egor & Coda:
i think `local <static> y = y or {x}` would/should/could(?) keep
`{x}`, as i would interpret it as `y` will be there in the next call
from the previous one, otherwise, as it is, its always overwrite `y`,
that contains the stuff from the previous round (in my
interpretation...)

(ps.: sry for the poor linkage to the history of the messages, but i
use the dummy variant of gmail, where i can only top post, throw away
the original, or copy-paste whatever, and i also only have the last
msg, so i dont even know if i should name anyone else around this sub-
and/or offtopic... and im also too lazy and busy to invest more
efforts :D )

bests! :)

That doesn't quite work. As it stands, this statement:

local x = x

creates a new local variable named x containing the value of the global variable named x. Unlike in C, the expression is evaluated BEFORE the new identifier is added to the scope.

/s/ Adam
Reply | Threaded
Open this post in threaded view
|

Re: [ANN] Lua 5.4.0 (alpha-rc1) now available

szbnwer@gmail.com
tl;dr: nothing much important here, its safe to move on :D

Coda:
> the expression is evaluated BEFORE the new identifier is added to the scope.

u r right! :)

i forgot about that even after i had that lesson way back in time,
when a recursive function worked only in the global namespace (in the
`local x=function() x() end` form... i even wanted to yell on lua-l
about it, but then ive seen that its well documented :D (as `local
function y() end` is actually `local y; y=function() end`))

so now i dunno how to imagine `<static>` variables... :D

otherwise i still like both upvalues and holding state in a table for
such needs :D (furthermore we have coroutines for "static" variables
(or state - better said), that i used only once when tekui asked for
it, just i prefer iterators for these kinda tasks...)

12345