'How to return continuations in Racket?
I'm trying to build a good intuition behind continuations in Racket, I want to write a function that suspend it's execution and returns a continuation that when called continue the work from where it was suspended.
I kind of achieved this with this code
# lang racket
(define resume-with null) ;; called to resume a call of suspend
(define (suspend abort)
(call/cc (lambda (k)
(set! resume-with k)
(abort))))
(define (foo) ;; a function that do suspended work
(call/cc (lambda (abort)
;; abort is used to abort from foo from within suspend
;; if we do not abort the whole body will be executed
(printf "-> A\n")
(define x (suspend abort))
(printf "-> B\n")
(define y (suspend abort))
(printf "-> C\n")
(+ x y))))
But in this example I save the continuation in resume-with I want to return it instead.
I was trying something like this
(define (foo1)
(call/cc (lambda (abort)
(define x (call/cc (lambda (k)
(abort k))))
(printf "x -> ~a\n" x)
(+ x 1))))
I would like to achieve the smaller and simpler example in a single function, using only call/cc and no mutability.
This example kind of works, but it seems that the final result is not usable in another computation, I don't understand what's happening
foo.rkt> (define k (foo1)) ;; I call it and save the continuation, so far so good
foo.rkt> k ;; the continuation is a procedure
#<procedure>
foo.rkt> (k 1) ;; I call the continuation, the print shows up so we seem to be in good shape, but
x -> 1
foo.rkt> (+ 1 (k 1)) ;; if I try to apply this inside another computation I get this weird error, the 2 in the error message suggests is some what computed the `(+ x 1)` but the rest of the error I don't know how to interpret
; application: not a procedure;
; expected a procedure that can be applied to arguments
; given: 2
Solution 1:[1]
Okay I find out after trying another example, I don't fully understand why but the value of k becomes the 2 after the first call
foo.rkt> (define k (foo2))
foo.rkt> (k 1)
x -> 1
foo.rkt> k
2
foo.rkt> (+ 1 k)
3
foo.rkt>
Solution 2:[2]
You have suspended the computation inside the definition - it is "waiting" for the value of x.
(The initial "value" of k is not the value returned from (foo1) but the continuation you called k in (define x ....)
Illustration:
(define (foo1)
(call/cc (lambda (abort)
(define x {this is where the continuation returns})
(+ x 1))))
When you do (k 1), the definition continues with x bound to 1, then it prints the output, and lastly binds the value of (+ x 1) to k.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | geckos |
| Solution 2 |
