lua-users home
lua-l archive

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


On 27/07/2022 08:33, Egor Skriptunoff wrote:
On Tue, Jul 26, 2022 at 2:36 PM Lars Müller wrote:

"return" is the only "retstat" and thus the only statement that is
syntactically only allowed at the end of the block:

Why is this not extended to "break", which is a normal statement and thus
allowed to precede arbitrary other statements?


"return" statement may have or have no parameters.
The Lua parser has to decide whether the lexemes following "return" are its
parameters or beginning of the next statement;
this implies a non-trivial look-ahead.
To keep Lua parser simple, "return" was declared as the last statement in a
block by the language syntax.
I personally consider this as a dirty hack :-)

The Lua team initially had plans about improving the "break" statement in
the future:
"break" may be given an optional parameter for exiting multiple nested
loops,
similar to the labeled break statement in Java.
That's why "break" in Lua 5.1 also was declared as the last statement in a
block:
improved "break" will have the same parsing problem as the "return"
statement.

But after introducing "goto" in Lua 5.2 the plan of improving "break" was
cancelled,
because now you can break multiple nested loops with "goto".
Since "break" is now parameter-less now and forever, it was removed from
"retstat".



As I recall it, this is the right explanation for the current situation.

FWIW, I'd still like "break" to be improved to manage multi-level breaks, even as syntactic sugar for an hidden goto+label definition. I don't despise GOTOs, but I think that using a goto to exit a multilevel loop is very error prone, especially if the label is far away from the goto, which is not so rare a case when algorithm with 3 or 4 nested loops are used (and this is really the case where you would find a multilevel break really useful).

Semantically a multilevel break is a very clear program action, which should be understandable at the break site ("I want to exit multiloop"). Using a goto at that same point must rely on "meta" information to convey the same meaning to the code reader, such as a comment or a descriptive label, but these may be misleading (possibly ambiguous: "goto start", to exit a multiloop).

I would welcome a syntax like "break 4", to exit four loop levels.
WRT the parser lookahead capabilities, maybe an uglier syntax could avoid excessive lookahead, like "break<4>". After all with Lua 5.4 and const/to-be-closed vars the syntax has already been uglified a lot, IMHO.

An alternative would be sort of like "relative jumps" (breaks are essentially that):

goto +1 = break (jumps just after the end of current loop body)
goto +2 = break 2 (jumps just after the end of the innermost enclosing loop body)

This could be generalized to implement a "continue" statement (multilevel too):

goto -1 = continue (jumps at the end of current loop body)
goto -2 = continue 2 (jumps at the end of the innermost enclosing loop)

(and maybe someone could come up with a syntax that's nicer than in these ramblings of mine :-).


Currently, Lua 5.2 to Lua 5.4 happily allow abominations such as

while true do break break break end
while true do break a = 1 end


Do you want to complicate the language syntax to guarantee that every
statement is reachable?
It's not worth it.


Cheers!

-- Lorenzo