首页 文章

Racket中的宏定义宏?

提问于
浏览
6

在Common Lisp中,创建宏定义宏相对容易 . 例如,以下宏

(defmacro abbrev (short long)
  `(defmacro ,short (&rest args)
     `(,',long ,@args)))

是一个宏定义宏,因为它扩展到另一个宏 .

如果我们现在放

(abbrev def defun)

在我们的程序中,每当我们定义一个新函数时,我们都可以编写 def 而不是 defun . 当然, abbrev 也可以用于其他事情 . 例如,之后

(abbrev /. lambda)

我们可以写 (/. (x) (+ x 1)) 而不是 (lambda (x) (+ x 1)) . 尼斯 . (有关缩写的详细说明,请参阅http://dunsmor.com/lisp/onlisp/onlisp_20.html

现在,我的问题是:

  • 我可以在Racket中编写宏定义宏吗?

  • 如果可以,怎么办? (例如,如何在Racket中编写类似 abbrev 宏的内容?)

3 回答

  • 8

    根据球拍指南的this部分:

    (define-syntax-rule (abbrev short long)
      (define-syntax-rule (short body (... ...))
        (long body (... ...))))
    

    引用上述链接:

    其定义中唯一不明显的部分是(......),它“引用”......因此它在生成的宏中起着通常的作用,而不是生成宏 .

    现在

    (abbrev def define)
    (abbrev /. lambda) 
    (def f (/. (x) (+ x 1)))
    (f 3)
    

    产量

    4
    

    FWIW,它也适用于Guile,所以它不是特定于Racket的东西 .

  • 5

    广告1.是的 . 广告2.您的示例最容易编写

    #lang racket
    
    (define-syntax (abbrev stx)
      (syntax-case stx ()
        [(_ short long)
         #'(define-syntax short (make-rename-transformer #'long))]))
    
    (abbrev def define)
    (def x 42)
    x
    

    上面的例子评估为42 .

  • 0

    我发现可以使用define或let语句简单地重命名:

    (define =? =)
    (define lr list-ref)
    

    要么:

    (let ((=? =)
          (lr list-ref))
      (println (lr '(1 2 3) 2))
      (println (=? 1 2))
      (println (=? 1 1)))
    

    输出:

    3
    #f
    #t
    

    似乎没有必要为此目的使用任何宏 .

相关问题