I don’t think we are going to agree on much here, but some new points of 
agreement pop up occassionally. Continuing this …

>> What is lousy and expectation-violating about a keyword argument
>> doing what it name describes?
>well, this should have been discussed at the R6RS committee, but...

This is not something to be discussed at the R6RS committee, because #:unwind? 
is a Guile extension, not part of R6RS. Unless the idea is to (in an alternate 
past) have introduced keyword arguments to R6RS and this is about keyword 
argument stuff.

>an API is facilitating efficient reading comprehension when the "verbs" are 
>closer to the beginning of the "sentence" (the sexp), and nothing later in the 
>sentence adjusts the meaning of the verb fundamentally.

Do you have evidence for this? I mean, beyond your own experience, anecdotal 
evidence doesn’t generalise well. (Not that I don’t use anecdotal evidence or 
the like myself, but it would be better if at least one of us has something 
better.)

Also, I don’t see a fundamental change in meaning, except in the sense that 
anything could be considered fundamental, just like every two topics are 
related however distantly, etc..  #:unwind? #true/#false is too small a change 
for me to consider ‘fundamental’ – both #true?/#false result in exception 
handling, just slightly different exception handling. Neither do I really have 
an argument to consider it un-fundamental, size isn’t everything. In this 
context, it’s too meaningless a label to base things on or me.

