lua-users home
lua-l archive

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



On 6-Oct-05, at 9:03 AM, Javier Guerra wrote:

my opinion is that Shivers' vocabulary makes sense when you read it tightly in the context of the loop. particularly the 'when' and 'unless' aren't clear
without the 'do'

Maybe it just takes getting used to.

You could, of course, choose to indent:

function command_shell(stream, handlers, endword)
  for line in stream:lines() do
    until line == endword
      line = line:gsub("^%s*", "")
      unless line == ""
        unless line:find("^#")
          local cmd, rest = line:match("(%S+)%s*(.*)")
          if h = handlers[cmd] satisfies h then
            h(argsplit(cmd, rest))
          else
            print("Unrecognized command "..cmd)
          end
  end
end

In fact, aside from the lack of an 'end', 'unless' is pretty well equivalent to 'if not(expr) then'. However, one of the main criticisms people have expressed about using an 'if' statement for this sort of construct is that it leads to excessive indentation, and that's a point Olin Shivers makes as well:

    The fact that the rightward-drifting/nested indentation of the
    original code has aligned into a vertical column is a hint that
    our control and environment structuring has been brought more
    closely into alignment.

This is the same as Lua's 'local' statement, of course. Allowing 'local' statements to appear anywhere in a block reduces indentation level; the scope of the 'local' (just like the scope of the 'unless'/'when') extends to the end of the existing block without requiring an additional block terminator.

Personally, I think I'd prefer to undent if I didn't have a syntax highlighter. That makes the iteration controls stand out more, but it also masks the vertical control flow.

function command_shell(stream, handlers, endword)
  for line in stream:lines() do
    until line == endword
      line = line:gsub("^%s*", "")
    unless line == ""
    unless line:find("^#")
      local cmd, rest = line:match("(%S+)%s*(.*)")
      if h = handlers[cmd] satisfies h then
          h(argsplit(cmd, rest))
        else
          print("Unrecognized command "..cmd)
      end
  end
end