0

Clojure でこのロジックを実装しようとしています (ほんの一例):

a = 1 + 5
b = a + 3
c = a + 4
d = c + a
return f(a, b, c, d) 

これまでに書いた中で最高のコードは次のようになります。

(let [a (+ 1 5) b (+ a 3) c (+ a 4) d (+ c a)] (f a b c d))

私の実際のケースでは、これらの「追加」操作ははるかに複雑で、数行のコードが必要な場合があるため、これはかなり面倒に見えます。(Lisp スタイル) のように書きたいと思います。

(set a (+ 1 5))
(set b (+ a 3))
(set c (+ a 4))
(set d (+ c a))
(f a b c d)

Clojureでそれは可能ですか?

4

3 に答える 3

4

いいえ、それは意図による(set ...)ものです。あなたが説明している呼び出しは、Java や C# などの言語のように可変状態の使用を暗示しているからです。これは、より健全な方法で状態を管理するために、Clojure が積極的に回避しているものであり、並行性において非常に重要になります。詳細については、Clojure の Web サイトを参照してください。

さらに、letフォームは面倒ではなく、便利なスコーピング ツールです。例aでは、 、bcおよびdlet はすべてローカルです。これが意味することは、命令ポインターが let の外に出ると、それらのバインディングはすべて忘れられるということです。

対照的に、(set...)例が機能したとしても、これらの一時的な名前のすべてで名前空間を汚染したことになります。

于 2013-05-24T20:26:10.280 に答える
4

実際、Clojure で可能な最善の解決策をほとんど見つけました。

(let [a (+ 1 5)
      b (+ a 3)
      c (+ a 4)
      d (+ c a)]
  (f a b c d))

Clojure コードは関数型言語であるため、命令型スタイルで書くことはできません。Clojure のすべての変数は不変であるため、定義を自由に使用することもできません。したがって、定義されたものは変更できません。したがって、いくつかの変数を一時的にバインドしたい場合は、 を使用する必要がありますlet

于 2013-05-24T20:39:10.450 に答える
3

Clojureのset 関数は、変数の値を変更するのではなく、別のコレクション コンテナーから set データ型を作成します。ただし、次のことを行うことができます。

(def a (+ 1 5))
(def b (+ a 3))
(def c (+ a 4))
(def d (+ c a))
(f a b c d)

alet ステートメントを使用すると、同じことを実行できますが、トップレベルの名前空間を、bc、およびd値で「汚染」することはできません。aただし、 、bc、およびに固執して参照できるようにしたい場合はd、 aでうまくいきますdef

于 2013-05-24T20:40:23.400 に答える