I am reverting to the renaming semantics Larceny has been using for 10 years. That means tonight's nightly builds will not be able to run the sample implementation of SRFI 148. I will explain why in a moment. Marc Nieper-Wißkirchen wrote: > Yes, I think in fact the main point that needs to be resolved is whether a > pattern variable is bound (for the purposes of hygiene) by a syntax rule as > much as a variable is bound by a lambda form. In Larceny, pattern variables are indeed bound, but I don't think that's important. That binding happens after (and has to happen after) the matching that determines whether the identifiers are pattern variables or literals. > From the view of a macro writer, the syntax-rules system is more powerful > when pattern variables are being renamed, because this would allow me to > generate arbitrary many pattern variables by the usual tricks. That renaming is the reason your sample implementation doesn't work in Larceny (with the reverted semantics). If an identifier occurs within a template but not within the corresponding pattern, it is renamed when the template is transcribed. Those identifiers do indeed act as generated pattern variables, which is the problem. For your sample implementation to work, some of them need to be treated as literals instead of pattern variables. In the sample implementation of SRFI 147 (not 148), an identifier named :continuation is inserted by the 4th rule of expand-transformer the 1st rule of syntax-rules-aux the 2nd rule of syntax-rules-aux the 4th rule of syntax-rules-aux Those inserted identifiers are renamed for hygiene. That means the identifiers named :continuation that are introduced by the 1st and 2nd rules of syntax-rules-aux, in the hope that they will end up as literals, will not match the identifier named :continuation that is introduced by the fourth rule of expand-transformer or by the fourth rule of syntax-rules-aux. Instead of being recognized as literals, which appears to be your intention, the :continuation identifiers introduced by the fourth rules of those two macros will act as pattern variables. That is why your sample implementation doesn't run in Larceny. Here is an example: (let-syntax ((m (em-syntax-rules () ((m 'a) 'a)))) (m '(define x 10)) x) eventually expands into an expression whose de-mangled form is (begin (define-syntax o (em-syntax-rules-aux2 o free-identifier=? () ... () (((m 'a) 'a)) ())) (expand-transformer (let-syntax-aux (m) () () ((m '(define x 10)) x)) o)) The define-syntax form expands into something like (expand-transformer (scheme-define-syntax o) (em-syntax-rules-aux2 o free-identifier=? () ... () (((m 'a) 'a)) ())) which matches the 4th rule of expand-transformer so it becomes something like (em-syntax-rules-aux2 (:continuation&&91 expand-transformer (scheme-define-syntax o)) o free-identifier=? () ... () (((m 'a) 'a)) ()) I have written :continuation&&91 to remind you that :continuation has been renamed. This is a tentative renaming, which will end up resolving to the same binding as :continuation if it ends up as a free variable of the final output, but that isn't what's going to happen. The form above eventually turns into something like (scheme-define-syntax o (scheme-syntax-rules (quote :prepare :call :continuation&&87) ((_ (:continuation&&91 c ...) :prepare s %x) (c ... (ck s "arg" (o) %x))) ((_ (:continuation&&90 c ...) :prepare s . args) (c ... (syntax-error "bad arguments to macro call" . args))) ((_ (:continuation&&89 c ...) :call s 'a) (c ... (ck s 'a))) ((_ (:continuation&&88 c ...) . args) (c ... (ck () (o . args)))) ((_ :prepare s %x) (ck s "arg" (o) %x)) ((_ :prepare s . args) (syntax-error "bad arguments to macro call" . args)) ((_ :call s 'a) (ck s 'a)) ((_ . args) (ck () (o . args))))) Skipping a few steps, the macro expander has to figure out whether the four renamed occurrences of :continuation are pattern variables or literals. To decide which, the macro expander has to match :continuation&&91 (say) against the literal :continuation&&87. Those don't match unless you ignore the renaming, in which case other bad things happen as you pointed out, so they don't match. That means all of the :continuation identifiers in the four rules where they appear are treated as pattern variables, which causes the fourth rule to match when the last was intended. That's why (m '(define x 10)) turns into ((define x 10) (ck () (o))) instead of (ck () (o '(define x 10))) which is why Larceny reports a definition outside any legal context. Now the mystery is why the sample implementation works with all the other systems you tried. They might be renaming less aggressively than Larceny, or they might be using a different semantics when matching identifiers that occur in patterns against the literals. If you had to add a definition of :continuation to get your implementation to work in those systems, that's a clue. They might be resolving the bindings of identifiers just before they decide whether the identifiers are pattern variables or literals, and that resolution might fail for some reason if :continuation isn't bound. That sounds very much like using free-identifier=?, however, which (as you pointed out) does the wrong thing for a different example. Will