2

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.

Rptx
  • 1,159
  • 1
  • 12
  • 17
Jean
  • 601
  • 1
  • 10
  • 26

3 Answers3

3

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.)

molbdnilo
  • 64,751
  • 3
  • 43
  • 82
  • You are right @molbdnilo. In call/cc, `f` is a procedure which takes one argument. And that argument is the return value. When you call the procedure you (bound to `a-continuation`) it will return it's argument `2014` in your example. And this will be evaluated above. The only thing you are forgetting is the `0` `myfunction` returns when called on the `null?` list. – Rptx Jan 28 '15 at 15:13
0

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.

Nathan Davis
  • 5,636
  • 27
  • 39
Rptx
  • 1,159
  • 1
  • 12
  • 17
  • Thanks. I understand your example, but I don't understand mine. I'd think that I shoud have (+ 1 ( 2014), so 2015 but I get 2018. – Jean Jan 28 '15 at 15:54
  • the execution of `myfunction` continues. Every loop you set `a-continuation` tu a new value. So for each recursion you get `(+ 1 ...)` and the last recursion gets 0. So you add 2014 to a 1 for each element for which `what?` is true. – Rptx Jan 28 '15 at 18:34
0

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

Sylwester
  • 47,942
  • 4
  • 47
  • 79