[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Named loops and blocks for use with break
- From: Rici Lake <lua@...>
- Date: Thu, 6 Oct 2005 23:09:08 -0500
On 6-Oct-05, at 5:59 AM, Doug Rogers wrote:
with them. I'd prefer 'break when' and 'continue when'. The 'when'
keyword could then be used to support a 'case' statement
implementation.
And now we're off on another grand exploration!
Well, ok, another update (same url:
<http://primero.ricilake.net/newloop.diff>). This one adds back the
'break' and 'continue' statements (well, adds the continue statement
would be a better phraseology, I guess), and adds named loop labels.
(See below.)
Syntaxes:
<condition> ::= [ <name-list> '=' <expr-list> 'satisfies' ] <expr>
<for-binding> ::= <name-list> ('=' | 'in') <expr-list>
-- Not quite accurate, but it hasn't changed: I just put it in
-- for completeness
<label> ::= ':' <name>
-- labels *follow* the keyword, which makes ':' unambiguous
<iterator> ::= [ 'for' <for-binding> ] 'do' [<label>] <block>
'end'
<iteration-control>
::= <shivers-iteration-control> | <c-iteration-control>
<shivers-iteration-control>
::= ('unless' | 'until' | 'when' | 'while') <condition>
<iteration-condition>
::= ('when' | 'unless') <condition>
<c-iteration-control>
::= ('break' | 'continue') [ <label> ] [
<iteration-condition> ]
-- Note: If the <iteration-control> is not conditional, it must be
the last
-- statement in the block. There's actually no syntactic need
for this.
<if-condition> ::= <condition> 'then' <block>
<if-statement> ::= 'if' <if-condition>
[ 'elseif' <if-condition> ]*
['else' <block>]
'end'
I hope that's clear.
The scope of a <condition> extends to the end of the <block>; that is,
in the case of <*-iteration-control>, it goes to the end of the
iteration block (assuming that no exit is taken, otherwise the point is
somewhat moot); in the case of an <if-condition> it goes to the end of
the following <block> (and terminates with the 'elseif' or 'else' or
'end'.) The latter is not the same as C++ scoping rules, I don't
believe, but it seemed more natural to me, after trying both variants.
The 'satisfies' clause is mandatory even though in many cases you end
up writing:
if a = foo() satisfies a then ... end
because if it were optional, it would introduce the classic problem
with writing = instead of == and changing semantics. I make this typo a
lot, so I wasn't about to make it possible for the compiler to not
complain.
After I added the loop labels, I had to try them out at least once. I
can't say that the experiment was a success, and I'm starting to wonder
if it's really a good idea aside from really simple cases, and possibly
not even then. Anyway, be your own judge (and feel free to criticize
the code.) The experiment is in
<http://primero.ricilake.net/8q/8q.lua.html> (the code itself can be
downloaded at <http://primero.ricilake.net/8q.tgz>), which consists of
three implementations of the 8-queens problem (actually, the n-queens
problem). The first one is a standard recursive backtracking solution;
the second one is a functional recursive backtracking solution (i.e. no
mutable state); the third one is a purely iterative solution using
labelled iteration blocks. I find the third one almost unreadable. (It
wasn't easy to write, either.) Moreover, it has no speed benefits.
The tarball also includes a C implementation using the functional
recursive backtracking solution; it demonstrates that heap-allocation
is not intrinsic to that style, although I don't off-hand know how to
accomplish that feat in languages other than C, which is an odd
commentary.
Let me know if there are any unsquashed bugs. I might even fix them. :)
R.