2014-10-27 87 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