简体   繁体   中英

Macro-defining macro in Racket?

In Common Lisp it is relatively easy to create a macro-defining macro. For example, the following macro

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

is a macro-defining macro, because it expands to another macro.

If we now put

(abbrev def defun) 

in our program, we can write def instead of defun whenever we define a new function. Of course, abbrev can be used for other things, too. For example, after

(abbrev /. lambda)

we can write (/. (x) (+ x 1)) instead of (lambda (x) (+ x 1)) . Nice. (For detailed explanation of abbrev, see http://dunsmor.com/lisp/onlisp/onlisp_20.html )

Now, my questions are:

  1. Can I write the macro-defining macros in Racket?
  2. If I can, how to do that? (for example, how to write something similar to abbrev macro in Racket?)

According to this part of the Racket Guide:

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

Quoting the above link:

The only non-obvious part of its definition is the (... ...), which “quotes” ... so that it takes its usual role in the generated macro, instead of the generating macro.

Now

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

yields

4

FWIW, it works on Guile as well, so it's no Racket-specific thing.

ad 1. Yes. ad 2. Your example can most easily be written

#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

The example above evaluates to 42.

I find that renaming can be done simply with define or let statements:

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

or:

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

Output:

3
#f
#t

There seem to be no need for any macro for this purpose.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM