1

看看一些特殊形式的扩展方式:

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

...并意识到它们是作为宏实现的,这让我很好奇用户定义的宏的语法形式限制是什么。到目前为止,我所有的宏在语法形式上都类似于函数。但是,例如,是否有可能定义一个如下所示的宏?

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

2 回答 2

3

限制是宏必须有一个有效的名称并返回一个表达式。例如,它不能在调用命名空间中的表达式的末尾添加一些东西,也不能返回两个表达式按顺序插入到调用命名空间中(而不是通过将其包装在一个表达式中来使其成为一个表达式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 表达式(函数 arg arg ...)。宏的名称必须与要调用的宏完全匹配,因此宏的名称不能是宏的一部分。您可以使用新的可扩展阅读器功能接近您所询问的内容,尽管这不是您所需要的。

ps:值得指出的是,这个例子违反了宏俱乐部的第一条规则,是“不卫生的”

于 2013-03-04T18:45:44.347 回答
1

如果我理解正确,您正在尝试编写阅读器宏,而简短的回答是“不,这是不可能的”(或者至少不支持)。

看看这篇文章及其评论

于 2013-03-04T20:15:08.193 回答