Макроопределяющий макрос в Racket?

В 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 макрос в ракетке?)

3 ответа

Решение

Согласно этой части руководства по ракеткам:

(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.

Объявление 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.

Я считаю, что переименование может быть сделано просто с помощью операторов 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

Кажется, для этой цели не требуется никакой макрос.

Другие вопросы по тегам