Subject: Re: bug#76200: `with-parameters*' seems to create a continuation barrier

From: Linus Björnstam <[email-masked]>
Date: Fri, 14 Feb 2025 08:57:32 +0100

It seems with-fluids* (used by with-parameters*) is still a c function. I am not really sure how that stuff works, but I believe C can (always?) impose continuation barriers of delimited continuations. 

 If you look at the source of parameterize, with-fluids, with-fluids* (and more?) in boot-9 ther are all using scheme functions, or things defined in the VM, whereas srfi-39 depends on with-fluids* that is defined in fluids.c. 

If the transform from let to let* extends to with-fluids->with-fluids* it should be a trivial thing to put into boot-9.scm, but I rarely dabble with dynamic environments and whatever is in the documentation is somewhat opaque. 

Best regards
  Linus Björnstam

On Tue, 11 Feb 2025, at 11:59, W. Kosior via Bug reports for GUILE, GNU's Ubiquitous Extension Language wrote:
> Hello,
>
> I've been experimenting with guile-fibers.  I noticed that
> `with-parameters*' procedure included as an "extra" in Guile's srfi-39
> creates a continuation barrier.  From the documentation it is not clear
> that it does so.
>
> Consider this sample program (which I ran with Guile 3.0.9 and Fibers
> 1.0.0, as they are defined in Guix
> 2fda889ac992977af7b4cd96d09f737d834e0b2d):
>
> --8<---------------cut here---------------start------------->8---
> (use-modules (fibers)
>              (fibers channels)
>              (srfi srfi-18)
>              ((srfi srfi-39) #:select (with-parameters*)))
>
> (define %my-channel
>   (make-channel))
>
> (define %my-param
>   (make-parameter #f))
>
> (define %my-thread
>   (make-thread (lambda ()
>                  (run-fibers (lambda ()
>                                (with-parameters* (list %my-param) '(hello)
>                                  (lambda ()
>                                    (put-message %my-channel (%my-param))
>                                    'ok)))))))
>
> (thread-start! %my-thread)
>
> (format #t "message: ~a~%" (get-message %my-channel))
>
> (thread-join! %my-thread)
> --8<---------------cut here---------------end--------------->8---
>
> It prints:
>
>> Uncaught exception in task:
>> In fibers.scm:
>>    186:20  6 (_)
>>    145:21  5 (_)
>> In unknown file:
>>            4 (with-fluids* (#<fluid 7f192cf70d70>) (hello) #<procedure 100903e0 at <…>)
>> In current input:
>>     17:35  3 (_)
>> In fibers/operations.scm:
>>    154:10  2 (perform-operation _)
>> In fibers/scheduler.scm:
>>     357:6  1 (suspend-current-task _)
>> In ice-9/boot-9.scm:
>>   1685:16  0 (raise-exception _ #:continuable? _)
>> ice-9/boot-9.scm:1685:16: In procedure raise-exception:
>> Attempt to suspend fiber within continuation barrier
>
> But if I use `parameterize' rather than `with-parameters*', no errors
> occur.  Here's an example of a working program:
>
> --8<---------------cut here---------------start------------->8---
> (use-modules (fibers)
>              (fibers channels)
>              (srfi srfi-18))
>
> (define %my-channel
>   (make-channel))
>
> (define %my-param
>   (make-parameter #f))
>
> (define %my-thread
>   (make-thread (lambda ()
>                  (run-fibers (lambda ()
>                                (parameterize ((%my-param 'hello))
>                                  (put-message %my-channel (%my-param))
>                                  'ok))))))
>
> (thread-start! %my-thread)
>
> (format #t "message: ~a~%" (get-message %my-channel))
>
> (thread-join! %my-thread)
> --8<---------------cut here---------------end--------------->8---
>
> It prints:
>
>> message: hello
>
> Is it a bug that `with-parameters*' doesn't work equivalently?  Or am I
> reading the info pages wrong?
>
> Best :)
> Wojtek
>
> --
> W. Kosior
>
> website: https://koszko.org/koszko.html
> fediverse: https://friendica.me/profile/koszko/profile
> PGP fingerprint: E972 7060 E3C5 637C 8A4F  4B42 4BC5 221C 5A79 FD1A