Le mardi 08 août 2023 à 21:38 +0200, Maxime Devos a écrit : > As such, this not working on the top-level seems a bug to me -- after > all, a module definition is conceptually just a big let: > > (if applicable) > (let () >    >    (define ...) >    (define-syntax-rule ...) ... >    ;; use a new macro using syntax-local-binding >    ;; to extract the syntax transformer (*). >    ) > > (*) not sure if that precise approach actually works in this context This is very tempting to believe, and I wish it were true, but it's not true. At least in Guile, the part doesn't happen at the end of evaluating the module. Each module variable is created and inserted while evaluating the define form. Otherwise this would give an error: (define a 5) (define b (module-ref (current-module) 'a)) (display b) The consequences are not innocent. A variable is associated to a binding which is a "place" in the terminology of some other languages, i.e., something you can set!. For toplevel variables, because you can use module-set!, a module variable is used as the place. And because module variables are bound to names which are just symbols, duplicate definitions stomp on each other. Consider this: (define a 5) (define (b) a) (define a 6) (display (b)) This is valid in Guile and prints 6. The second definition for `a` reuses the same variable as the first one, effectively acting like a set!. Contrast this with (let () (define a 5) (define (b) a) (define a 6) (display (b))) which raises an error due to the duplicate binding. As https://okmij.org/ftp/Scheme/macros.html#syntax-rule-dark-corner puts it, "the top level of Scheme is indeed under-specified and treacherous". Best, Jean