unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
From: Zelphir Kaltstahl <zelphirkaltstahl@posteo.de>
To: guile-user@gnu.org
Subject: Re: Guile fibers return values
Date: Sun, 5 Jan 2020 02:30:06 +0100	[thread overview]
Message-ID: <d7e44d35-27b5-b93f-ab83-c365c42d1b6e@posteo.de> (raw)

Hello Guile Users,

so I figured out an example for using channels, but I am not sure, if
that is the only way to get results from a fiber:

~~~~8<~~~~8<~~~~
(use-modules
 (fibers)
 (fibers channels)
 (ice-9 match))

;; Define a procedure to run in a fiber.
(define fiber1-proc
  (lambda (in-chan out-chan)
    ;; Look for mesages.
    (let loop ([received-proc (lambda (data) 'no-proc-received)])
      (match
          ;; Write arguments to the current output port, and return the last
          ;; argument. This will get the message received and write to current
          ;; output port an information, that the get-message procedure was
          ;; called.
          (pk 'fiber1-proc-called-get-message
              (get-message in-chan))
        ;; Match anything tagged as procedure and store it in the argument for
        ;; the named let.
        [('proc . proc)
         (loop proc)]
        ;; Match anything labeled as data and apply the stored procedure to
        ;; it. If no procedure has been received yet, use the default one.
        [('data . data)
         (put-message out-chan (received-proc data))
         ;; Loop again with the default procedure, awaiting a new procedure and
         ;; data for it.
         (loop (lambda (data) 'no-proc-received))]
        ;; Have a default reaction to anything, but the correctly tagged
        ;; messages.
        [any-other-message
         (put-message out-chan 'unrecognized-message)
         ;; Allow for unrecognized messages in between correct communication.
         (loop received-proc)])
      ;; Continue looking for messages.
      (loop received-proc))))

(run-fibers
 (lambda ()
   (let ((fiber1-in-chan (make-channel))
         (fiber1-out-chan (make-channel)))
     ;; Spawn a fiber to run fiber1-proc, which internally looks for messages on
     ;; its in-channel.
     (spawn-fiber
      (lambda ()
        (fiber1-proc fiber1-in-chan fiber1-out-chan)))
     ;; Send a mssage to the fiber.
     (put-message fiber1-in-chan
                  ;; Send some tagged data, in this case the procedure to use.
                  (cons 'proc
                        ;; A procedure, which checks all things in data for
                        ;; whether they are even numbers and builds a list of
                        ;; the answers.
                        (lambda (data)
                          (let loop ([remaining-data data])
                            (cond
                             [(null? remaining-data) '()]
                             [else
                              (cons (even? (car remaining-data))
                                    (loop (cdr remaining-data)))])))))
     ;; Then put the data on the channel.
     (put-message fiber1-in-chan
                  (cons 'data '(0 1 2 3 4 5 6 7 8 9)))
     ;; Look for the answer on the out-channel of the fiber.
     (display
      (simple-format
       #f "~a\n" (pk 'main-thread-called-peek
                     (get-message fiber1-out-chan))))

     ;; And then do it again.

     ;; Send a mssage to the fiber.
     (put-message fiber1-in-chan
                  ;; Send some tagged data, in this case the procedure to use.
                  (cons 'proc
                        ;; A procedure, which checks all things in data for
                        ;; whether they are even numbers and builds a list of
                        ;; the answers.
                        (lambda (data)
                          (let loop ([remaining-data data])
                            (cond
                             [(null? remaining-data) '()]
                             [else
                              (cons (even? (car remaining-data))
                                    (loop (cdr remaining-data)))])))))
     ;; Then put the data on the channel.
     (put-message fiber1-in-chan
                  (cons 'data '(0 1 2 3 4 5 6 7 8 9)))
     ;; Look for the answer on the out-channel of the fiber.
     (display
      (simple-format
       #f "~a\n" (pk 'main-thread-called-peek
                     (get-message fiber1-out-chan)))))))
~~~~>8~~~~>8~~~~

Is there another way or anything quite wrong in this example?

This way of communication between the fiber and the main process seems
in the style of Racket's places. Except that I can send normal
procedures / lambdas to the fiber, which is great on a single machine,
while I need to send serializable lambdas to Racket places (and I have
not gotten to do that yet).

Is there a restriction on the kind of lambdas I can send on a channel as
I did in the example above?

Regards,
Zelphir

Regards,
Zelphir



             reply	other threads:[~2020-01-05  1:30 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-01-05  1:30 Zelphir Kaltstahl [this message]
2020-01-05 12:33 ` Guile fibers return values Chris Vine
2020-01-05 12:58   ` Zelphir Kaltstahl
2020-01-05 14:28     ` Chris Vine
     [not found]     ` <20200105142358.4ad96d15a23a0b947b2d55e3@gmail.com>
2020-01-05 18:22       ` Zelphir Kaltstahl
2020-01-05 21:45         ` Chris Vine
2020-01-06 19:42           ` Zelphir Kaltstahl
2020-01-06 21:14             ` Chris Vine
2020-01-06 21:47               ` John Cowan
2020-01-06 22:45                 ` Zelphir Kaltstahl
2020-01-07  1:36                   ` John Cowan
  -- strict thread matches above, loose matches on Subject: below --
2020-01-04 22:49 Zelphir Kaltstahl
2020-01-05  2:42 ` John Cowan
2020-01-05 12:46   ` Zelphir Kaltstahl
2020-01-14 10:59 ` Amirouche Boubekki
2020-01-15  0:04   ` Zelphir Kaltstahl

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/guile/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=d7e44d35-27b5-b93f-ab83-c365c42d1b6e@posteo.de \
    --to=zelphirkaltstahl@posteo.de \
    --cc=guile-user@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).