On Thu, 2008-07-10 at 08:09 -0400, Kevin Reid wrote:
> In case this is new and useful information: Other than /escape-ident/
> being bound to a procedure, this is identical to Common Lisp's BLOCK &
> RETURN-FROM.
>
> http://www.lispworks.com/documentation/HyperSpec/Body/s_block.htm
>
> (Note that it is possible to capture a RETURN-FROM in a closure; it
> still has only dynamic extent.)
I am very glad that you pointed this issue out, because I had failed to
consider it adequately. Let me try again.
Basically, we have three constructs that I would like to have a way to
support: CONTINUE, BREAK, and RETURN. In their un-labeled form, none of
these seem to present a major problem. BREAK converts directly into
RETURN when the loop construct is lambda-converted. CONTINUE becomes
tail-call on the loop-lambda.
RETURN presents a mild problem, because it means that two of our current
derived forms must become core forms. The BEGIN and DO forms are
currently defined by the spec to be canonically rewritten in terms of
LAMBDA and application. The problem here is that we want both of the
following to work as expected:
(define (f x)
(begin
1
(return #t)
#f))
(define (f x)
(while ...
(if (funny-condition)
(return 1)
... rest-of-loop-body ...)))
The present compiler does not actually implement either BEGIN or DO
using lambda.
On reflection, I think it is better if both of these become core forms
for a variety of reasons, and I have just updated the spec to make them
core forms.
Unfortunately, it seems to me that the labeled BLOCK escape, which is
the generalization of these constructs, can't be handled by any
stateless implementation if it is possible for the label to be captured.
The problem is that we need to disarm the label when its associated
block exits. What we need here is dynamic scope rather than dynamic
extent, which seems to require something like:
(define (f x)
(block myBlock expr)) =>
(define (f x)
(let ((myBlock-armed #t)))
(defexception myBlock '#a)
(try
...body...
(catch id
((myBlock exitValue)
(if myBlock-armed
exitValue
(throw DynamicLabelExtentViolation))))))
(set! myBlock-armed #f)))
Inside the body, the RETURN-FROM will be rewritten as
(throw (myBlock-exception myBlock-armed theValue))
This is bad, because it *appears* to suggest that we have two mutually
exclusive choices:
1. Restrict block escape labels so that the cannot escape. One
implementation is to ensure that they cannot be captured.
2. Use some form of mutable arm/disarm mechanism, in which case
the labeled block escape mechanism cannot be included in the pure
BitC subset.
Does anybody see a way to justify the arm/disarm mechanism in the purely
functional BitC subset?
shap
_______________________________________________
bitc-dev mailing list
[email protected]
http://www.coyotos.org/mailman/listinfo/bitc-dev