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
next 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).