💾 Archived View for idiomdrottning.org › define-er-syntax captured on 2024-02-05 at 10:10:59. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2023-01-29)

-=-=-=-=-=-=-

define-er-syntax*

An explicitly implicitly renaming macro transformer.

Ok, so this is define-er-syntax*. Pretty much the closest thing we’ve got to the Common Lisp, Emacs Lisp style defmacros.

You explicitly make for renaming things that you don’t want to clobber into the environment. The equivalent of renaming with gensyms in those other languages. Here’s an implementation of anaphoric if:

(define-er-syntax*
  (e-aif test yeah naw)
  `(,(rename 'let) ((it ,test)) (,(rename 'if) it ,yeah ,naw)))

(e-aif (+ 2 2) (+ 2 it) 5)
⇒ 6

But unlike defmacro, and like syntax-rules, you can have several patterns to dispatch between. (It uses matchable.)

(define-er-syntax*
  ((foo bar) `(,(rename 'quote) ,bar))
  ((foo baz quux) `(,(rename 'quote) (,baz ,quux))))

(foo beer)
⇒ beer

(foo orange soda)
⇒ (orange soda)

If you’re getting tired of all that renaming, there’s ir and except in addition to rename and compare:

(define-er-syntax*
  (ei-aif test yeah naw)
  (ir `(let ((,(except 'it) ,(except test)))
         (if ,(except 'it) ,(except yeah) ,(except naw)))))

(ei-aif (+ 4 4) it 9)

Of course, if you only want ir all the time, let me introduce you to my friend, define-ir-syntax* from brev-separate:

(import brev-separate)

(define-ir-syntax*
  (i-aif test yeah naw)
  `(let ((,(inject 'it) ,test)) (if ,(inject 'it) ,yeah ,naw)))

(i-aif (* 9 9) (+ 1 it) 18)
⇒ 82

99% of the time, that’s what you want to use instead of this egg and define-er-syntax*.

define-ir-syntax* is even better since you don’t have to “except” the macro’s own inputs, you only have to “inject” things you really want to inject there, like anaphora and generated defines.

But define-er-syntax* exists for that 1% of times when you’re building a macro that’s really weird and complicated and you need full control over your renaming since you might be loading and reloading generated code or other shenanigans.

TL;DR: don’t use define-er-syntax* unless you know what you’re doing; use syntax-rules if you don’t need to inject and define-ir-syntax* if you do.

What am I doing with my life… making code to generate code to generate code to generate code to generate code to…

Source code

For source code,

git clone https://idiomdrottning.org/define-er-syntax