7

在 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

现在,我的问题是:

  1. 我可以在 Racket 中编写宏定义宏吗?
  2. 如果可以,该怎么做?abbrev(例如,如何在 Racket中编写类似于 宏的东西?)
4

3 回答 3

9

根据球拍指南的这一部分:

(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 的东西。

于 2014-10-27T21:39:45.033 回答
5

广告 1. 是的。ad 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。

于 2014-10-27T21:38:38.523 回答
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

为此目的似乎不需要任何宏。

于 2016-10-18T02:30:31.993 回答