2014-10-27 83 views
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

现在,我的问题是:

  1. 我可以写在球拍宏定义宏?
  2. 如果可以,该怎么做? (例如,如何在球拍中写入类似于 abbrev宏的东西?)
+0

你反过来你的宏参数,应该先来。 – uselpa 2014-10-27 21:51:55

+0

我纠正了我的问题。坦克! – 2014-10-27 22:00:30

回答

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,它适用于狡诈一样,所以它没有具体的球拍的事情。

5

ad 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

“新”一词在这里造成混乱(“短”实际上是新词)。如果在本页面的其他地方使用“长”(而不是“新”),则会更清楚。 – rnso 2016-08-24 05:19:27

+0

我同意。我改变了它。 – soegaard 2016-08-24 07:50:35

0

我发现,重命名,可以简单地进行定义或让语句:

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

或:

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

输出:

3 
#f 
#t 

似乎有没有必要任何宏为此目的。

+0

当你想重新命名一个特殊的窗体或者像'define'或者'lambda'这样的宏时,这是行不通的。 – 2016-10-18 04:03:51

+0

然后''define-syntax def(make-rename-transformer#'define))''' (define-syntax /。(make-rename-transformer#'lambda))' – 2016-10-18 04:04:51