Hello,
I have been playing with implementing algebraic effects using delimited
control, and Dorai Sitaram’s `fcontrol` and `%` operators are a natural fit.
For example, it’s straightforward to implement McCarthy’s `amb` operator using
them:
(define amb-tag (make-continuation-prompt-tag 'amb))
; -> none/c
(define (fail) (fcontrol 'fail #:tag amb-tag))
; -> boolean?
(define (choice) (fcontrol 'choice #:tag amb-tag))
(define-syntax amb
(syntax-rules ()
[(_) (fail)]
[(_ e) e]
[(_ e0 e ...) (if (choice) e0 (amb e ...))]))
The whole point of algebraic effect handlers is that we can interpret the same
effect multiple ways, and `%` makes that easy. For example, we can write one
`amb` handler that returns only the first result and another one that returns
all results:
(define (run-amb/first proc)
(% (proc)
(λ (op k)
(match op
['fail #f]
['choice (or (run-amb/first (thunk (k #t)))
(run-amb/first (thunk (k #f))))]))
#:tag amb-tag))
(define (run-amb/all proc)
(let go ([proc (thunk (list (proc)))])
(% (proc)
(λ (op k)
(match op
['fail '()]
['choice (append (go (thunk (k #t)))
(go (thunk (k #f))))]))
#:tag amb-tag)))
This mostly works nicely, but the way it interacts with `dynamic-wind` leaves
something to be desired:
> (run-amb/first
(thunk
(dynamic-wind
(thunk (displayln "--> in"))
(thunk (+ (amb 1 2) (amb 3 4)))
(thunk (displayln "<-- out")))))
--> in
<-- out
--> in
<-- out
--> in
<-- out
4
This is a little bit silly, since control is jumping out of the extent of
`dynamic-wind` only to immediately re-enter it. If `dynamic-wind` is being used
to guard access to a lock or pooled resource, we probably don’t want it to be
released and reacquired on every call to `amb`.
However, I’m not sure how I can rearrange things to make that possible. I can’t
just store the current `amb` handler in a parameter/continuation mark because
it really does need to extend the continuation of the whole computation. Is
there any way to do that with Racket’s continuation machinery, or would I need
to use mutable state to imperatively extend a list of continuations maintained
by the current handler? Also, is this kind of thing discussed anywhere in the
literature?
Thanks,
Alexis
--
You received this message because you are subscribed to the Google Groups
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/racket-users/9EEF26EF-C60C-49B7-92D4-27648C111213%40gmail.com.