From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Maxime Devos Newsgroups: gmane.lisp.guile.devel Subject: RE: exception from inside false-if-exception? Date: Thu, 20 Jun 2024 00:03:30 +0200 Message-ID: <20240620000329.da3V2C0080K6dk401a3VaK@xavier.telenet-ops.be> References: <87le4wz1s9.fsf@cbaines.net> <20240506205840.Kuyd2C00E17cfcj01uygoD@xavier.telenet-ops.be> <20240617225055.ckqu2C0045M5ED401kquFP@laurent.telenet-ops.be> <20240619185059.dUqy2C00M0K6dk406UqzfD@michel.telenet-ops.be> Mime-Version: 1.0 Content-Type: multipart/alternative; boundary="_2FA69448-0431-492C-8A8C-6B8D9BCE68CB_" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="15016"; mail-complaints-to="usenet@ciao.gmane.io" Cc: Christopher Baines , "guile-devel@gnu.org" , "46009@debbugs.gnu.org" <46009@debbugs.gnu.org> To: Attila Lendvai Original-X-From: guile-devel-bounces+guile-devel=m.gmane-mx.org@gnu.org Thu Jun 20 00:04:10 2024 Return-path: Envelope-to: guile-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1sK3PV-0003fc-OV for guile-devel@m.gmane-mx.org; Thu, 20 Jun 2024 00:04:10 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sK3P1-0001jT-5y; Wed, 19 Jun 2024 18:03:39 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sK3Oz-0001jK-W1 for guile-devel@gnu.org; Wed, 19 Jun 2024 18:03:38 -0400 Original-Received: from xavier.telenet-ops.be ([2a02:1800:120:4::f00:14]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1sK3Ov-0003QJ-De for guile-devel@gnu.org; Wed, 19 Jun 2024 18:03:37 -0400 Original-Received: from [IPv6:2a02:1811:8c0e:ef00:ad11:ee0:137f:2aa4] ([IPv6:2a02:1811:8c0e:ef00:ad11:ee0:137f:2aa4]) by xavier.telenet-ops.be with bizsmtp id da3V2C0080K6dk401a3VaK; Thu, 20 Jun 2024 00:03:29 +0200 Importance: normal X-Priority: 3 In-Reply-To: DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=telenet.be; s=r24; t=1718834609; bh=ELYe5i63eSJcyw1kyEZYhUtxSeLqJuUmePM0Skkafcs=; h=To:Cc:From:Subject:Date:In-Reply-To:References; b=GaGdRQnP+5FdmVe9jFiW/gLgBnsxXt69CutxN/Nogi2bwHZoNEErS5g0AYKemZ3iN 8CF+aRxHXBWIp2d36N2cUEaktXITiWwNMR0YRBKbfVbTZDSkxq57wrwP5YYJDelisR BlQmH7sepQh7YX44QE2UWqnxeGvnUxU5Rr60yMiW5jXnFZyqdXXbalcUQRQANNOXne yDM7DiOdh2Yt3HO3bNdKGN4ycPjdz1WwYcHQ6Hh55K5icyxtLFh2GdJJXulh3vpzj7 48d/CroDPNk7ejPPoarVVF0h9WV9T3pLTSVA2qT7Ls+Fz3G4JD+WKAWzloag4hAc9b 1ZHSlG+PMogjw== Received-SPF: pass client-ip=2a02:1800:120:4::f00:14; envelope-from=maximedevos@telenet.be; helo=xavier.telenet-ops.be X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_LOW=-0.7, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: guile-devel@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Developers list for Guile, the GNU extensibility library" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guile-devel-bounces+guile-devel=m.gmane-mx.org@gnu.org Original-Sender: guile-devel-bounces+guile-devel=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.lisp.guile.devel:22455 Archived-At: --_2FA69448-0431-492C-8A8C-6B8D9BCE68CB_ Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" > Also, I don=E2=80=99t see a fundamental change in meaning >>just look at my test.scm: >>without the explicit (let/ec return ...) wrapper, and the explicit use of= (return ...) in the handlers, the two invocations lead to different flow o= f control. >>It's icing on the cake that if the underlying ERROR were in fact a RAISE-= CONTINUABLE, then >it wouldn't even lead to a &NON-CONTINUABLE error in the= #:unwind? #f case, only to a >different return value (different flow of co= ntrol). =E2=80=98error=E2=80=99 is a procedure, not something that would be raise-c= ontinuable (I guess you could pass it to =E2=80=98raise-continuable=E2=80= =99, but seems rather unlikely). I propose replacing ERROR by condition (la= ck of quotes and capitals intentional, since I=E2=80=99m referring to the c= oncept here, not a Scheme object or macro and in particular not the macro = =E2=80=98condition=E2=80=99 from SRFI-35 Now I look at the output (somehow when I previously read it I thought it wa= s testing control flow with dynamic-wind, but it turns out it is testing se= mantics instead (without dynamic-wind) =E2=80=93 reading comprehension fail= ure on my part?), the observed behaviour (for v3.0.9) is indeed a significa= nt change. I don=E2=80=99t think test.scm is a good example though =E2=80=93 the outpu= t is, AFAICT, just a bug =E2=80=93 for the nested error, AFAICT neither of = the exception handlers receive the exception, which is plain nonsense. >>In my vocabulary, a different flow of control when using a control-flow p= rimitive is a >>fundamental change to its meaning. but your miliage may war= y of course. It=E2=80=99s not in mine. What matters to me is (denotational) semantics (i= n a broad sense, including things like complexity, whether something is con= stant-time (important for cryptography), etc.). Control-flow is more a oper= ational semantics thing. Often a convenient way of defining the semantics o= f control structures, but ultimately, if with a different control flow you = achieve the same semantics (and aren=E2=80=99t compiling with the equivalen= t of -Og), that=E2=80=99s fine too. >> If we are talking about reading comprehension, I would like to point >> out that (Guile) Scheme is case-sensitive. >for effective communication we need a syntax to designate when a word is t= o be > interpreted in the scheme/lisp domain (as opposed to plain english). usin= g all-caps > in english prose is a somewhat well-spread syntax for that, even in non-C= L lisp > contexts in my experience. A simple syntax is to use quotes, e.g. =E2=80=98call-with-current-continuat= ion=E2=80=99, which is well-spread (even outside programming to some degree= ), and does not require mangling the casing. Depending on the medium, there= are other options like monotype, putting a small box around it or coloring= . For texts (but not e-mail or terminal things), I recommend monotype (and = depending on capabilities of the writing software and aesthetic preferences= , maybe try out things like coloring and boxes). So =E2=80=A6 >> Someone coming from case-insensitive languages and someone > unfamiliar with the upcasing practice might get confused for a > moment. >for a moment. and that is key. =E2=80=A6 why not both eliminate the moment of confusion _and_ use a syntax= that avoids the ambiguity? >> >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. >>=20 > I don=E2=80=99t get the distinction. These are two sides of the same coin= ? > >not really, because there are two, orthogonal dimensions here: > >1) whether to unwind the stack, > >2) where to return the control flow when the handler returns. > >(even if one combination is impossible) Err, all four combinations are possible with sufficient application of deli= mited continuations. If you have unwinded you can just rewind (if you have = captured continuation things and accept the change in visible behaviour to = =E2=80=98dynamic-wind=E2=80=99, the first is not a given because of perform= ance consid=C3=A9rations and the latter isn=E2=80=99t a given because, well= , different behaviour). There are two components to (1): (1)(a): what does dynamic-wind see? (1)(b): how does unwinding affect the dynamic environment of the handler= . For (2): first, there is no =E2=80=98return the control flow=E2=80=99 happe= ning! The returning is all in tail position (albeit with some extra layers = in the dynamic environment, so don=E2=80=99t do tail loops with with-except= ion-handler or you will use lots of memory) =E2=80=93 according to the docs= , once the handler is invoked, with-exception-handler stops doing things. As mentioned in the documentation: > https://www.gnu.org/software/guile/manual/html_node/Raising-and-Handling-= Exceptions.html >Unless=C2=A0with-exception-handler=C2=A0was invoked with=C2=A0#:unwind? #t= , exception handlers are invoked __within the continuation of the error__, = without unwinding the stack. The dynamic environment of the handler call wi= ll be that of the=C2=A0raise-exception=C2=A0call, with the difference that = the current exception handler will be =E2=80=9Cunwound=E2=80=9D to the \"ou= ter\" handler (the one that was in place when the corresponding=C2=A0with-e= xception-handler=C2=A0was called). > [=E2=80=A6] >=C2=A0if=C2=A0with-exception-handler=C2=A0was invoked with=C2=A0#:unwind? = #t=C2=A0is true,=C2=A0raise-exception=C2=A0will first unwind the stack by i= nvoking an=C2=A0escape continuation=C2=A0(see=C2=A0call/ec), and then invok= e the handler __with the continuation of the=C2=A0with-exception-handler=C2= =A0call__. (emphasis added with __) Now, while =E2=80=98return the control flow=E2=80=99 is not accurate, there= is definitely some control flow manipulation going on (see: =E2=80=98call/= ec=E2=80=99). But consider this: whether you are in tail-position w.r.t. so= mething, is a property of the dynamic environment! I mean, it definitely is= visible in backtraces (which you can make with =E2=80=98(backtrace)=E2=80= =99, doesn=E2=80=99t need exceptions). Let=E2=80=99s look at some R6RS definitions=C2=A0: >For a procedure call, the time between when it is initiated and when it re= turns is called its dynamic extent. [currently irrelevant things about call= /cc] >Some operations described in the report acquire information in addition to= their explicit arguments from the dynamic environment. (Technically it doesn=E2=80=99t state that the concept of =E2=80=98dynamic = environment=E2=80=99 includes the =E2=80=98dynamic extent=E2=80=99, but it = seems quite natural to consider all the dynamicness together, and =E2=80=98= environment=E2=80=99 seems a sufficiently generic word to also include the = =E2=80=98extent=E2=80=99.) (dynamic extent <-> a region of stack, without focus on what the dynamic bi= ndings in that stack are, dynamic environment <-> the full stack upto a poi= nt, with a focus at what=E2=80=99s visible at the point] Summarised: stack stuff is part of the dynamic environment, control flow is= stack stuff, so control flow is dynamic environment stuff. >> >for reference, in CL they are called HANDLER-CASE and HANDLER-BIND, wit= h >completely different syntaxes. >> >> Can=E2=80=99t honestly say I like those names (those suffixes -CASE / -B= IND >> don=E2=80=99t really provide information, you have to go into the spec o= f >> HANDLER-CASE / HANDLER-BIND itself to get the differences). >my point is not whether it's deducible, or whether the names are good. my = point is that one API is misleading (i.e. wastes human time), while the oth= er forces the reader to, at worst, look up the documentation. but certainly= not conflate the two, thinking that they are doing the same thing -- plus = some implementation detail regarding unwinding that he can postpone learnin= g about. It wasn=E2=80=99t my point either, I didn=E2=80=99t think you liked them ei= ther, I didn=E2=80=99t think your point was whether it=E2=80=99s deducible,= I just interpreted it as an example of splitting stuff up and wanted to ma= ke clear those don=E2=80=99t seem good names. >here's a caricature of this situation: > >imagine a hypothetical (raise [a potentially larger sexp] #:enabled? #t/#f= ) control flow primitive that simply returns when #:enabled? is #f. > >one can argue that "well, it's disabled, dummy!" (turing tarpit), or try t= o walk in the shoes of the reader or a newcomer. > >yes, you're right when you say something is possible, or deducible. but no= , with all due respect, you're wrong when you imply that it doesn't make a = difference (in human-brain efficiency). With all due respect, that=E2=80=99s a strawman (as expected by a caricatur= e). I never claimed #:unwind? is a great name, that keyword #:enabled? is terri= bly named and even worse than #:disable, both you and I previously made cle= ar that naming is important, I proposed renamings of #:unwind? to other thi= ngs (that you even agreed to were better) or proposals for names for splitt= ing up the procedure (not great names, but still more descriptive than #:en= abled? Of all things). Also, let=E2=80=99s do this walking into the shoes of the newcomer. As a ne= wcomer, one of the things I do is _reading the documentation_ (I have heard= this is a rare thing, but I actually do this, and did this). As a newcomer, I find these references to delimited continuations, dynamic = environment and tail call thingies, really interesting and cool, so I read = a lot about it (more than I actually use them, even!) and try it out a bit.= I also see these mentions of virtual machines and stack frames. I read tho= se too of course, how stack frames are done is really cool and interesting = (VM a bit less so, but still ok to skim through). As a reader, I also think that sometimes the descriptions aren=E2=80=99t do= ne well =E2=80=93 it=E2=80=99s not a verbosity thing despite what some woul= d say, but more a structure thing (both local or global). But that=E2=80=99= s a property of the documentation, not the API. I also thing that occassionally the APIs aren=E2=80=99t quite right, making= it difficult to understand when to, say, use #:unwind? #false/#true. But a= s a newcomer, I don=E2=80=99t _need_ to know those distinctions, I can just= assume the default is fine and avoid doing fancy dynamic environment stuff= inside the exception handler. So, I can just avoid the complicated unwindi= ng-or-not stuff until I=E2=80=99m not a newcomer anymore, and once that=E2= =80=99s the case, I can start thinking about how to improve API stuff and u= tilise the fancy stuff. Going back to the strawman: > you're wrong when you imply that it doesn't make a difference (in human-b= rain efficiency). I didn=E2=80=99t imply this! Just because I said you need to _read the docu= mentation_ doesn=E2=80=99t mean that naming and the like can=E2=80=99t be i= mproved, the existence of a =E2=80=98problem between monitor and chair=E2= =80=99 does not exclude the existence of a problem in the software as well.= Also that the status quo is ok doesn=E2=80=99t mean it can=E2=80=99t be be= improved. (I think the _name_ itself is fine, rather, I think that the _concept_ that= it represents would preferably be changed to something different (and natu= rally this change in concept induces a change in name and perhaps semantics= as well).) >> Maybe you can install a breakpoint on >> scm_c_with_continuation_barrier or something > >it assumes that it's already known that the curlpit is w-c-b, but that was= already well >into the debugging effort. see my attached patch that intend= s to greatly shorten the >debugging time for anyone else walking down this = path after me. > >and it's been decades i've done any serious C coding, and i'm not looking = forward to >learning the ins and outs of gdb when i'm debugging an issue in= scheme. Of course it assumes that the culprit is =E2=80=98with-continuation-barrier= =E2=80=99. You provided the information that =E2=80=98with-continuation-bar= rier=E2=80=99 might have something to do with the issue to me. Also, I didn= =E2=80=99t mention gdb anywhere. It=E2=80=99s a common debugger, but not th= e only one. And neither did I mention learning the ins and outs =E2=80=93 s= etting up a breakpoint and asking gdb to print a backtrace is hardly =E2=80= =98the ins and outs=E2=80=99. (Whether the information of the backtrace wil= l prove useful is another matter.) Also, difficulty with C debugging is your problem, not mine =E2=80=93 this = thread isn=E2=80=99t named =E2=80=9Chow to simplify debugging from C=E2=80= =9D, as a volunteer I=E2=80=99m just mentioning some options to consider an= d I=E2=80=99m not your boss. Besides, given that the existence of FFI and t= he like, and that Guile it partially implemented in C instead of Scheme, it= isn=E2=80=99t a given that the issue you are debugging is, in fact, fully = in Scheme. (Also maybe look if Shepherd is doing REPL stuff. The REPL implementation i= n Guile installs (in Scheme!) a continuation barrier.) > I don=E2=80=99t think Shepherd has much use of with-continuation-barrier. > > IIUC, any time the posix thread enters C code is an implicit continuation= barrier. if a > fiber in shepherd uses any primitive in guile that is implemented in C, t= hen it's a > continuation barrier (and breaks when an attempt is made to suspend that = fiber). Not in the sense of with-continuation-barrier. C code can throw Scheme exce= ptions and those exception can in turn be caught by normal Scheme exception= (but no raise-continuable stuff from C). On a related note, there is also some (non-Scheme) dynwind-rewind stuff in = Guile=E2=80=99s C code. I don=E2=80=99t have a clue on how that works and i= f it even works at all. > changing shepherd not to unconditionally unwind (so that meaningful backt= races > can be logged) can lead to subtle issues due to now having some extra C f= rames on > the stack that were previously unwound prior to handling the error. That=E2=80=99s not unwinding, that=E2=80=99s rewinding. Unwinding can=E2=80= =99t lead to leaving extra C frames on the stack, because removing those C = frames is part of the unwinding process and C frames are only generated by = C code. (Except perhaps for that dynwind-rewind stuff, but if it does that= stuff, presumably it is prepared to deal with rewinding.) Hypothetically a Scheme implementation could put C frames back onto the sta= ck, but Guile doesn=E2=80=99t do this =E2=80=93 whenever this would happen,= it simply refuses(*). (IIRC it does so by throwing an exception.). From th= e documentation: (*) besides perhaps that dynwind-rewind stuff. >Scheme Procedure: suspendable-continuation? tag >Return #t if a call to abort-to-prompt with the prompt tag tag would produ= ce a >delimited continuation that could be resumed later. > >Almost all continuations have this property. The exception is where some c= ode between the call-with-prompt and the abort-to-prompt recursed through C= for some reason, the abort-to-prompt will succeed but any attempt to resum= e the continuation (by calling it) would fail. This is because composing a = saved continuation with the current continuation involves relocating the st= ack frames that were saved from the old stack onto a (possibly) new positio= n on the new stack, and Guile can only do this for stack frames that it cre= ated for Scheme code, not stack frames created by the C compiler. It=E2=80= =99s a bit gnarly but if you stick with Scheme, you won=E2=80=99t have any = problem. > >If no prompt is found with the given tag, this procedure just returns #f. Best regards, Maxime Devos. --_2FA69448-0431-492C-8A8C-6B8D9BCE68CB_ Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset="utf-8"

= > Also, I don=E2=80=99t see a fundamental change in m= eaning

>>= ;just look at my test.scm:

 

>>without the explicit (let/ec return ...) wrapper, and the exp= licit use of (return ...) in the handlers, the two invocations lead to diff= erent flow of control.

>>It's icing on the cake that if the underlying ERROR were i= n fact a RAISE-CONTINUABLE, then >it wouldn't even lead to a &NON-CO= NTINUABLE error in the #:unwind? #f case, only to a >different return va= lue (different flow of control).

=  

=E2=80=98error=E2=80=99 is a procedure, not something that woul= d be raise-continuable (I guess you could pass it to =E2=80=98raise-continu= able=E2=80=99, but seems rather unlikely). I propose replacing ERROR by con= dition (lack of quotes and capitals intentional, since I=E2=80=99m referrin= g to the concept here, not a Scheme object or macro and in particular not t= he macro =E2=80=98condition=E2=80=99 from SRFI-35

 

Now I look at the output (somehow when I previ= ously read it I thought it was testing control flow with dynamic-wind, but = it turns out it is testing semantics instead (without dynamic-wind) =E2=80= =93 reading comprehension failure on my part?), the observed behaviour (for= v3.0.9) is indeed a significant change.

 

I don=E2=80=99t think test.scm is a good example though= =E2=80=93 the output is, AFAICT, just a bug =E2=80=93 for the nested error= , AFAICT neither of the exception handlers receive the exception, which is = plain nonsense.

 

>&= gt;In my vocabulary, a different flow of control when using a control-flow = primitive is a >>fundamental change to its meaning. but your miliage = may wary of course.

 

I= t=E2=80=99s not in mine. What matters to me is (denotational) semantics (in= a broad sense, including things like complexity, whether something is cons= tant-time (important for cryptography), etc.). Control-flow is more a opera= tional semantics thing. Often a convenient way of defining the semantics of= control structures, but ultimately, if with a different control flow you a= chieve the same semantics (and aren=E2=80=99t compiling with the equivalent= of -Og), that=E2=80=99s fine too.

 

>> If we are talking about reading comprehension, I wou= ld like to point

>> out that (Guile) Scheme is case-sensitive.

>for effective communication we= need a syntax to designate when a word is to be

> interpreted in the scheme/lisp doma= in (as opposed to plain english). using all-caps

> in english prose is a somewhat well= -spread syntax for that, even in non-CL lisp

> contexts in my experience.<= /span>

 <= /p>

A simple syntax is to use quotes= , e.g. =E2=80=98call-with-current-continuation=E2=80=99, which is well-spre= ad (even outside programming to some degree), and does not require mangling= the casing. Depending on the medium, there are other options like monotype= , putting a small box around it or coloring. For texts (but not e-mail or t= erminal things), I recommend monotype (and depending on capabilities of the= writing software and aesthetic preferences, maybe try out things like colo= ring and boxes).

 

So = =E2=80=A6

 

>= > Someone coming from case-insensitive languages and someone<= /p>

> unfamiliar with the upcasing practice might ge= t confused for a

> moment.=

>for a moment. and that is key.

<= p class=3DMsoNormal> 

=E2=80=A6 why not both eliminate the moment= of confusion _and_ use a syntax that avoids the ambiguity?

 

>> >that would be be= tter, but i still wouldn't like the fact that it's

>> >focusing on the dynamic c= ontext of the handler, instead of the

>> >different flow of control.<= /span>

>>

> I don=E2=80=99t get the = distinction. These are two sides of the same coin?

> 

>not really, because there are two, or= thogonal dimensions here:

> 

>1) whether to unwind the stack,

> 

>2) where to return the control flow when t= he handler returns.

