[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: Re: New scoping rule for "repeat" and "continue" patch
- From: Rici Lake <lua@...>
- Date: Wed, 28 Sep 2005 21:41:17 -0500
On 28-Sep-05, at 9:00 PM, email@example.com wrote:
My example 'continue' using repeat ... until true 'misused' that
construct, turning it into a simple block by making the iteration
Indeed, leading to anti-self-documenting code. I've seen the same thing
C, occasionally preceded with a comment like "this 'do' is only to
use of 'break´". I've always thought that it would be better to use a
in such cases, since (may I not be smitten by Djikstra's ghost) a
a well-chosen label is easier to understand than a misused iteration
Having said that, I do not favour adding 'goto' to Lua.
The special cases about what's in an 'environment frame' for a block
it has a conditional attached have created a surprise. This surprise
suggests to me that the 'block' as a construct should be 'promoted' and
reconsidered independently of the looping control conditional
with which it's usually very closely associated.
Lua does not associate 'blocks' with looping constructs. The various
in 'if' statements are 'blocks', for example (both syntactically and
semantically). The manual explicitly states "The scope of variables
at the first statement after their declaration and lasts until the
end of the innermost block that includes the declaration." That clearly
identifies "blocks" as a scope construction, which seems reasonable to
me. It was, therefore, a real surprise to find that the 'until' clause
of the 'repeat' instruction was inside the scope of the 'block'.
On the other hand, a 'block' in Lua is *also* (more or less) a 'basic
in the sense usually used in structured programming analysis. The
of Lua suggest that a block (as defined by a Block structure) is really
more oriented towards compiling basic blocks than towards maintaining
scope. This does not need to be ambiguous; keeping the two concepts
completely in synch is consistent with Lua's minimalist design.
It's worth noting that internally, all loop constructs consist of two
nested Blocks: the outer block, which is invisible in the source code,
is used to provide an execution context for the 'break' statement,
while the inner block is used to contain scope. Since the loop statement
itself is in the outer block, 'break'ing from the inner block would be
tantamount to 'continue'. This observation would have lead to a much
cleaner implementation of the continue patch, although it still would
have failed for the new semantics of 'repeat'.
The aspect of Lua that really sets it apart from other languages for me
is that it and its syntax revolve around manipulating a few carefully
selected and useful computing constructs. The 'block' may be one of
I agree with this. (In fact, I wouldn't have said "may be one".)
I also wonder what motivated the change in repeat ... until ... .
is, what new use or better use of repeat ... until ... was envisioned
this change was to make possible?
I also wonder about this. The actual implementation of "until <expr>"
generates the same code as would have been generated by replacing the
clause with "if <expr> then break end; until true" (aside from a small
optimization in the case that no upvalues are created in the block).
This suggests that it might be better to make "until" into a very
simple macro-expansion, and terminate 'repeat' blocks with 'end':
-- do something
until z < 3
If 'until' is a statement (expanding into "if <cond> then break end")
then it could appear anywhere inside the loop, even several times;
allowing the unification of pre-tested ("while") loops with post-tested
("repeat") loops (and adding mid-tested loops as well):
until p == nil
--- do something
loops = loops + 1
until loops > 1e4
p = p.next
However, I'm not convinced that this adds anything in the way of
readability; it is simply more compact than:
if loops > 1e4 then
It does, however, realign blocks and scopes, which is a good thing.
Everyone will have their own deeply-held and radically distinct
views about what "looks better". I personally prefer a minimum
set of powerful constructs than a large confusing set of one-shot
constructs. In fact, I would favour replacing the numeric 'for'
with a 'range' basic function:
for i in range(1, 100, 4) do ... end
even though it might come at a small price at execution time. (Making
the price small would be the challenge, of course.)