unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
* Re: Guile fibers return values
@ 2020-01-05  1:30 Zelphir Kaltstahl
  2020-01-05 12:33 ` Chris Vine
  0 siblings, 1 reply; 16+ messages in thread
From: Zelphir Kaltstahl @ 2020-01-05  1:30 UTC (permalink / raw)
  To: guile-user

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



^ permalink raw reply	[flat|nested] 16+ messages in thread
* Guile fibers return values
@ 2020-01-04 22:49 Zelphir Kaltstahl
  2020-01-05  2:42 ` John Cowan
  2020-01-14 10:59 ` Amirouche Boubekki
  0 siblings, 2 replies; 16+ messages in thread
From: Zelphir Kaltstahl @ 2020-01-04 22:49 UTC (permalink / raw)
  To: guile-user

Hello Guile users!

I have questions regarding the usage of the fibers library. It seems,
that I cannot find any way to get a computation result back from a
fiber. I also cannot find anything about how to get a value back from a
fiber, except for channels. The examples include one example using the
procedure `make-channel`, to create one channel for a client to send to
a server and one channel to use for the server to send messages to the
client.

Are channels the only way to get a computation result back from a fiber?

Should I be creating channels, which the spawned fiber then can use on
its own, to asynchronously give me a result?

This is an aside of my actual project currently. I want to parallelize
some algorithm and want to make use of fibers for that, but in order to
do that, I must understand how to run multiple fibers and get their
results back.

Can you give me an example, where fibers are used to split up a
computation heavy task so that it is sped up, because of running on
multiple cores?

Regards,

Zelphir




^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2020-01-15  0:04 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-05  1:30 Guile fibers return values Zelphir Kaltstahl
2020-01-05 12:33 ` 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

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