[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
RE: COND/DO consistency
I had proposed the following:
> | (DO ((<variable> <init> <step>)
> | ...)
> | (<test> <expression>...)
> | <command>...)
> |
> | If the <test> evaluates to a true value, then the value of the last
> | <expression> is returned as the result of the DO. If no <expression>s
> | are present, then the value of the DO expression is unspecified.
>
> I propose that this last line read "then the value of the <test> is
> returned as the value of the DO expression." for consistency with the
> way test clauses are handled in COND.
>
> Consequently, I propose that the rewrite rule for DO in section 7.3
> be changed to:
>
> | (DO ((<variable_1> <init_1> <step_1>)
> | ...)
> | (<test> <expression>...) ;; NB: <sequence> changed to <expr>...
> | <command_1>...)
> |
> | = (LETREC ((<loop>
> | (LAMBDA (<variable_1>...)
> | (COND (<test> <expression>...) ;; NB: COND
> | (ELSE <command_1> ;; not IF
> | ... ;;
> | (<loop> <step_1>...)))))) ;;
> | (<loop> <init_1>...))
Morry countered by generalizing this to have potentially many <test> clauses:
> | (DO ((<variable_1> <init_1> <step_1>)
> | ...)
> | ((<test> <expression>...) ;; NB: <sequence> changed to <expr>...
> | ...)
> | <command_1>...)
This is a more substantial change and, as Morry noted, it is not compatible with
the current DO syntax. I would like to add that I have never had occasion to
malign the language for not providing a more general exit <test> structure. To
point, I have adopted the following idiom:
(DEFINE call-with-nonlocal-exit call-with-current-continuation)
(DEFINE (first-such-that test-pred lst)
(call-with-nonlocal-exit
(LAMBDA (exit)
(DO ((to-do lst (CDR to-do)))
((NULL? to-do) *THE-CANONICAL-FAILURE-OBJECT*)
(LET ((next (CAR to-do)))
(COND ((test-pred next) (exit next))
((something-interesting? next) (exit (mumble next)))
...
))))))
I find this not excessively verbose and I actually enjoy the distinction between
the "normal" loop-variable-exhausted exit condition to the "exceptional"
short-cut-situation exit condition. I have generalized this into a
SHORT-CURCUIT-ACCUMULATE idiom which I use fairly often.
My point is that I would not like my initial painless proposal to be
overshadowed or superceeded by a more controversial counter-proposal. I really
have had occasion to want to return the result of the non-FALSE test. For
example, when I exit with the first element of a list which has a frame in a
possibly lengthy association list, I don't cherish the thought of probing for
the frame twice and I don't relish named-LET or LETREC as an alternative since
this obscures the DO-ish nature of the iteration. I prefer DO when doing DO-ish
doodles, but when faced with multiple exit conditions, I prefer the
nonlocal-exit idiom to Morry's more moribund morsel.
Cheers,
~Ziggy