It might be useful to add something like a condition that can hold arbitrary values. I'll call this a promise for the moment and it might expose something like this:
- `make-promise`
- `promise?`
- `resolved?`
- `resolve`
- `promise-wait` (calling this promise-wait to distinguish from the condition wait)
An example where this is useful would be to signal completion of a request with return value.
In some code bases (e.g. shepherd) a reply channel is used for something similar. A request is posted to a pool of worker along with a newly created channel that is used to send the return value of the request back to the requestee. Here an example from (shepherd services):
(define (service-name-count)
"Return the number of currently-registered service names."
(let ((reply (make-channel)))
(put-message (current-registry-channel)
`(service-name-count ,reply))
(get-message* reply 5 'no-reply)))
(get-message* is like get-message but also does timeout handling).
Using promises this might be (omitting the timeout logic):
(define (service-name-count)
"Return the number of currently-registered service names."
(let ((promise (make-promise)))
(put-message (current-registry-channel)
`(service-name-count ,promise))
(wait-promise promise)))
Code looks very similar, but there seem to be some differences:
- Multicast: A promise can have multiple waiters, whereas the reply message in the channel is only received by a single waiter.
- A promise can be re-used for caching the response to a request.
From what I understand this can be implemented using make-base-operation. Still, this might be useful enough to include in fibers itself?
Naming
The name promise is used in the manual as an example for monadic style concurrency. The promise proposed here does not force the usage of monads.
Guile has promises for delayed execution (https://www.gnu.org/software/guile/manual/html_node/Delayed-Evaluation.html).
Maybe calling it something else would make sense.
It might be useful to add something like a condition that can hold arbitrary values. I'll call this a promise for the moment and it might expose something like this:
An example where this is useful would be to signal completion of a request with return value.
In some code bases (e.g. shepherd) a reply channel is used for something similar. A request is posted to a pool of worker along with a newly created channel that is used to send the return value of the request back to the requestee. Here an example from
(shepherd services):(
get-message*is likeget-messagebut also does timeout handling).Using promises this might be (omitting the timeout logic):
Code looks very similar, but there seem to be some differences:
From what I understand this can be implemented using
make-base-operation. Still, this might be useful enough to include in fibers itself?Naming
The name
promiseis used in the manual as an example for monadic style concurrency. The promise proposed here does not force the usage of monads.Guile has promises for delayed execution (https://www.gnu.org/software/guile/manual/html_node/Delayed-Evaluation.html).
Maybe calling it something else would make sense.