2013-04-22 4 views
10

私は反時計を使ってREPLを実行していますが、私はこれもLeiningenに気づきました。なぜVarを再定義することができますか(FP値が不変であることを前提とします)?

私はvarを2回定義するためにdefを呼び出すことができます。たとえば、

=> (def a 1) 
#'fractal.core/a 
=> a 
1 
=> (def a 2) 
#'fractal.core/a 
=> a 
2 

ClojureはFPであり、FPオブジェクトでは不変であると考えられます。私はこれをどのような意味で行うことができれば、不変ですか?

ありがとうございます。

+1

厳密に言えば、Varの値は変更されていないので、* rebinding *(命令型言語で考える*シャドーイング)と呼ばれています。 –

+0

@ om-nom-nomこれはシャドーイングのようなものではありません。必要に応じて再バインドを呼び出すことができますが、これとvarの値を変更することには特別な違いはありません。はい、varはまだ同じ値のセルを保持していますが、そのセルの内容は変更されています。これは通常は値を変更することによって意味されます。 – amalloy

答えて

12

varsの全ポイントは、それらがリバウンドできることです。したがって、名前はvar - > variableです。 docsから

Clojureのは、変化値に永続的な参照を維持するために臨時の必要性を認識して実用的な言語です。 ... Varsは、スレッド単位で動的にリバウンドできる(変更可能な)格納場所を参照するメカニズムを提供します。

varを再バインドすることで、不変の値は変更されません。

不変の値に名前を与え、後でその名前に別の不変の値を与えると考えてください。 FPオブジェクト内の

1

は不変であるはずです。

これは間違っています。

純粋な関数プログラミングでは変数が不変の値である必要があります。 しかし、Clojureは純粋に機能的な言語ではなく、どこにも拡張されていない副作用を許容します。

機能的言語の大半は、言語自体の突然変異などの副作用の発生を追跡しないため、この点では不十分です。

+1

FPでは、オブジェクトを不変にして、可能な限り純粋な関数を使うべきであるという意味では間違っていません。 Clojureのような不純なFP言語で状態を変えることができるという事実は、これが良い習慣であることを意味するものではありません。 – mikera

+0

私はそれがOPの "想定される" –

3

re-def(つまり、一時バインド/スレッドローカル再バインドとは対照的にルートバインディングを設定する)は、ほとんどが開発のためのツールであることを意図しています。標準のグローバル関数と値(def/defnで定義されたもの)はvarベースなので、編集しているクローージャプログラムを再起動しなくてもそれらを再定義することができます。 VARSはない値であることを

注意、それらが明示的に値/機能へ可変言及することを意図しています。

関連する問題