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