Reputation: 621
I'm completly lost with the call continuation in Scheme. Can someone help me with this example ?
#lang scheme
(define a-continuation '*dummy-value*)
(define (myfunction what? l)
(cond ((null? l) 0)
((what? (car l))
(+ 1 (call/cc (lambda (f)
(set! a-continuation f)
(myfunction what? (cdr l))))))
(else (myfunction what? (cdr l)))))
(myfunction number? '(18 16 2015 2))
(a-continuation 2014)
I understand the first result (3) but I don't understand the result 2017.
Upvotes: 2
Views: 250
Reputation: 1189
This can be really confusing. But maybe a simpler example can help (taken from here:
(define return #f)
(+ 1 (call/cc
(lambda (cont)
(set! return cont)
1))) ;; <--- (+ 1 1)
> 2
(return 22)
> 23
When you evaluate the (+ 1 (call/cc ...))
You get 2
. Because the return value of the (call/cc ...)
part is 1
. Now we have set return
to be cont
in call/cc
. In this scope, cont
is a procedure that takes 1 argument. And when called, it will evaluate to that argument. Here is the interesting part, when you evaluate the procedure, evaluation is resumed at the spot of the call/cc
. So when you call (return 22)
It will evaluate to 22
up there in (+ 1 (call/cc ...))
, resulting in 23
.
Hope this is clear. In the page I linked to there are other more complex examples.
Upvotes: 0
Reputation: 48745
When calling (myfunction number? '(18 16 2015 2))
you will have a-continuation
set to the continuation of each iteration and the last one when it has processed 18
, 16
, and 2015
and processing 2
.
When calling (a-continuation 2014)
you go back to the processing of 2
but instead of recursing you tell the answer to the continuation is 2014
, thus you get (+ 1 (+ 1 (+ 1 (+ 1 2014)))) ; ==> 2018
Upvotes: 0
Reputation: 66371
I get this
> (myfunction number? '(18 16 2015 2))
4
> (a-continuation 2014)
2018
but this "to the best of my knowledge" explanation should still work.
(I expected the continuation to add 1 to its argument. I was wrong, so I'm trying to explain this to myself, too.)
If you remove the continuation parts, myfunction
is a function that counts for how many elements the predicate what?
holds.
Playing around a little in the REPL/interaction window,
> (myfunction number? '(1))
1
> (a-continuation 1)
2
> (a-continuation 2)
3
> (myfunction number? '(1 2 3 4 5 6 7 8 9 10))
10
> (a-continuation 1)
11
> (a-continuation 2)
12
> (a-continuation 3)
13
> (myfunction even? '(1 2 3 4 5 6 7 8 9 10))
5
> (a-continuation 1)
6
> (a-continuation 2)
7
> (a-continuation 3)
8
One can suspect from this pattern that the continuation adds to its argument the number of elements that myfunction
found.
This is my explanation of why this is so:
If you view each call/cc
as a "hole" that you can fill in later by calling the captured continuation, the first one is
(+ 1 <hole>)
the second
(+ 1 (+ 1 <hole>))
and so on, creating a "chain" of additions, one for each time the predicate holds.
(I.e. capturing the entire recursion that's "waiting" for the continuation to continue, not just the innermost call.)
So
(myfunction number? '(18 16 2015 2))
creates something that looks like
(+ 1 (+ 1 (+ 1 (+ 1 <hole>))))
and when you call the continuation,
(a-continuation 2014)
you evaluate
(+ 1 (+ 1 (+ 1 (+ 1 2014))))
which is, of course, 2018.
(Disclaimer: This may be completely wrong.)
Upvotes: 3