The scheme programming language--continuation

開始學習大名鼎鼎的continuation,腦殼轉起來吧.express

continuation is just a procedure that accepts one single variable.app

call/cc catch the current continuation------current continuation means what the system are going to do with the result of (call/cc expression)學習

In example, (call/cc (lambda(k).....))this continuation is stored in k. whenever k is invoked. We return to that situationthis

(call/cc
    (lambda(k)
        (* 5 (k 4))))  => 4 (+ 2 (call/cc (lambda(k) (* 5 (k 4))))) => 6

A more useful examplespa

(define product
  (lambda(ls)
    (call/cc
      (lambda(break)
        (let f ([ls ls]) (cond [(null? ls) 0] [(= (car ls) 0) (break 0)] [else (* (car ls) (f (cdr ls))]))))))

A very subtle examplerest

(let ([x (call/cc (lambda(k) k))])
  (x (lambda(ignore) "hey!")))

the behavior of this piece needs careful understanding.code

The value binded to x is likeblog

(lambda(var)
  (let ([x var]) (x (lambda(ignore) "hey!"))))

when this procedure applys to (lambda(ignore) "hey!")), result in printing "hey"it

 Another subtle oneio

(((call/cc (lambda (k) k))  (lambda (x) x))  "HEY!") => "HEY!"

Continuation could be saved in top-level env. And can be invoke whenever necessary

(define retry #f)

(define factorial
  (lambda (x)
    (if (= x 0) (call/cc (lambda (k) (set! retry k) 1)) (* x (factorial (- x 1)))))) (factorial 4) => 24 (retry 1) => 24 (retry 5) => 120

Continuation is a whole procedure during a process about what to do with a single value. In this example this procedure include all the operation on the base value till the procedure returns.

The last example is fairly interesting and useful. A very cool application to do a ligh-weight multitasking job

(define lwp-list '())
(define lwp
  (lambda(thunk)
    (set!  lwp-list (append lwp-list (list thunk)))))
(define start
  (lambda()
    (let ([p (car lwp-list)]) (set! lwp-list (cdr lwp-list)) (p)))) (define pause (lambda() (call/cc (lambda(k) (lwp (lambda() (k #f)) (start)))))
(lwp (lambda () (let f () (pause) (display "b") (f)))))
(lwp (lambda () (let f () (pause) (display "i") (f)))))
(lwp (lambda () (let f () (pause) (display "t") (f)))))
(lwp (lambda () (let f () (pause) (display "c") (f)))))
(lwp (lambda () (let f () (pause) (display "h") (f)))))
(lwp (lambda () (let f () (pause) (display "!") (f)))))
(lwp (lambda () (let f () (pause) (newline) (f)))))
(start) => where amazing happens

Analyse the complex behavior step by step

(lwp (lambda () (let f () (pause) (display "b") (f))))))

At first, put these thunks on the the excution list one by one

Then 」start". pop out the first (thunk) and execute it. It is a recursive procedure. (pause) is invoked soon. (pause) append the bomb to the back end. Then continue read from the execute list.

When come to the bomb. The continuation is invoked. The continuation should 1. print "b" 2.invoke f again. That's it! As literally defined.

f->(pause)->||->print "b"->f->(pause)->||->.......

SO COOL!!

相關文章
相關標籤/搜索