Also, I disagree – this is not a garden path sentence situation (where, and OV 
(object-verb) languages exist. If you want to understand a sentence just read 
the entire sentence?

Now, I did some quick searches for differences in reading comprehension for 
OV/VO languages, and unfortunately found nothing relevant (neither positive nor 
negative nor neutral).

If we are talking about reading comprehension, I would like to point out that 
(Guile) Scheme is case-sensitive. I’d consider it beneficial to reading 
comprehension if the procedure names that are written in documentation 
correspond to what’s recognised by the implementation. Someone coming from 
case-insensitive languages and someone unfamiliar with the upcasing practice 
might get confused for a moment.

> and especially not a keyword arg at the end of the sentence that is not even 
> mandatory, and defaults to one of the rather different possibilities.

Also, I would rather not have the keyword argument at the front. Usually 
keyword arguments aren’t verbs and better fit for the end of the procedure 
call, and even if they were sometimes better suited for the beginning, you now 
have a situation where sometimes keyword arguments are at the front and other 
times are at the end, which creates ambiguity when interpreting the arguments.

Another interpretation of this would be to replace the keyword argument by an 
optional argument, but optional arguments are at the end, so same thing.

A potential way to avoid this is to split things off into a new procedure, say 
with-exception-handler/unwinding or with-exception-handler/winding (well not 
these precise name because of issues mentioned earlier). While both provide a 
similar function (to the point that often you can swap between the two without 
trouble), if you were to precisely document them or implement them, the 
documentation and implementation would be rather different, so I think this 
would be better than an argument (whether (non-)keyword or optional or 
required) (it’s not like the unwinding-ness varies dynamically in practice, so 
not really a point in sharing a procedure name).

(I don’t think this really is an improvement in readability though, just a 
neatness thing.)

>in this case, it's a primitive to catch and handle exceptions. and it's 
>possible to implement both #:unwind? #t and #f so that when the handler 
>returns then the control flow continues at the guard, and never at the RAISE. 
>it's just that one version would call the handler before unwinding.

AFAICT this paragraph as-written is technically true, but rather misleading – 
there is also raise-continuable, where the control flow needs to continue at 
raise-continuable.

>> If you have unwinded, it’s too late to return return from the raise
>> (unless the implementation is doing delimited continuations
>> shenanigans, which maybe you had in mind?), which explains the
>> behaviour for #:unwind #true.
>
>i didn't have anything on my mind, and that's the point. i'm simply new to 
>scheme. >now that i've learned it, i'll learn to live with it.

[no replies to this part, I just don’t want to trim context / disrupt flow here]

>put another way, my learning curve would have been much steeper if the two, 
>>rather different behaviors were defined under two distinct names (or at least 
>>mentioned with bold in the documentation).

At first, I was going to write that you probably meant to write the opposite 
that if the different behaviour were more clearly different (e.g. with distinct 
names), then the learning would be _less_ steep, but now I read (Wikipedia 
article on learning curves):

>The common expression "a steep learning curve" is a misnomer suggesting that an
> activity is difficult to learn and that expending much effort does not 
> increase
> proficiency by much, although a learning curve with a steep start actually 
> represents
> rapid progress.[2][3]

(reading comprehension failure).

>> That said, I would prefer it to be named something like [#:handler-context 
>> 'raise]/[#:handler-context 'guard]

>that would be better, but i still wouldn't like the fact that it's focusing on 
>the dynamic context of the handler, instead of the different flow of control.

I don’t get the distinction. These are two sides of the same coin? Almost 
equivalent, though I suppose that flow of control is a bit more general since 
if you only have info on the dynamic context then multiple flow of controls 
remain possible (but I don’t know any important change of flow that’s still 
correct exception handling).

Also, for a hypothetical #: [something flowy], I don’t like the fact that it’s 
focusing on the flow of control instead of the dynamic context of the handler.

Whenever I do #:unwind? #false/#:true (#:handler-context ‘raise’), it’s to get 
the dynamic environment/context (I forgot standard terminology) right (think 
call stack and parameter bindings (either at raise or guard, depending on what 
you are implementing)). I don’t really care about Guile does the control flow 
is implemented, as long as the dynamic environment is correct and 
raise-continuable functions (though TBH I almost never use raise-continuable, 
and when I do, I always think something along the lines of “neat that this is 
possible, but there are other methods that are simpler both to implement 
(whether caller/callee) and to understand”).

>for reference, in CL they are called HANDLER-CASE and HANDLER-BIND, with 
>completely different syntaxes.

Can’t honestly say I like those names (those suffixes -CASE / -BIND don’t 
really provide information, you have to go into the spec of HANDLER-CASE / 
HANDLER-BIND itself to get the differences).

Going by this and some earlier text, it seems we are in agreement that 
with-exception-handler should be split (albeit for different reasons).

>> Wait where did this happen? You say what’s happening, but you don’t
>> seem to be referring to false-if-exception stuff, and you didn’t
>> mention continuation barriers earlier.

>this has caused me layers of confusion, which is sadly reflected in my mails.

>guile prints a backtrace without any prelude, which made me think that it's my 
>own code that is printing this backtrace and exception in the logs (remember, 
>i'm working on nested error handling and logging in shepherd). then 3.0.9 does 
>something funny with the control flow, which further made me believe that i'm 
>logging an exception coming from inside FALSE-IF-EXCEPTION and it's somehow 
>flying past my error handler, and reaching fibers.
>
>and i think i'm still confused about a possible continuation barrier being 
>injected somewhere that probably/maybe causes the exception from inside 
>FALSE-IF-EXCEPTION somehow ending up at fibers instead of my error handler. 
>but at this point i'm reaching the frontier of my understanding of scheme, 
>delimited continuations, fibers, etc.
>
>so, one step at a time. once this test.scm is clear, and i'm able to run 
>shepherd on guile-next, then i'll get back to investigate my original issue in 
>its original context.

Maybe you can install a breakpoint on scm_c_with_continuation_barrier or 
something, and see when this happens. Or search for with-continuation-barror in 
Scheme code. I don’t think Shepherd has much use of with-continuation-barrier. 
If it does, it’s a rather crude tool and can probably be replaced by something 
else that doesn’t replace the exception handler.

I don’t know what you are investigating precisely, but maybe it is

>https://sources.debian.org/src/guix/1.4.0-6/gnu/build/shepherd.scm/?hl=112#L109

If it is this, surely (@ (fibers) sleep) could be adjusted to _not_ suspend 
(and instead just, well, sleep) when there is no Fibers task scheduler (similar 
stuff exists for the (Fibers) channels and conditions implementation).

Best regards,
Maxime Devos.

Reply via email to