lua-users home
lua-l archive

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



On 23-Sep-05, at 11:27 AM, jrs@tbrve.net wrote:

Ripke <paul-lua@malete.org> wrote:
> ...
too sad you are losing the semantics of break -- bad deal.



likewise with
i=0
while (function () -- clearly you'd rather create function only once
  print(i) -- but it would be less readable
  if i<3 then return true end -- continue
  -- break
end)() do
  i=i+1
end

now you have break and continue plus a "continue block",
but sacrificy return.


I've actually never really noticed the lack of continue in Lua, since you can almost always achieve the effect simply by inverting the if statement:

for x in iterator() do
  if condition(x) then continue end
  ...
end

-->

for x in iterator() do if not condition(x) then
  ...
end end

Or:

for x in iterator() do
  if condition1(x) then continue end
  if condition2(x) then continue end
  ...
end

-->

for x in iterator() do
  if not condition1(x)
     and not condition2(x) then
   ...
  end
end

Or:

for x in iterator() do
  if condition1(x) then continue end
  local y = f(x)
  if condition2(y) then continue end
  ...
end

-->

for x in iterator() do
  if not condition1(x) then
    local y = f(x)
    if not condition2(y) then
      ...
    end
  end
end


Once in a blue moon, this is a bit awkward:

for x in iterator() do
  if condition1(x) then
    if condition2(x) then
      continue
     else
      break
    end
  end
  ...
end

This sort of thing can be dealt with by using a tailcall, although that means expanding the for statement:

  local function loop(nexter, obj, state)
    local x = nexter(obj, state)
    if condition1(x) then
      if condition2(x) then
        return loop(nexter, obj, x) -- continue
       else
        return -- break
      end
    end
    ...
    return loop(nexter, obj, x) -- explicit continue
  end
  loop(iterator())

If you really really need to be able to 'return' as well, you can wrap the whole thing in a coroutine. I can't say I've ever encountered this situation, and there are probably better ways to handle it. However:

function foo()
  ...
  for x in iterator() do
    if condition1(x) then
      if condition2(x) then
        continue
       else
        break
      end
    end
    return x
  end
  -- fall through in certain cases :)
  print "Failed to find anything"
end

-->

function foo()
  local try = coroutine.wrap(function()
    ...
    local function loop(nexter, obj, state)
      local x = nexter(obj, state)
      if condition1(x) then
        if condition2(x) then
          -- continue
          return loop(nexter, obj, x)
         else
          -- break
          return
        end
      end
      -- return
      coroutine.yield(x)
    end
    loop(iterator())
    -- "fall through"
    print "Failed to find anything"
  end)
  return try()
end

I'd really love to see a non-contrived use case for a loop like that. :)

R.