> 

>(even if one combination is impossible)

 

Err, all four combinations are possible with suff= icient application of delimited continuations. If you have unwinded you can= just rewind (if you have captured continuation things and accept the chang= e in visible behaviour to =E2=80=98dynamic-wind=E2=80=99, the first is not = a given because of performance consid=C3=A9rations and the latter isn=E2=80= =99t a given because, well, different behaviour).

 

There are two components to (1):

 

=C2=A0=C2=A0 (1)(a): what does dyn= amic-wind see?

=C2=A0=C2=A0 (1)(b): how does unwinding affect the dynamic environment of = the handler.

<= o:p> 

For (2):= first, there is no =E2=80=98return the control flow=E2=80=99 happening! Th= e returning is all in tail position (albeit with some extra layers in the d= ynamic environment, so don=E2=80=99t do tail loops with with-exception-hand= ler or you will use lots of memory) =E2=80=93 according to the docs, once t= he handler is invoked, with-exception-handler stops doing things.

 

As mentioned in the documentat= ion:

&nbs= p;

> https://www.gnu.org/software/guile/manual/html_node/Raising-= and-Handling-Exceptions.html

= >Unless with-excep= tion-handler was inv= oked with #:unwind? #t, exception handlers are invoked __within the continuation o= f the error__, without unwinding the stack. The dynamic environment of the = handler call will be that of the raise-exception call, with the difference th= at the current exception handler will be =E2=80=9Cunwound=E2=80=9D to the \= "outer\" handler (the one that was in place when the correspondin= g with-exception-handler was called).

