lua-users home
lua-l archive

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

I very much like Ada's named loops and the ability to specify which loop
to break. I've found a few times that I wish I had that ability in Lua
and sadly resigned myself to keeping track of things with local
variables. I also like the idea of something similar to Ada's 'exit when
<exp>' syntax.

I've searched the archives to see what others had to say on the topic.
The most succinct response came from - no surprise - Roberto:

'... multiple-level breaks are seldom used, so I think the real question
is whether to support them or not; the actual syntax is not that
relevant.'  []

I would agree that a multilevel break is seldom used, but I find myself
using it more often than I do 'repeat until'. Lua supports the latter
despite the difficult scoping decision it creates (see 'New scoping rule
for "repeat" and "continue" patch').

Though it is true that the syntax doesn't much matter until the decision
is made to include multilevel breaks, I think it is fun and enlightening
to entertain some syntactical possibilities.

For example, a very simple syntactic sugar would provide for Ada's 'exit
when <exp>' construct:

 for i = 1, table.getn(t) do
   breakif t[i] > max   -- Sugar for 'if t[i] > max then break end'.
 end   -- for

Using 'break if <exp>' (with whitespace after 'break') would create an
ambiguous syntax, but only in the case where an (unreachable) 'if'
follows a 'break' - and that is often desirable when debugging.

I believe named blocks/loops provide more than one benefit. They
  - allow exiting of outer loops from inner ones,
  - provide a hint to the purpose of the loop (as with all names),
  - are superior to numbered (depth) breaks for maintenance reasons,
  - and allow more natural flow control than 'goto' would.

I'm sure others can come up with better ideas, but here's one to get
started, introducing a 'when' keyword to avoid the ambiguities of using

   <outer> while true do
     <inner> for i = 1, 50 do
       break <outer> when i > obj:max()
       break <inner> when i > obj:mean()  -- or: break when ...

       if obj:error() then
         print('error: ' .. obj:error())
         break <outer>
       end   -- if
     end   -- for <inner>
   end   -- while <outer>

The way that the name is delimited is another place for exploration, but
I like the one above. A loop/block name starts with '<', which is a
binop. The parser never looks for a 'binop' at the same time it is
looking for a 'stat'. I'm using terms from The Complete Syntax of Lua in
the Lua 5.0 Reference Manual.

So this seems like it should be unambiguous - with the exception of the
greedy interpreter problem that is present in other cases already. The
Complete Syntax could be modified as follows:

stat ::= ... -- deleted items
   | [blockname] 'do' block 'end'
   | [blockname] 'while' exp 'do' block 'end'
   | [blockname] 'repeat' block 'until' exp
   | [blockname] 'for' ... -- all the 'for' variants
   | 'break' [blockname] ['when' exp]

blockname ::= '<' Name '>'  -- Without whitespace.

Has anyone else thought about this?

Perhaps a patch is in order; hope I can find the time.


Doug Rogers - ICI - V:703.893.2007x220