【问题标题】:Is it possible for a user to define special form macros?用户是否可以定义特殊形式的宏?
【发布时间】:2013-03-04 18:43:13
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: clojure


    【解决方案1】:

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

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

    【讨论】:

    • 请参阅更新。我的意思是是否有可能以某种方式影响字符的标记化和对什么构成标记的识别。否则,在“字符串”的宏展开的情况下。我不清楚扩展的宏名称是什么(我不认为宏“String。”是硬编码定义的)
    【解决方案2】:

    如果我理解正确,您正在尝试写 reader macro,简短的回答是“不,这是不可能的”(或至少不支持)。

    看看this article 和它的cmets

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-08
      • 1970-01-01
      • 1970-01-01
      • 2011-07-15
      • 1970-01-01
      相关资源
      最近更新 更多