Impure language features
I/Oや,set!
等の変数への破壊的代入が純関数的でないのは明らかだ.しかしそれらを一つも使わなくとも継続を使ったSchemeプログラムが純関数的でないという例があったような,なかったような... 見かけたのは確か
(define (foo) ... (call/cc (lambda (k) ...)) ...) ; is this impure function? (define (bar p q) ...) (bar (foo) (foo)) (define (bar-1 p) (bar p p)) (bar-1 (foo))
みたいな例だったように覚えているが,set!
を使わずにどうにかなるものか? (いや異なる2箇所での継続が異なるのは自明なんだが,分かりやすい例が書けるかってこと)
それと例外も純関数的でないのだっけ? まぁかなり外側へ脱出されてしまったら関数が値を「返した」と言えなくなるとは思うが... I/Oや破壊的代入なしでも何がどこまでまずいのかは,適当な教科書がないと分からないな.
int foo(int x) throws RuntimeException { if (x == 0) throw new RuntimeException("foo found that x == 0"); return 100; }
これを定数100と同一視できないのは明らかだが,えーと,外側に確実に(?)存在するcatch
まで含めて解析すれば問題なくない? (CPS変換でコンパイルするなら自明だよね?)それともこれは単純過ぎで,もう少し複雑な例だと破綻が明らかになるのだっけか?