1

約1週間前、私はこのスレッドで質問をしました。Clojureの「let」リストをループしますか? 私は良い答えを受け取りました、しかし、かなり紛らわしい質問が私の頭の中で起こりました:

答えの一部は次のとおりです。

(defmacro anaphoric-let [alternating-symbols-and-values & body]
    `(let [~@alternating-symbols-and-values
           names# (quote ~(flatten (partition 1 2 alternating-symbols-and-values)))
           values#  ~(vec (flatten (partition 1 2 alternating-symbols-and-values)))
           ~'locals (zipmap names# values#)]
        ~@body))


Input: 
(anaphoric-let [a 1 b 2 c 3 d 4 e "cat"] 
     (dorun (for [x (vals locals)] 
          (if (number? x) (println "roar")))))

この場合の(dorun)ステートメントは、マクロパラメーターの本体ですよね?だから、体を「コピー&ペースト」するだけだという印象を受けました。したがって、代わりに:

~@body

以下のようになり、コピーされたテキストとそのすべての引用が解除されます。

~@(dorun (for [x (vals locals)] 
       (if (number? x) (println "roar"))))

何が起こっているのかをすべて解釈しようとして、今説明したとおりのことを試みました。〜@ bodyを使用する代わりに、「実際のコード」をそこに配置しようとしました。

その場合、次のようになります。

(defmacro anaphoric-let [alternating-symbols-and-values & body]
     `(let [~@alternating-symbols-and-values
          names# (quote ~(flatten (partition 1 2 alternating-symbols-and-values)))
          values#  ~(vec (flatten (partition 1 2 alternating-symbols-and-values)))
          ~'locals (zipmap names# values#)]
       ~@(dorun (for [x (vals locals)] 
             if (number? x) (println "roar"))))))

そして、これは機能せず、「シンボルを解決できない:このコンテキストではローカル」であると不平を言います。私はこれでとても初心者なので、実験と分析を試みましたが、賢くなりませんでした。私がそれをすべて理解したと思うたびに、いつもこの小さな「しかし...」がやって来て、すべてを押しつぶします!

邪悪な〜@ bodyを除いて、残りの例については十分に理解しているように感じます...私の個人的な推測では、これらの小さな風変わりな記号をすべて組み合わせる方法について完全に理解していないので、私はおそらくそれらのある種の組み合わせを見逃しています...

4

1 に答える 1

1

バッククォートされた式内の〜@ exprは、exprを評価し、それを周囲の式にスプライスすることを意味します。

(dorun ...)式を評価したくないので、代わりにコピーして貼り付けることができます。

(defmacro anaphoric-let [alternating-symbols-and-values & body]
     `(let [~@alternating-symbols-and-values
          names# (quote ~(flatten (partition 1 2 alternating-symbols-and-values)))
          values#  ~(vec (flatten (partition 1 2 alternating-symbols-and-values)))
          locals# (zipmap names# values#)]
       (dorun (for [x (vals locals#)] 
           if (number? x) (println "roar"))))))

ボディに特定のシンボルを挿入する必要がなくなったので、置き換えられたローカルをgensym'dシンボルに移動しました

なぜこのようなハードコードされたマクロにユーザー指定のシンボルを導入したいのか、私にはわかりません。これは実験用だと思います。

于 2013-01-18T12:39:32.920 に答える