lua-users home
lua-l archive

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


I propose extending the `do` statement to allow it to contain multiple
labeled blocks, where each block is normally executed in sequence but
can break to any other labeled block, like a state machine.  The
syntax is

  `do` block {label block} `end`

Example:

  local x
  do
    x = 1
  :loop:
    if x > 10 then break :exit: end
    print(x)
    x = x + 1
    break :loop:
  :exit:
  end

You may recognize that as equivalent to a `for x=1,10 do print(x)
end`.  In fact, this can emulate a number of control structures.  It
can also emulate `continue` [1], breaks out of nested loops, and even
`redo`:

  do
    for kk, vv in pairs(tt) do
      for k, v in pairs(t) do
        :redo:
        if condition1 then break end
        if condition2 then break :continue: end
        if condition3 then break :redo: end
        if condition4 then break :forfor: end
        :continue:
      end
    end
  :forfor:
  end

As seen above, a couple syntactic simplifications are allowed.  This
same behavior is supported in the `do/end` of `while` and `for` loops,
and an unlabeled `break` in one of these exits the containing loop as
before.  We can even make certain labels like :redo: and :continue:
implicit in loops so that you may simply write

  for kk, vv in pairs(tt) do
    for k, v in pairs(t) do
      if condition1 then break end
      if condition2 then break :continue: end
      if condition3 then break :redo: end
      if condition4 then break :forfor: end
    end
  end

A couple qualities of this proposal:

  - It looks quite versatile, perhaps nearly as versatile as goto, maybe even
    addressing David Given's recently stated needs for expressing arbitrary flow
    graphs in code generation [2].
  - It remains fairly structured despite the versatility.  Each block
can only break to
    the start of another block in the same lexical scope, and local
variables in each
    block are private to the block.
  - It remains terse for common needs despite the versatility.
  - It extends the existing `do` statement.
  - It does not introduce new keywords but rather labels.
  - Labels perhaps could also be numbers that evaluate at runtime,
supporting jump
    tables (like C `switch` statements) and things like Duff's device.
  - It kills multiple birds with one stone, perhaps addressing the
criteria of Roberto [3].
  - It should be possible to write a program that translates programs with this
    syntax back to Lua 5.1 syntax for compatibility.  The bytecode
generated from that
    Lua 5.1 source might not be as efficient.  However, it may be
possible to write a
    compiler (e.g. Metalua) that directly generates efficient Lua 5.1
bytecode for
    running under a standard Lua 5.1 VM.
  - Is this supported in `repeat/until`?  It's not mandatory.  We
could require a nested
    `do/end` inside the `repeat/until`.  That avoids the scoping problem.
  - It does not necessarily introduce more nesting in most cases.

[1] http://article.gmane.org/gmane.comp.lang.lua.general/74476
[2] http://lua-users.org/lists/lua-l/2011-01/msg01461.html
[3] http://lua-users.org/lists/lua-l/2008-02/msg01183.html