Search code examples
schemecontinuations

how to pass data to call/cc?


I try to implement function that takes list of atoms and returns only sub part of given list. Sub part is everything after particular token. I try to use call-with-current-continuation for that purpose.

Here is my approach:

(define rest 
  (lambda (a lat)
    (call-with-current-continuation 
      (lambda (res)
        (letrec ((r (lambda (l)
                      (cond 
                        ((null? l) ())
                        ((eq? (car l) a) (res (cdr l)))
                        (else (r (cdr l)))))))
        (r lat))))))

as you can see I try to pass data to continuation ((eq? (car l) a) (res (cdr l))) but I always get back () using this approach. But if I hard-coded values like this ((eq? (car l) a) (apple tea) it works fine.

I am really stuck and I need help.

EDIT: I've found solution instead of (res (cdr l)) I have to pass (res (r (cdr l)))

Also real mistake was not with how I call continuation, but with (else (r (cdr l))))))) I should write as:

(else (cons (car l)
      (r (cdr l))))))))

Solution

  • Your code works fine in MIT-Scheme 9.2:

    MIT/GNU Scheme running under OS X
    Type `^C' (control-C) followed by `H' to obtain information about interrupts.
    
    Copyright (C) 2014 Massachusetts Institute of Technology
    This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
    PURPOSE.
    
    Image saved on Wednesday February 24, 2016 at 8:07:52 PM
      Release 9.2 || Microcode 15.3 || Runtime 15.7 || SF 4.41 || LIAR/C 4.118 || Edwin 3.116
    
    1 ]=> (define rest
      (lambda (a lat)
        (call-with-current-continuation
          (lambda (res)
            (letrec ((r (lambda (l)
                          (cond
                            ((null? l) ())
                            ((eq? (car l) a) (res (cdr l)))
                            (else (r (cdr l)))))))
            (r lat))))))
    
    ;Value: rest
    
    1 ]=> (rest 'c '(a b c d))
    
    ;Value 2: (d)
    
    1 ]=> (rest 'c '(a b c d e))
    
    ;Value 3: (d e)
    
    1 ]=> (rest 'c ())
    
    ;Value: ()
    

    My best guess is that you're working with objects where eq? is the inappropriate comparison procedure.

    FWIW, here's a shorter implementation:

    (define (rest a lat)
      (call-with-current-continuation
       (lambda (res)
         (let r ((l lat))
           (if (null? l)
               '()
               ((if (eq? (car l) a) res r) (cdr l)))))))