How to write anaphoric macros in a portable circuit?

I'm learning Scheme macros, but I haven't been able to find a portable way to write anaphoric macros.

I am trying to write a macro each-it

so this code:

(each-it (list 1 2 3)
  (display it))


Expands to:

(for-each (lambda (it)
            (display it))
          (list 1 2 3))


I wrote a macro with syntax-rules

, but it gives me an error regarding the undefined id when I try to use it.

(define-syntax each-it
  (syntax-rules ()
    ((each-it lst body)
     (for-each (lambda (it) body)


This SO question mentions define-syntax-parameter

which seems to be only Racket. This blog post provides some sample code for the schema, but the code samples do not run in DrRacket in mode R5RS

(I think these are square brackets?).

R4RS has an interesting macro app , but it's not in R5RS and I don't know if I can depend on it.

Can I write my macro in a each-it

completely portable way? If not, what are the most widely available macrosystem functions for writing my macro?


source to share

2 answers

This should be portable at least in R6RS:

(define-syntax each-it
  (lambda (x)
    (syntax-case x ()
      ((_ lst body)
       (with-syntax ((it (datum->syntax x 'it)))
         #'(for-each (lambda (it) body) lst))))))




Yes, you can write it portable, assuming the R6RS is portable enough for you. (The same cannot be said for R7RS, which currently has nothing short of simple syntax-rules

, and it is unclear what will be included in the big language or when this will happen.) See Uselpa for how to do it.

So why am I writing another answer? Because it would actually be a bad idea. Not a bad idea in some vague academic sense that doesn't matter to the most real code in the world - bad in a way that is more likely to bite you later. I know "paper" makes it look scary, but read at least the first two sections of the document mentioned in another SO question you have seen. In particular, section 1.2 shows the problem you are facing. Then, Section 2 shows you how to do it "right", in a tedious way to write macros that expand to use your macro. For now, this will be a call to accept "just keep it hygienic", but at the end of section 2 you will seewhy doesn't that work either.

Bottom line, IMO, just don't do it unless you have syntax parameters or something similar. Perhaps the only exception to this (which might be in your case) is that a macro is something you intend to use yourself and you will never leave it to others.



All Articles