15

私は関数型プログラミングに比較的慣れていないので、「これが関数型のやり方なのか?」という疑問に多くのエネルギーを費やしています。明らかに、再帰と反復は非常に単純であり、再帰が機能的な方法であることは明らかです。しかし、クロージャを例にとってみましょう。私は Lisp を使用してクロージャーについて学び、クロージャーが関数と環境の組み合わせであることを理解しています (状態と動作によく似ています)。例えば:

(let ((x 1))
           (defun doubleX()
              (setf x (* x 2))))

ここに、x 変数の環境内で定義された関数 doubleX があります。この関数を他の関数に渡して呼び出しても、x 変数を参照できます。関数は、変数が定義されている環境の外で呼び出された場合でも、引き続きその変数を参照できます。私が見たクロージャーの例の多くは、このようなものです。setf を使用して字句変数の値を変更します。これは私を混乱させます:

1.) setf は悪だと思った。ほとんどの場合、それは副作用を引き起こし、明らかにそれらも悪であるためです.

2.) これは本当に「機能的」ですか? グローバルな状態を維持する方法のように思え、関数型言語はステートレスだと思っていました。

クロージャを理解していないだけかもしれません。誰かが私を助けることができますか?

4

3 に答える 3

13

そうです、クロージャーを使用して状態を操作することは、純粋に機能的ではありません。Lisp を使用すると、関数型のスタイルでプログラミングできますが、強制されるわけではありません。私は実際にこのアプローチを好みます。これにより、純粋に機能的なものと、状態を変更する利便性との間の実用的なバランスを取ることができるからです。

あなたが試みるかもしれないことは、外部から機能しているように見えますが、効率のために内部の可変状態を維持するものを書くことです. これの良い例は、フィボナッチのような関数を高速化するために以前のすべての呼び出しの記録を保持するメモ化ですが、関数は常に同じ入力に対して同じ出力を返し、外部状態を変更しないため、それを考慮することができます外側から機能すること。

于 2008-11-16T06:39:28.033 に答える
8

クロージャーは貧乏人のオブジェクトです (逆もまた然りです)。

いつ閉鎖を使用するのですか?

そしてその中の私の答え。したがって、OO 以外のアプリケーションで副作用を使用して状態を管理する場合、closures-over-mutable-state は実際にこれを行う簡単な方法です。不変の代替手段は「害が少ない」ですが、言語の 99.9% は可変状態を提供しており、すべてが間違っているわけではありません。:) ミュータブルな状態は、慎重に使用すると価値がありますが、ここで見られるように、クロージャとキャプチャで使用すると特にエラーが発生しやすくなります。

ラムダ、キャプチャ、可変性について

いずれにせよ、「このような多くの例」が表示される理由は、クロージャーの動作を説明する最も一般的な方法の 1 つは、クロージャーがミュータブルをキャプチャしてミニになるこのような小さな例を示すことだと思います。 -いくつかの変更可能な状態をカプセル化するステートフル オブジェクト。これは、構造体の有効期間と副作用の意味を確実に理解するのに役立つ素晴らしい例ですが、この構造体をあらゆる場所で使用することを推奨するものではありません。

ほとんどの場合、クロージャーを使用すると、値または不変の状態を閉じるだけで、それを行っていることに「気付かない」だけです。

于 2008-11-16T06:41:41.977 に答える
3

Common Lisp と Scheme は純粋に機能的ではありません。Clojure はほとんどの場合機能的ですが、それでも純粋ではありません。Haskell は、私が知っている純粋に関数型の唯一の言語です。別の言語の名前について言及することさえできません。

真実は、純粋に関数型の環境で作業するのは非常に難しいということです (行って、Haskell を学び、そこで何かをプログラミングしてみてください)。したがって、これらすべての関数型プログラミング言語は、関数型プログラミングを許可するだけで、それを強制することはありません。関数型プログラミングは非常に強力なので、できるときもできないときも使用してください。

これからの時代に知っておくべき重要なことは、機能するものはすべて並列化できるということです。そのため、副作用を避けたり、プログラムのサブセットを可能な限り小さくしたりすることは理にかなっています。

于 2008-11-26T14:20:30.970 に答える