を使用せずにどのletrec
ように実装できますset!
か?
set!
これは命令型プログラミング構造であり、それを使用すると関数型プログラミングの利点が失われるように私には思えます。
を使用せずにどのletrec
ように実装できますset!
か?
set!
これは命令型プログラミング構造であり、それを使用すると関数型プログラミングの利点が失われるように私には思えます。
通常、コンテンツのコピーをお願いしていることは承知していますが、あなたの質問に対する簡単な答えはありません。http://www.cs.indiana.edu/~dyb/pubs/fixing-letrec.pdf
いいえ。関数機能が舞台裏で命令型コードを使用して実装されているからといって、その機能が命令型になるわけではありません。私たちのコンピューティング マシンはすべて不可欠です。そのため、ある時点ですべての機能コードを命令型コードに変換して実装する必要があります。
ここで理解しておくべき重要なことは、関数型プログラミングは実装ではなくインターフェースに関係するということです。コード自体が副作用を観察できない場合、そのコードは機能しています。つまり、同じ変数の同じバインディングの値を複数回チェックすると、同じ値が得られます。set!
の場合、ここにちょっとした落とし穴があります。 のいずれかのバインディングの評価によって別のバインディングが逆参照されるletrec
場合、結果は未定義です。letrec
したがって、このコードの結果は未定義です。
(letrec ((foo bar)
(bar 7))
(cons foo bar))
foo
letrec 本体の の値は定義されていません。一方、次の結果は次のように定義されます。
(letrec ((foo (lambda () bar))
(bar 7))
(cons (foo) bar))
これは、lambda
キャプチャの評価が bar への参照を評価するためですが、実際の値は本体でクロージャーが実行されるまで検索されないためです。