> [=E2=80=A6]=

> if with-exception-handler was invoked with = ;#:unwind? #t is true, raise-exception will first unwind the stack by invoking an&= nbsp;escape continuation (see = call/ec), and then invoke the handler __with the continuation= of the with-exception-handler call__.

 

(emphasis added with __)

 

Now, while =E2=80=98return th= e control flow=E2=80=99 is not accurate, there is definitely some control f= low manipulation going on (see: =E2=80=98call/ec=E2=80=99). But consider th= is: whether you are in tail-position w.r.t. something, is a property of the= dynamic environment! I mean, it definitely is visible in backtraces (which= you can make with =E2=80=98(backtrace)=E2=80=99, doesn=E2=80=99t need exce= ptions).

=  

Let=E2=80=99= s look at some R6RS definitions :

 

<= span lang=3DFR-BE>>For a procedure call, the time between when it is ini= tiated and when it returns is called its dynamic extent. [currently irrelev= ant things about call/cc]

>Some operations described in the report acquire information= in addition to their explicit arguments from the dynamic environment.=

 <= /span>

(Technically it doesn=E2= =80=99t state that the concept of =E2=80=98dynamic environment=E2=80=99 inc= ludes the =E2=80=98dynamic extent=E2=80=99, but it seems quite natural to c= onsider all the dynamicness together, and =E2=80=98environment=E2=80=99 see= ms a sufficiently generic word to also include the =E2=80=98extent=E2=80=99= .)

 =

