Skip to content

Instantly share code, notes, and snippets.

@knjname
Created August 31, 2013 12:37
Show Gist options
  • Select an option

  • Save knjname/6397936 to your computer and use it in GitHub Desktop.

Select an option

Save knjname/6397936 to your computer and use it in GitHub Desktop.
;;; 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