Reputation: 935
I'm working in a Scheme-like language which completely lacks any forms of mutable cells (such as Scheme's set!
or OCaml's ref
). Ideally, I want to implement generators so that the "result" of the generator is just it returning normally. This means generators and iterators would be typed something like (pseudo-code):
Generator (receive : Type) (yield : Type) (return : Type) = Fix(fun (nextStep : Type) =>
(receive, (yield, nextStep) -> ⊥) -> return
)
Iterator (yield : Type) = Generator ⊤ yield ⊤
In Scheme, I can implement such an iterator that yields numbers 0 through 10:
(define (seqTo10 y)
(define (go i yl)
(if (< i 10)
(go (+ i 1) (call/cc (lambda (cont) (yl (list i cont)))))))
(go 0 y))
The problem becomes consuming the results of these iterators without set!
. If I try something like:
(define (seqSum seq)
(call/cc (lambda (return)
(define (sum t n)
(apply
(lambda (i x) (sum (+ t i) x))
(call/cc (lambda (k)
(n k)
(return t)))))
(sum 0 seq))))
Because in this situation, n
is a continuation (representing the next step of the iterator), when go
exits normally, it returns to the first frame outside a looped call/cc
: the frame where t
is 0
. This causes (seqSum seqTo10)
to be 0
, rather than my desired 45
.
My question is: can I keep this behavior for Generator
s and Iterator
s (specifically where normal termination of the generator/iterator specifies the terminal value), but consume and accumulate their results without set!
?
Upvotes: 0
Views: 94