Am So., 14. Juni 2020 um 16:57 Uhr schrieb John Cowan <firstname.lastname@example.org>:
> Reformatting your definition of either-guard for better readability, it is:
> (define-syntax either-guard
> (syntax-rules ()
> ((either-guard pred? . body)
> ((pred? exc) (left exc))
> (else (raise-continuable exc)))
> (call-with-values (lambda () . body) right))))
> The question here is: What is the continuation of `raise-continuable`? And the answer is that it is the continuation of `guard`, namely the invocation of `either-guard` as a whole. But that's not what we want. What we want is for its continuation to be the `raise` or `raise-continuable` that raised the exception in the first place. But the only way to get there from a `guard`, once any exception is raised, is to fall out of the guard, which cannot happen here because there is an else-clause.
I may have misunderstood the description of `guard' in the report. I have been thinking that the implicit cond expression is evaluated as an exception handler installed by `with-exception-handler'. In that case, it does the right thing.
So I have taken another look at the definition of `guard' in the appendix of the report. As I see, it already contains a call to `raise-continuable' if `exc' is not caught. It is wrapped in `(handler-k (lambda () ...))'. This will be evaluated at `((call/cc (lambda (guard-k) ...)))'. Evaluating causes the code to jump back into the exception handler installed by `with-exception-handler' (due to the `handler-k'). So the exception `exc' will be continuably raised there. Assuming that it is caught, the call to `raise-continuable' of the `guard' will yield values, which become the return values of the installed exception handler. This, however, means that any original continuable exception would be cured.
Here is a test:
(#f #f)) ;Dummy clause
(raise-continuable "Hello, World!"))
This displays "Hello, World!" using the implementation of `guard' in the appendix of the report.