Here is where we seem to be:

1. Modulo further bugs in my feeble attempts to write the
transformation, We now have a demonstration that there is no new core
semantics required for BLOCK/RETURN-FROM.

2. The construct is not pure in general, but it can be implemented in
pure form provided the block label does not escape.

3. A block label cannot (conservatively) escape if there are no
syntactically intervening lambdas between a BLOCK and a RETURN-FROM
referencing the same label. That is: if no label ever appears free in a
lambda. This is easy to check statically, and it is a reasonable
restriction to say that pure uses of labeled block returns must obey
this restriction.

In light of this, I propose to add BLOCK and RETURN-FROM to the language
as derived forms. They are derived in the sense that no new semantics is
generated. Implementing the actual rewrite requires synthesis of unique
exception names.

I also propose to add CONTINUE, BREAK, and RETURN as keywords using the
obvious naive rewrites. CONTINUE and BREAK operate on the nearest
enclosing loop form. RETURN exits from the nearest enclosing lambda
form.

I have gone ahead and added the following reserved words to the spec:

  break  continue return block return-from


shap

On Thu, 2008-07-10 at 22:26 -0400, Jonathan S. Shapiro wrote:
> On Thu, 2008-07-10 at 19:45 -0400, Kevin Reid wrote:
> > On Jul 10, 2008, at 14:57, Jonathan S. Shapiro wrote:
> > 
> > >  (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)))
> > 
> > It seems to me that one of these is the case:
> > 
> > 1. myBlock-armed will never be seen to be false, in that if the throw  
> > occurs outside after myBlock-armed is set to #f, it is outside the  
> > catch as well.
> > 
> > 2. You meant (defexception myBlock '#a) as a "static" (as in the C  
> > storage class) definition rather than a lexical one; in which case  
> > your implementation is incorrect anyway, as this example demonstrates:
> > 
> > (define (call-with-return f)
> >    (block myBlock
> >      (f (lambda (x) (return-from myBlock x)))))
> > 
> > (call-with-return (lambda (b1)
> >    (call-with-return (lambda (b2)
> >      (b1 "ok")))
> >    "broken"))
> 
> I definitely did not mean [2]. DEFEXCEPTION is a type declarator, not a
> value declarator. Regardless, Swaroop has since clarified that there is
> no problem with polymorphic exception fields, in which case that
> DEFEXCEPTION can be lifted to top level after unique renaming. The
> requirement is only that the exception name must be unique to the block
> that it guards.
> 
> You are right that my example is completely broken, and after we fix it
> your statement [1] will no longer be correct. Here is the (hopefully)
> corrected version:
> 
>   (define (f x)
>     (block myBlock ...body...)) =>
> 
>   (define (f x)
>     (let ((myBlock-armed #t)))
>       (defexception myBlock value:'a)  ;; hoisted to top level after renaming
>       (try
>           ...body...
>           (set! myBlock-armed #f)
>         (catch id
>           (myBlock ;; first raise
>             (set! myBlock-armed #f)
>             id.value)
>           (default ;; re-propagate other exceptions after disarm
>             (set! myBlock-armed #f)
>             (throw id))))))
> 
> Within the body:
> 
>   (return-from myBlock value) =>
>   (if myBlock-armed
>       (throw (myBlock value))
>       (throw DynamicLabelExtentViolation))
> 
> In the corrected form, you can see that both the value and the state
> change on /myBlock-armed/ are witnessed within the body. The whole point
> was to cause the arming variable to be captured by anything that
> escaped. Unfortunately, I messed up the example enough that this wasn't
> shown.
> 
> > Evaluating this with a correct (per CL) lexically scoped BLOCK  
> > operator will yield "ok". Your implementation above, /if/ there is  
> > only one exception type, will yield "broken" since b2's catch is the  
> > nearest exception handler.
> 
> Yes. But I think that my corrected rewrite yields "ok". If not, then it
> is probably still broken. :-)
> 
> Very nice counter-example, by the way.
> 
> shap
> 
> _______________________________________________
> bitc-dev mailing list
> [email protected]
> http://www.coyotos.org/mailman/listinfo/bitc-dev

_______________________________________________
bitc-dev mailing list
[email protected]
http://www.coyotos.org/mailman/listinfo/bitc-dev

Reply via email to