Idiomdrottning’s homepage

define-ir-syntax

Part of a future thing I’m daydreaming about for Chicken Scheme but maybe useful already on its own:

(define-syntax define-ir-syntax
  (ir-macro-transformer
   (lambda (e i c)
     `(define-syntax ,(cadr e)
        (ir-macro-transformer
         (lambda (,(i 'exp) ,(i 'inject) ,(i 'compare))
           ,@(cddr e)))))))

If you’re, like me, nostalgic for the leakiness & brevity of defmacro, this might be just the ticket. Here’s an example of how to use it:

(define-ir-syntax aif
  `(let ((,(inject 'it) ,(cadr exp)))
     (if ,(inject 'it) ,(caddr exp) ,(cadddr exp))))

That’s right. Even the definer of anaphoric macros is itself an anaphoric macro, implicitly binding exp, inject, and compare.

Bonus Episode! define-syntax-rules

Also, while there is already define-syntax-rule, here is define-syntax-rules for when you have multiple patterns per name.

(define-syntax define-syntax-rules
  (syntax-rules ()
    ((_ name arg ...)
     (define-syntax name
       (syntax-rules arg ...)))))

That might be a little “not worth it”—only saving a single token and a pair—but I’m just really longing for more brevity.

Update: define-ir-syntax*

I found in practice that I often enough wanna destructure and pattern match on exp, rather than inject it. The destructuring-bind companion to our defmacro, as it were. Let’s add a * variant.

(import-for-syntax matchable)
(define-syntax define-ir-syntax*
  (ir-macro-transformer
   (lambda (e i c)
     `(define-syntax ,(cadr e)
        (ir-macro-transformer
         (lambda (exp ,(i 'inject) ,(i 'compare))
           (match exp
             ,@(cddr e))))))))

So it’s similar to define-syntax-rules except there is no keyword field but you can inject and compare.

With this we can make another version of aif:

(define-ir-syntax* aif
  ((aif test yes no)
   `(let ((,(inject 'it) ,test))
      (if ,(inject 'it) ,yes ,no))))

For another example, see define-closure in Fancy defines.