lua-users home
lua-l archive

Re: continuing continue - was Re: [patch] continue statement

[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.

AltStyle によって変換されたページ (->オリジナル) /