1

いくつかの特別なフォームが展開される方法を見る:

(macroexpand '(String. "foo"))
(macroexpand '('a))
;; etc

...そして、それらがマクロとして実装されていることを理解すると、ユーザー定義マクロの構文形式の制限は何かについて興味があります。これまでのところ、私のマクロはすべて構文上の関数に似ています。しかし、たとえば、次のようなマクロを定義することは可能でしょうか?:

(macroexpand '(myprintln-foo))
;;=> (println "foo")
(macroexpand '(myprintln-zoo))
;;=> (println "zoo")
4

2 に答える 2

3

制限は、マクロが単一の有効な名前を持ち、単一の式を返す必要があることです。たとえば、呼び出し元の名前空間で式の末尾に何かを追加することはできません。また、呼び出し元の名前空間に挿入される 2 つの式を返すこともできません (1 つの式を a でラップしてdo. と書くことはできません)。多くのマクロを定義するマクロ:

(defmacro make-printers [& names]
  `(do ~@(for [name  names]
           `(defmacro ~(symbol (str "myprintln-" name)) []
              (println ~(str name))))))

user> (make-printers foo bar)
#'user/myprintln-bar
user> (myprintln-foo)

foo
nil 
user> (myprintln-bar) 
bar
nil 

マクロは、s 式を返す単なる関数です。その式は、有効な s 式 (function arg arg ...) である限り、何でもかまいません。マクロを呼び出すには、マクロの名前が正確に一致する必要があるため、マクロの名前をマクロの一部にすることはできません。新しい拡張可能なリーダー機能を使用すると、求めていることに近づくことができますが、それは必要なものではありません.

ps: この例は、マクロ クラブの最初の規則に違反しており、「非衛生的」であることを指摘する価値があります。

于 2013-03-04T18:45:44.347 に答える
1

私の理解が正しければ、リーダー マクロを作成しようとしており、短い答えは「いいえ、不可能です」(または少なくともサポートされていません) です。

この記事とそのコメントを見てください

于 2013-03-04T20:15:08.193 に答える