(dynamic extent &l= t;-> a region of stack, without focus on what the dynamic bindings in th= at stack are, dynamic environment <-> the full stack upto a point, wi= th a focus at what=E2=80=99s visible at the point]

 

Summarised: stack stuff is part of the dyna= mic environment, control flow is stack stuff, so control flow is dynamic en= vironment stuff.

 

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

>> 

>> Can=E2=80=99t honestly say I like tho= se names (those suffixes -CASE / -BIND

>> don=E2=80=99t really provide information,= you have to go into the spec of

= >> HANDLER-CASE / HANDLER-BIND itself to get the d= ifferences).

<= o:p> 

>my p= oint is not whether it's deducible, or whether the names are good. my point= is that one API is misleading (i.e. wastes human time), while the other fo= rces the reader to, at worst, look up the documentation. but certainly not = conflate the two, thinking that they are doing the same thing -- plus some = implementation detail regarding unwinding that he can postpone learning abo= ut.

 = ;

It wasn=E2=80=99t= my point either, I didn=E2=80=99t think you liked them either, I didn=E2= =80=99t think your point was whether it=E2=80=99s deducible, I just interpr= eted it as an example of splitting stuff up and wanted to make clear those = don=E2=80=99t seem good names.

 

>here's a caricature of this situation:

