Reputation: 583
Currently, I am studying Scheme language. I'm confused in how to use call-with-current-continuation.(call/cc) For a better understanding it, I wrote an example code for non-local exits. But it doesn't work properly.
Does anyone know why? Any help would be appreciated. Thanks in advance
[example code]
(define (product ls)
(call/cc
(lambda (return)
(cond
((null? ls ) =>
(begin
(display "list end")
(newline)
1)) ;; NG
;;(return 1)) ;; OK
((not (number? (car ls))) =>
(begin
(display "not number")
(newline)
(return 0)))
(else =>
(begin
(display (car ls))
(newline)
(* (car ls) (product (cdr ls)))))))))
[repl output]
gosh> (product '(1 2 a 3)) ; it works as I expected.
==> 1
==> 2
==> not number
==> 0 (return)
gosh> (product '(1 2 3)) ;; it doesn't work as I expected. I expect 6 as return value.
==> 1
==> 2
==> 3
==> list end
*** ERROR: invalid application: (1 #t)
Upvotes: 0
Views: 230
Reputation: 17223
There are a couple of things going on here.
First and foremost, it looks like the =>
you're inserting into your cond clauses is causing the problem. In Scheme, the =>
has a special meaning... which you don't want. Take them out, and I think you'll see that your code behaves as you expect.
BUT: your use of call/cc is not actually causing a non-local exit, as I believe you're intending. That is, my guess is that you want the zero to bypass all of the waiting multiplies, and it's not. To see this, change the 0 into something that can't be multiplied---say, the string "not a number"
--and watch it fail.
This is because you're re-binding return
on each call to the function. I think you probably actually want something like this:
(define (product ls)
(call/cc
(lambda (return)
(letrec ([loop
(lambda (ls)
(cond
((null? ls )
(begin
(display "list end")
(newline)
1)) ;; NG
;;(return 1)) ;; OK
((not (number? (car ls)))
(begin
(display "not number")
(newline)
(return "not a number")))
(else
(begin
(display (car ls))
(newline)
(* (car ls) (loop (cdr ls)))))))])
(loop ls)))))
(product '(1 2 a 3))
... which produces this output:
1
2
not number
"not a number"
>
Upvotes: 4