3

それ以外の

(let [x 1] (my-expression))

私は使用しようとしています:

(let (vector x 1) (my-expression))

理由は聞かないでください。私は通常のブラケットの方が好きです。しかし、Clojure は次のように述べています。

let requires a vector for its binding in ...

どうしたの?

4

4 に答える 4

7

let特殊形式バインディング形式は、ベクトルに評価される式だけでなく、ベクトルリテラルである必要があります。

なんで?大まかに言うと、式を評価する前にコンパイルする必要があります。コンパイル時(vector x 1)に評価されるvectorことはなく、単なるリストになります。実際、それが評価される場合、の引数vectorが評価され、意味xを解決する必要があります。しかし、あなたはx解決されたくはありません、あなたはそれを束縛したいのです。

于 2013-02-19T21:33:29.920 に答える
3

let(コンパイル時に)バインディング用のベクトルが必要なため、その場所にベクトル関数呼び出しを配置し​​ようとしても機能しません(実行時にのみベクトルが生成されるため)。

ただし、少しのmacro-fuを使用して独自のletを作成できます。

(defmacro mylet [bindings & exprs]
  `(let ~(vec bindings) ~@exprs))

(mylet (x 1) (inc x))
=> 2
于 2013-02-20T03:16:35.060 に答える
3

マクロのソースを見てくださいlet

(defmacro let
  "binding => binding-form init-expr

  Evaluates the exprs in a lexical context in which the symbols in
  the binding-forms are bound to their respective init-exprs or parts
  therein."
  {:added "1.0", :special-form true, :forms '[(let [bindings*] exprs*)]}
  [bindings & body]
  (assert-args let
     (vector? bindings) "a vector for its binding"
     (even? (count bindings)) "an even number of forms in binding vector")
  `(let* ~(destructure bindings) ~@body))

bindingsマクロが を介して正しい引数が与えられたことを確認しようとすると、引数が評価されないことに気付くでしょうassert-args

clojure が を評価する時点で(vector? bindings)、最初の要素としてa を含み、その後にその引数が続くbindingsフォーム ( ) であるため、その時点では a ではありません。listfnvector

于 2013-02-19T21:39:07.493 に答える
0

たとえば、このコードは機能します。

(eval `(let ~(vector 'a 1) (println ~'a)))

これは、ベクトルの代わりにリストを受け入れる独自のletマクロを作成できることを意味します。これはClojureの全体的な経験にとってかなり悪いことであり、私はそれをお勧めしません。

于 2013-02-19T21:57:28.873 に答える