[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: New scoping rule for "repeat" and "continue" patch
- From: Javier Guerra <javier@...>
- Date: Tue, 4 Oct 2005 12:33:16 -0500
On Tuesday 04 October 2005 12:10 pm, Rici Lake wrote:
> What is the semantics of 'continue'? The whole point of using
> "structured" exits like 'break' and 'continue' instead of 'goto' is
> that it syntactically prevents the error of jumping around
> initialization of a variable. So 'continue' must mean to go to the end
> of the scope, at which point the loop will be repeated. If the 'until'
> clause is inside the scope, 'continue' should continue to after the
> 'until' clause. That would be more apparent if the loop were written:
>
> repeat
> local l = io.read"*l" or "quit"
> if l:match"^#" then continue end
> local g, rest = l:match"(%S+)%s*(.*)"
> local done = handle[g](g, words(rest))
> until done
> end
>
> which was obviously the intention. (In fact, in this particular case
> you could eliminate the local altogether.) That's what I suggested
> earlier in the thread, and the more I look at it, the more sense it
> makes to me.
i think you got 'continue' wrong. i'd expect it to goto the loop test, not
after it.
in fact, i feel that signaling a compiler error for this case is the best
approach; precisely because the 'continue' means to do the check immediately.
if a test variable isn't defined yet, it can't be right.
maybe the "can't cross scopes" check would be appropriate, but it might be
needlessly restrictive. with the current example:
this shouldn't compile, because the 'continue' skips over local declarations
repeat
local l = io.read"*l" or "quit"
if l:match"^#" then continue end
local g, rest = l:match"(%S+)%s*(.*)"
local done = handle[g](g, words(rest))
until done
then, the author realizes it can't be right because of the undefined test, and
changes to this:
repeat
local done = false
local l = io.read"*l" or "quit"
if l:match"^#" then continue end
local g, rest = l:match"(%S+)%s*(.*)"
done = handle[g](g, words(rest))
until done
now it's semantically right, but still wouldn't compile because of the "local
g, rest"! the only fix is to write:
repeat
local g, rest
local done = false
local l = io.read"*l" or "quit"
if l:match"^#" then continue end
g, rest = l:match"(%S+)%s*(.*)"
done = handle[g](g, words(rest))
until done
which is just uselessly ugly
maybe if we could think of 'continue' as syntactic sugar for a if...end block,
any local defined after it would be in a smaller scope, that doesn't include
the test condition. that would explain why any local used in the condition
have to be declared before any 'continue'; and at the same time allow for
some 'smaller' locals after that.
<warning> i haven't ever worked the insides of any compiler, not even read the
Lua sources; anything i say here might save us, or destroy Lua as we know it
</warning>
--
Javier
Attachment:
pgpOJSmwLSlzw.pgp
Description: PGP signature