2

clojuredefmacroに自分のやりたいことをさせるのに苦労しています。実際のコードを次のスニペットに減らしました。

これは私が欲しいものに近い何かを作成します。マクロに渡されたパラメーターに応じて、(最初のp#)または(2番目のp#)のいずれかを条件付きで挿入しようとしています。

(defmacro mmz1 [t]
  `(map (fn [p#] (let [t1# (first p#)
                      t2# ~(if t `(first p#) `(second p#))]
                  (* t1# t2#)))
        [ [1 2] [3 4] ]))

(macroexpand-1 '(mmz1 false))

ショー

(map
  (fn [p__18341__auto__]
    (let [t1__18342__auto__ (first p__18341__auto__)
          t2__18343__auto__ (second p__18340__auto__)]
      (* t1__18342__auto__ t2__18343__auto__)))
  [[1 2] [3 4]])

ただし、この形式の変数(2番目のp_ 18340 _auto_)は無名関数の引数p _18341_auto_と一致しないことに注意してください。したがって、その2番目の変数が定義されていないため、コードを実行するとエラーが発生します。これらの変数を一致させるにはどうすればよいですか?これが私が成し遂げたいことです。

テストの目的で、このコードは私が望むことを達成しますが、t2#を設定する結果のマクロコードに(if)形式は必要ありません。マクロは私がこれを行うことを可能にするはずです-そうではありませんか?

(defmacro mmz0 [t]
  `(map (fn [p#] (let [t1# (first p#)
                      t2# (if ~t (first p#) (second p#))]
                  (* t1# t2#)))
        [ [1 2] [3 4] ]))

(macroexpand-1 '(mmz0 false))

ショー

(map
  (fn [p__18387__auto__]
    (let [t1__18388__auto__ (first p__18387__auto__)
          t2__18389__auto__ (if false
                              (first p__18387__auto__)
                              (second p__18387__auto__))]
      (* t1__18388__auto__ t2__18389__auto__)))
  [[1 2] [3 4]])

コードの出力は期待どおりです。

(mmz0 false) -> (2 12)
4

2 に答える 2

3

ソリューションの1つ

(defmacro mmz1 [t]
  `(map (fn [p#] (let [t1# (first p#)
                       t2# (~(if t 'first 'second) p#)]
                   (* t1# t2#)))
        [ [1 2] [3 4] ]))

更新します。より一般的な解決策

(defmacro mmz1 [t]
  (let [trg-fn (if t 
                 `(fn [p#] (first p#)) 
                 `(fn [p#] (second p#)))]
    `(map (fn [p#] (let [t1# (first p#)
                         t2# (~trg-fn p#)]
                   (* t1# t2#)))
        [ [1 2] [3 4] ])))

ブランチをより複雑な関数に(fn [p#]...)置き換えることができます。if

Update2。事前定義された関数の仮パラメーターを使用するより単純なソリューションp

(defmacro mmz1 [t]
  (let [p `p#]
   `(map (fn [~p] (let [t1# (first ~p)
                        t2# ~(if t `(first ~p) `(second ~p))]
                    (* t1# t2#)))
         [ [1 2] [3 4] ])))
于 2013-01-11T03:45:05.780 に答える
0

これはマクロである必要はまったくないことを述べておく必要があります。

同等の機能は読みやすく、構成しやすいので、それを使用することをお勧めします。

于 2013-01-11T06:28:01.323 に答える