Created
August 31, 2013 12:37
-
-
Save knjname/6397936 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ;;; call/cc を理解しよう! | |
| ;; 一見すると普通にかけぬけている | |
| (call/cc (lambda (c) "Just invoke")) ; "Just invoke" | |
| (define boundval (call/cc (lambda (c) "Just invoke"))) | |
| boundval ; "Just invoke | |
| ;; だが… | |
| (define frozenval ()) | |
| (begin | |
| (print "before call/cc...") | |
| (call/cc (lambda (c) (set! frozenval c))) | |
| (print "after call/cc...")) | |
| ;; としてから… | |
| (frozenval) ; "after call/cc" | |
| (frozenval) ; "after call/cc" | |
| (begin | |
| (frozenval) | |
| (print "after frozenval")) ; 何も表示しない | |
| ;; 他の例 | |
| (define pokemonGetDaze ()) | |
| (string-append | |
| (call/cc | |
| (lambda (c) | |
| (set! pokemonGetDaze c) ; とりあえず現在位置を保存しとく | |
| "Pikachu")) | |
| " Get daze!") ; Pikachu Get daze! | |
| ;; 上のコードの部分のcall/ccにあたる部分の結果を"Hitokage"に置き換える感じ | |
| (pokemonGetDaze "Hitokage") ; Hitokage Get daze! | |
| (string-append (pokemonGetDaze "Fushigidane") | |
| "!????") ; もちろんstring-appendは実行されない | |
| ;; レキシカルかな? | |
| (define accumlator ()) | |
| (let ((cnt 0)) | |
| (call/cc (lambda (c) (set! accumlator c))) | |
| (set! cnt (+ cnt 1))) ; 1 | |
| (accumlator) ; 2 | |
| (accumlator) ; 3 レキシカルですね。 | |
| ;; 繰り返し | |
| ;; GOTO みたいなもんですわ | |
| (let ((i 10) | |
| (frozen ())) | |
| (call/cc (cut set! frozen <>)) | |
| (cond ((= i 0) | |
| (print "Done!")) | |
| (else | |
| (print i) | |
| (set! i (- i 1)) | |
| (frozen)))) ; 10 9 ... 1 Done! | |
| ;; call/ccだけど呼び戻してもらう | |
| (define reflector ()) | |
| (let ((startFromHere | |
| (call/cc (lambda (c) | |
| (set! reflector c) | |
| (lambda ()))))) | |
| (print "Reflect!") | |
| (startFromHere) | |
| (print "After reflection")) | |
| (let ((called #f) | |
| (frozen (call/cc (lambda (c) c)))) | |
| (cond | |
| ((not called) | |
| (set! called #t) | |
| (print "Call reflect") | |
| (reflector frozen)) | |
| (else | |
| (print "Reversed!") | |
| "Yeah"))) | |
| ;; Call reflect -> Reflect! -> Reversed! -> "Yeah" | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment