14

Clojure に慣れていない同僚に clojure コードを説明するまで、私はこれについて本当に考えたことはありませんでした。letリストではなくベクトルを使用してバインディングを宣言する理由を彼が尋ねたとき、私は彼に説明していました。私は彼に対して本当に答えがありませんでした。しかし、この言語ではリストの使用制限されています。

=> (let (x 1) x)
java.lang.IllegalArgumentException: let requires a vector for its binding (NO_SOURCE_FILE:0)

これはなぜですか?

4

5 に答える 5

26

主に読みやすさだと思います。Clojure でバインドが必要な場合は常に、ほぼ一貫してベクターが使用されます。多くの人は、バインディングのベクトルが物事の流れを良くし、バインディングと実行中のコードを識別しやすくすることに同意します。

楽しみのために:

user=> (defmacro list-let [bindings & body] `(let ~(vec bindings) ~@body))
#'user/list-let
user=> (macroexpand-1 '(list-let (x 0) (println x)))
(clojure.core/let [x 0] (println x))
user=> (list-let (x 0 y 1) (println x y))
0 1
nil
于 2010-10-04T23:57:23.453 に答える
13

これはSchemeのイディオムです。多くの Scheme 実装では、角括弧はリスト リテラルの丸括弧と同じ意味で使用できます。これらの Scheme 実装では、パラメータ リスト、引数リスト、バインディングを S 式またはデータ リストと区別するために角括弧がよく使用されます。

Clojure では、括弧と括弧の意味は異なりますが、バインド宣言では同じように使用されます。

于 2010-10-05T00:21:22.213 に答える
11

Clojure は一貫性を維持するために非常に努力しています。letfnwith-openなどでリスト フォームを使用できなかったという技術的な理由はありませんmy-let。ただし、目に見えて目立つことは別として、ベクトルはフォーム全体で一貫して使用され、「ここにいくつかのバインディングがある」ことを意味します。独自のコードでその理想を維持するように努力する必要があります。

于 2010-10-04T23:59:10.423 に答える
1

私の推測では、それはコンベンションだと思います

fn使った、defn使った、loop使った。

いくつかのパラメーターを持つコードのブロックに似ているすべてのもののようです。より具体的には、角括弧はそれらのパラメーターをマークするためのものです

ifまたはのように、コード ブロックの他の形式は使用しませんdo。パラメータはありません

于 2010-10-05T06:20:50.093 に答える
1

これについて考える別の方法は、let単にラムダから派生したものであるということです。これら 2 つの式は同等です。

((fn [y] (+ y 42)) 10)
(let [y 10] (+ 42 y))

したがって、学術的または教育的なポイントletとして、ベクトルだけでなくリストを使用する独自の非常に初歩的なバージョンを作成することもできます。

(defmacro my-let [x body]
  (list (list `fn[(first x)]
              `~body)
        (last x)))

(my-let (z 42) (* z z))

これを行う実際的な理由はありませんが。

于 2011-05-30T22:24:27.027 に答える