<= p class=3DMsoNormal>> 

>imagine a hypothetical (raise [a po= tentially larger sexp] #:enabled? #t/#f) control flow primitive that simply= returns when #:enabled? is #f.

<= span lang=3DFR-BE>> 

>one can argue that "well, it's disabled, dummy!&quo= t; (turing tarpit), or try to walk in the shoes of the reader or a newcomer= .

>&nb= sp;

>yes, you're= right when you say something is possible, or deducible. but no, with all d= ue respect, you're wrong when you imply that it doesn't make a difference (= in human-brain efficiency).

 

With all due respect, that=E2=80=99s a strawman (as expected by a = caricature).

<= o:p> 

I never = claimed #:unwind? is a great name, that keyword #:enabled? is terribly name= d and even worse than #:disable, both you and I previously made clear that = naming is important, I proposed renamings of #:unwind? to other things (tha= t you even agreed to were better) or proposals for names for splitting up t= he procedure (not great names, but still more descriptive than #:enabled? O= f all things).

 

Also, = let=E2=80=99s do this walking into the shoes of the newcomer. As a newcomer= , one of the things I do is _reading the documentation_ (I have hear= d this is a rare thing, but I actually do this, and did this).

 

As a newcomer, I find these refer= ences to delimited continuations, dynamic environment and tail call thingie= s, really interesting and cool, so I read a lot about it (more than I actua= lly use them, even!) and try it out a bit. I also see these mentions of vir= tual machines and stack frames. I read those too of course, how stack frame= s are done is really cool and interesting (VM a bit less so, but still ok t= o skim through).

 

As a= reader, I also think that sometimes the descriptions aren=E2=80=99t done w= ell =E2=80=93 it=E2=80=99s not a verbosity thing despite what some would sa= y, but more a structure thing (both local or global). But that=E2=80=99s a = property of the documentation, not the API.

 

I also thing that occassionally the APIs aren=E2= =80=99t quite right, making it difficult to understand when to, say, use #:= unwind? #false/#true. But as a newcomer, I don=E2=80=99t _need_ to k= now those distinctions, I can just assume the default is fine and avoid doi= ng fancy dynamic environment stuff inside the exception handler. So, I can = just avoid the complicated unwinding-or-not stuff until I=E2=80=99m not a n= ewcomer anymore, and once that=E2=80=99s the case, I can start thinking abo= ut how to improve API stuff and utilise the fancy stuff.<= /p>

 

Going back to the strawman:<= /span>

 <= /p>

> you're wrong when you imply= that it doesn't make a difference (in human-brain efficiency).<= /span>

 <= /p>

I didn=E2=80=99t imply this! Jus= t because I said you need to _read the documentation_ doesn=E2=80=99= t mean that naming and the like can=E2=80=99t be improved, the existence of= a =E2=80=98problem between monitor and chair=E2=80=99 does not exclude the= existence of a problem in the software as well. Also that the status quo i= s ok doesn=E2=80=99t mean it can=E2=80=99t be be improved.

 

(I think the _name_ itself is = fine, rather, I think that the _concept_ that it represents would pr= eferably be changed to something different (and naturally this change in co= ncept induces a change in name and perhaps semantics as well).)<= /span>

 <= /p>

>> Maybe you can install a= breakpoint on

>> scm_c_with_continuation_barrier or something

> 

>it assumes that it's already know= n that the curlpit is w-c-b, but that was already well >into the debuggi= ng effort. see my attached patch that intends to greatly shorten the >de= bugging time for anyone else walking down this path after me.

> 

>and it's been decades i've= done any serious C coding, and i'm not looking forward to >learning the= ins and outs of gdb when i'm debugging an issue in scheme.

 

<= p class=3DMsoNormal>Of course it assumes that the culpri= t is =E2=80=98with-continuation-barrier=E2=80=99. You provided the informat= ion that =E2=80=98with-continuation-barrier=E2=80=99 might have something t= o do with the issue to me. Also, I didn=E2=80=99t mention gdb anywhere. It= =E2=80=99s a common debugger, but not the only one. And neither did I menti= on learning the ins and outs =E2=80=93 setting up a breakpoint and asking g= db to print a backtrace is hardly =E2=80=98the ins and outs=E2=80=99. (Whet= her the information of the backtrace will prove useful is another matter.)<= o:p>

 

Also, difficulty with= C debugging is your problem, not mine =E2=80=93 this thread isn=E2=80=99t = named =E2=80=9Chow to simplify debugging from C=E2=80=9D, as a volunteer I= =E2=80=99m just mentioning some options to consider and I=E2=80=99m not you= r boss. Besides, given that the existence of FFI and the like, and that Gui= le it partially implemented in C instead of Scheme, it isn=E2=80=99t a give= n that the issue you are debugging is, in fact, fully in Scheme.=

 =

(Also maybe look if Shepherd is= doing REPL stuff. The REPL implementation in Guile installs (in Scheme!) a= continuation barrier.)

 

> I don=E2=80=99t think Shepherd has much use of with-continuation-ba= rrier.

> 

> IIUC,= any time the posix thread enters C code is an implicit continuation barrie= r. if a

> f= iber in shepherd uses any primitive in guile that is implemented in C, then= it's a

> c= ontinuation barrier (and breaks when an attempt is made to suspend that fib= er).

&nbs= p;

Not in the sense= of with-continuation-barrier. C code can throw Scheme exceptions and those= exception can in turn be caught by normal Scheme exception (but no raise-c= ontinuable stuff from C).

 

On a related note, there is also some (non-Scheme) dynwind-rewind stuf= f in Guile=E2=80=99s C code. I don=E2=80=99t have a clue on how that works = and if it even works at all.

 

> changing shepherd not to unconditionally unwind (so that mean= ingful backtraces

> can be logged) can lead to subtle issues due to now having some ex= tra C frames on

> the stack that were previously unwound prior to handling the error.<= o:p>

 

That=E2=80=99s not un= winding, that=E2=80=99s rewinding. Unwinding can=E2=80=99t lead to leaving = extra C frames on the stack, because removing those C frames is part of the= unwinding process and C frames are only generated by C code.=C2=A0 (Except= perhaps for that dynwind-rewind stuff, but if it does that stuff, presumab= ly it is prepared to deal with rewinding.)

 

Hypothetically a Scheme implementation could put C fr= ames back onto the stack, but Guile doesn=E2=80=99t do this =E2=80=93 whene= ver this would happen, it simply refuses(*). (IIRC it does so by throwing a= n exception.). From the documentation:

 

<= span lang=3Den-BE>(*) besides perhaps that dynwind-rewind stuff.=

 =

>Scheme Procedure: suspendab= le-continuation? tag

>Return #t if a call to abort-to-prompt with the prompt tag tag= would produce a >delimited continuation that could be resumed later.

> <= /o:p>

>Almost all cont= inuations have this property. The exception is where some code between the = call-with-prompt and the abort-to-prompt recursed through C for some reason= , the abort-to-prompt will succeed but any attempt to resume the continuati= on (by calling it) would fail. This is because composing a saved continuati= on with the current continuation involves relocating the stack frames that = were saved from the old stack onto a (possibly) new position on the new sta= ck, and Guile can only do this for stack frames that it created for Scheme = code, not stack frames created by the C compiler. It=E2=80=99s a bit gnarly= but if you stick with Scheme, you won=E2=80=99t have any problem.

> <= /span>

>If no prompt is found= with the given tag, this procedure just returns #f.

<= p class=3DMsoNormal> 

Best regards,

Maxime Devos.

= --_2FA69448-0431-492C-8A8C-6B8D9BCE68CB_--