>do i get this right? (with-exception-handler ... #:unwind? #f) installs a so 
>called pre-unwind-handler, which takes priority over a false-if-exception, 
>even if deeper in the stack, because f-i-e installs a post-unwind-handler?

It’s not post-unwind? If anything, I would call it pre-unwind. If 
with-exception-handler were post all the unwinding, then it’s too late to let 
raise-continuable return anything. 

But other than that (“[it] takes priority over a false-if-exception, [...]), 
that’s my understanding of things.

I guess what should be done, is it _not_ having priority, and instead it only 
handling things when there noguard/catch/... inside has caught the exception.

>i came from common lisp, and from a distance i always had this impression of 
>scheme that it is a much more cleaned up lisp... but in CL the condition 
>system is way cleaner/simpler than this. i wrote long running, multi-threaded 
>web services with advanced logging (backtraces, user installable backtrace 
>decorators, etc), error handlers that deal with nested errors, etc... so i'm 
>rather familiar with the problem domain, but apparently i'm lost in the forest 
>here.

First, I want to say that (purely semantically) conditions have nothing to do 
with exceptions in Guile – you can, technically, raise anything as an 
exception, not only conditions, and conditions are just a kind of record type 
that are conventionally used for exceptions (and convenient for that!) but 
could in principle be used for entirely different things.  So from now on I’ll 
talk about Guile _exceptions_ instead.

Going by < 9.1 Condition System Concepts | Common Lisp (New) Language Reference 
(lisp-docs.github.io)>, the API and semantics of CL is pretty much the same as 
guard/with-exception-handler/raise(-continuable) stuff(*).

(*) Actually, ‘guard’ as documented _always_ handles the exception, it just 
re-raises them. It’s not mentioned in Guile, but according to RnRS, it’s 
re-raised in the raise-continuable sense. So this way, it (in theory) has the 
same semantics as CL stuff.

Looking a bit further, there is also this ‘restart’ stuff in CL. But it seems 
Scheme already has this in the form or ‘guard’ + ‘raise-continuable’ (if the 
exception returns a value X, then the (raise-continuable [...]) evaluates to 
X). 

I don’t think it’s completely equivalent, but it seems to provide similar 
functionality, and with some effort you could implement something closer to CL 
with delimited continuations (+ maybe parameters, or their slightly more 
general API, fluids).

There is ‘warn’ which at first seems not to have an equivalent in Guile, but 
all that would need to be done is a top-level exception handler

[define a &ignorable-by-default condition]
(define (warn) (raise-continuable [&message stuff + &warning + 
&ignorable-by-default]))
(guard (c ((ignorable-by-default? c) [print stuff about c] (values)))
  [run main.scm or whatever]).

(I haven’t found search results on what backtrace decorators are in CL.)

>maybe the native call/cc primitive brings in a kind of complexity that is not 
>present in CL around exceptions, unwinding, and backtraces.

There are some implications w.r.t. not misusing parameters for the exception 
handler stack (IIRC, Guile uses the more general fluid stuff instead because of 
this), but otherwise, I don’t think so. I think the problem is just a bug (and 
some of the with-throw-handler stuff that’s making thinking about what’s 
correct/implementing stuff correctly harder).

Best regards,
Maxime Devos

Reply via email to