Next: Various utilities, Up: Overview
There’s no need to dive into Scheme continuations, or Guile-specific
prompts
feature, which the compose-cont macro internally relies on.
Here is the simplest example of composing with continuations, to demonstrate what’s the role of continuations here:
(define proc (compose-cont (lambda (val cont)
;; passing value to the next procedure
;; returning its result
(cont val))
(lambda (val cont)
;; returning any value, as a result of
;; the whole `proc`
'second-step-return)
(lambda (val cont)
;; not reached, as the previous procedure
;; has returned without calling `cont`
(throw 'never-mind))))
(proc 'the-value)
;; => second-step-return
The composed procedure can be made of any arity. The rule here is: if the composed procedure needs to accept N arguments, then each procedure of the composition must accept N+1 arguments, where the N+1’th argument is the continuation procedure. The continuation procedure itself accepts N arguments, and passes them as first arguments to the next procedure of the composition.
Procedures in a composition may return any amount of values - that would be the result of the whole composition. The neat thing is that each procedure is able to receive the result of the rest of the composition, do something with it or return its own result.
The order the procedures are applied is from top to bottom. What if
the last procedure of a composition calls the continuation?
In that case the built-in current-compose-end-handler is called,
which just returns #f by default.
Surely, the current-compose-end-handler can be customized, as
it is a Guile
parameter.
It needs to be a procedure of the same arity as the whole composed
procedure. That means, the end handler doesn’t receive the
continuation procedure. Here is an example of how it could be
customized:
(define proc (compose-cont
(lambda (val cont)
(cont val))
(lambda (val cont)
;; the last procedure calling the continuation
;; which applies the current-compose-end-handler
(cont val))))
(proc 'the-value)
;; => #f
;; the default end handler in action
(parameterize ((current-compose-end-handler (lambda (val)
(format #f "Unprocessed value: ~a" val))))
(proc 'the-value))
;; => "Unprocessed value: the-value"
;; the customized end handler in action
Next: Various utilities, Up: Overview