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 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. For example, after

 (abbrev /. lambda) 

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

Now my questions are:

  • Can I write macro-defining macros in Racket?
  • If I can, how to do it? (for example, how to write something similar to an abbrev macro in Racket?)
+6
source share
3 answers

In accordance with this part of the racket manual:

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

By specifying the link above:

The only non-obvious part of his definition is (......), which is "quotes" ... so that it fulfills 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) 

gives

 4 

FWIW, it also runs on Guile, so this does not apply to a specific game.

+8
source

ad 1. Yes. 2. Your example can be easily 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 above example evaluates to 42.

+5
source

I find that renaming can be done simply using 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 seems to be no need for any macros for this purpose.

0
source

Source: https://habr.com/ru/post/977298/


All Articles