Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Which lisps lack a macro expansion system?


R7RS (small, at least) doesn't seem to have macro-expand. R6RS also doesn't appear to have it.


So the modern scheme specs. (I'd argue putting small in there is unfair considering its intent and the actual implementations of r6rs do offer expansion, e.g. chez, guile, racket)


R6RS has syntax-case macros which is superior to Common Lisp macros in every respect, they're both hygienic and can be used to implement a sloppy macro system if one so wishes.


`syntax-rules` is very good and you can do a whole lot with them. However, you are limited to template -> pattern transformations, and there are plenty of macros that you cannot write this way. (E.g. anything requiring a predicate on the source syntax that you can't express in the template language, etc.) For that, you need the full power of procedural macros.

Racket improves on Scheme: its macros are fully hygienic whilst not being limited to template -> pattern transforms. See https://docs.racket-lang.org/guide/macro-transformers.html

EDIT: syntax-case -> syntax-rules; R6RS specifies the latter—I believe the former is a Racket construct equivalent in power to `syntax-rules`.


I think the parent meant that R6RS has `syntax-rules`, which has enough power to implement CL `defmacro` as well as `syntax-case`.


My mistake: R6RS has `syntax-rules`, not `syntax-case` as far as I can tell. However, `syntax-rules` and `syntax-case` are equivalent in power. [1]

It does not have the same power as `defmacro`: you cannot define general procedural macros with `syntax-rules`, as you are limited to the pattern-matching language to compute over and construct syntax objects.

[1]: https://docs.racket-lang.org/reference/stx-patterns.html#%28...


I think you got your wires crossed. R5 and R7 only have `syntax-rules` macros. R6 has both (`syntax-rule` can be trivially defined as a `syntax-case` macro).

R6 having `syntax-case` macros is one of the more controversial things about it; a surprising number of implementers don't care for them.


I found the relevant documentation and you are absolutely correct and I was mistaken. Thank you for setting me straight.

https://www.scheme.com/tspl4/syntax.html#./syntax:h3


I think we're talking past each other. I mean something like:

  (macroexpand '(when-let (foo (frob bar))
      (jib foo)))
  ;; (let ((foo (frob bar)))
  ;;   (when foo
  ;;     (jib foo)))


The name `macro-expand` is from Common Lisp.

Scheme R5RS, R6RS and R7RS all have macro systems. In R5RS has a pattern/template based system (syntax-rules). In R6RS the system has both patterns, templates and procedural macros.

The most modern system is Racket though. See `syntax-parse`.


+1 for `syntax-parse`—it's thoroughly the most powerful (and yet somehow also the most ergonomic) way to write macros in any language thus far.

Wait, r6rs has proc macros? Where is that in the spec? I've only seen the `syntax-rules` bit.





Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: