lua-users home
lua-l archive

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



On 5-Oct-05, at 9:24 AM, Doug Rogers wrote:
Has anyone else thought about this?

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

I've thought about it a lot :)

I suspect that this patch is not going to please anyone but me :) but for what it's worth, I've put it up on the web. It's not (yet) very well tested, and I just threw it together last night in order to give some solidity to some of the ideas which have been floating around (particularly mine, obviously :) The vocabulary comes from a really interesting paper by Olin Shivers (http://www.cc.gatech.edu/~shivers/papers/loop.pdf) which I hadn't yet read when I proposed putting 'until' clauses inside the block, but immediately struck a resonance with me.

This patch does not implement named loops, although it is something I've thought about. Syntax does matter, when it comes down to implementation, and I'm not sure what a good syntax would be; I agree with Roberto that using <label> is not a good idea.

Anyway, the patch. The patch gets rid of 'while', 'repeat', and 'break'. There are only two constructs:

for <table or numeric specification> do <body> end

and

do <body> end

The production for <statement> has been augmented with four new statements:

<statement> ::= <iteration-control>

<iteration-control> ::= ( 'unless' | 'until' | 'when' | 'while' ) <expr>

Each of these statements evaluates the expression and conditionally terminates the loop ('until' 'while') or the current iteration ('unless' 'when'). 'until' and 'when' terminate if the condition is true; 'unless' and 'while' terminate if the condition is false. Obviously they are not all necessary, but they read better, and having eliminated four reserved words (break, repeat, until, while), I figured it was ok to add four of them back (two of them are the same).

'while' and 'until' are effectively what Doug spells "breakif" ('while' would be "breakif not(...)"). 'unless' and 'when' would then be "continueif".

Note that a do block is a loop if and only if:
  it is part of a 'for' statement
or
  it contains at least one 'while' or 'until' statement.

It is legal to put any iteration-control inside an 'if' block, by the way, although it should only rarely be necessary.

Some examples might be helpful (hope y'all have fixed fonts)

Current Lua                              Patched Lua
---------------------------              -----------------------------
while t do                               do while t
  print(t.value)                           print(t.value)
  t = t.next                               t = t.next
end                                      end

repeat                                   do
  print(t.value)                           print(t.value)
  t = t.next                               t = t.next
until t == target                          until t == target
                                         end

for i, val in ipairs(t) do               for i, val in ipairs(t) do
  if val == "" then break end              until val == ""
  if type(val) == "string" then            when type(val) == "string"
    print(i, val)                          print(i, val)
  end                                    end
end

You can use the 'when' and 'unless' clauses to implement the C idiom do { ... continue; ... } while(0);

do
  local a = foo()
  when a
  local b = bar(a)
  when b
  local c = baz(a, b)
  unless c == "no"
  print(c)
end

Note that the above is not a loop since it does not contain either "while" or "until".

If you really want to do an unconditional 'break' or 'continue' you can use 'unless true'/'when false' or 'until true'/'while false'; unlike the current Lua, these do not need to be at the end of a block so you can insert them during debugging.

Here's the patch (against lua-5.1-alpha); comments are welcome.

http://primero.ricilake.net/newloop.diff