2013-04-03 9 views
5

2つ以上のs式を返すマクロを記述する(または既存のものを使用する)方法はありますか?2つ以上のs式を返すClojureマクロ

例。

(map * (repeat 2 (range 10))) 

(map * (range 10) (range 10)) 

は、今私がしようとすると、パラメータとして、私は、後に(今のところ2)電力を供給できるように繰り返しを使用したい:私は最初の10個の正方形を生成しようとしていますと言います

上記は動作しませんは2つの範囲ではなく2つの範囲で単一のs式を返します。

「最初の10四角形を返す」関数の代替実装を提供しないでください。このような状況や一般的に適用可能な回避策に対処するための慣用的な方法に興味があります。私はを実装する方法を探していたとし

は以下を爆発:

(explode '(a b c)) ;; evals to a b c 
(map * (explode (repeat 2 (range 10))) 
+0

ご質問はやや混乱しています。あなたが仕事を見たいと思う構文の例を提供できるなら、それは役に立ちます。現在、Clojureで特定の定義を持つ 'map'と' repeat'を使用しています。 – JohnJ

+0

@JohnJ私の投稿の更新された尾を参照してください –

答えて

4

1つのマクロは、これを行うことはできません。

マクロは、がs式を受け取り、別のs式に変換する関数です。入力は任意の式のシーケンス(シンボル、プリミティブ、その他の式など)で、出力は元のマクロ呼び出しの代わりに挿入される単一の式です。あなたは二つのマクロ、式と全体の外形を包含することが別のものを作り出す1、外側のマクロを使用している場合は

一般的にマクロは、フォーム全体をマッピングして変換するための呼び出しを囲むように

(your-macro-here (map * (repeat 2 (range 10)))) 

を持っているでしょうあなたの例では2つの範囲でマクロ結果を含む単一の式を見つけることができ、それらを独立した式として1つのレベルまで上げることができます。実際にこれを行うことはお勧めできませんでしたが、マクロの機能を説明するだけです。

2

アーサー氏によれば、マクロで探しているものを正確に行うことはできません。これらのフォームで何をしたいかによって、回避策が可能です。

マクロによって生成された複数のフォームを評価したい場合は、定型的なコードを簡素化するために、あなたはdo形で、これらの複数のフォームをラップすることができます:

(defmacro defn-foos [& foos] 
    `(do [email protected](map (fn [foo] `(defn ~foo [])) foos))) 

(defn-foos my-fn-1 my-fn-2) 
;; expands as: 
;; (do (defn my-fn-1 []) 
;;  (defn my-fn-2 [])) 

を使用すると、関数呼び出しで位置引数として拡大フォームを使用する場合、あなたが、あなたの最善の策である、やる表示されますおそらくそれらをlistで包み込み、applyを使用して、リストを関数の定位置引数としてアンパックします。

これがどのように動作するかを確認するには、あなたの元の質問の2番目の例は自明applyを使用して動作するように変更することができることに注意してください:文言として

(apply map * (repeat 2 (range 10))) 
関連する問題