I have a macro that generates another macro. It uses the letrec trick to generate temporaries to use as binders in the left-hand-side of the generated syntax-rules.

The following code, when pasted into csi (and chibi, as a test) does the correct thing:

(define-syntax define-alist-macro
  (syntax-rules ()
    ((_ name (ids ...))
     (define-alist-macro "generate" name (ids ...) ()))
    ((_ "generate" name (id ids ...) (acc ...))
(define-alist-macro "generate" name (ids ...) ((cons id tmp) acc ...)))
    ((_ "generate" name () ((cons id tmp) ...))
     (define-syntax name
       (syntax-rules ...* ()
         ((_ tmp ...) (list (cons (quote id) tmp) ...)))))))
(define-alist-macro test (a b c d))
(display (test 4 3 2 1))

This displays "((d . 4) (c . 3) (b . 2) (a . 1))".

However, if I put the same code in a module:

(module my-test (define-alist-macro test)
  (import scheme)
  (define-syntax define-alist-macro
    (syntax-rules ()
      ((_ name (ids ...))
       (define-alist-macro "generate" name (ids ...) ()))
      ((_ "generate" name (id ids ...) (acc ...))
(define-alist-macro "generate" name (ids ...) ((cons id tmp) acc ...)))
      ((_ "generate" name () ((cons id tmp) ...))
       (define-syntax name
         (syntax-rules ...* ()
           ((_ tmp ...) (list (cons (quote id) tmp) ...)))))))
  (define-alist-macro test (a b c d)))

compile that module with "csc -s tmp-module.scm", and then run in csi

(load "tmp-module.so")
(import my-test)
(display (test 1 2 3 4))

I get "((d . 4) (c . 4) (b . 4) (a . 4))", probably because the compiled CHICKEN code is turning all of the generated "tmp" variables into a single identifier.

-----------------------------------------------------------

Chicken Version: 5.4.0
OS: Alpine Linux x86_64
CC: GCC Alpine 13.2.1_git20240309 (using musl libc)

Reply via email to