Hello,
I've encountered an interesting behavior with Chicken's module system that
I'd like to understand better. When a module has a completely empty export
list, any exports generated by macros within the module body seem to be
ignored.
Here's a minimal example that demonstrates the issue:
;; mylib.scm
(module mylib () ;; Empty export list
(import scheme chicken.base chicken.syntax)
(define-syntax define-with-export
(er-macro-transformer
(lambda (x r c)
(let ((name (cadr x))
(value (caddr x)))
`(,(r 'begin)
(,(r 'export) ,name)
(,(r 'define) ,name ,value))))))
(define-with-export foo "hello")
)
When compiling with csc -s -J mylib.scm and trying to use it:
(import mylib)
foo ;; Error: unbound variable
However, if I change the module to export at least one symbol directly:
(module mylib (dummy) ;; Non-empty export list
;; ... rest of code including a (define dummy 'x)
Then the macro-generated export of foo works as expected.
Looking at the generated .import.scm file, the symbol appears in the export
list in both cases, but it's only actually accessible when the initial
module export list is non-empty.
Is this expected behavior? Is there a technical reason why macro-generated
exports require at least one explicit export in the module declaration? Or
is this perhaps a bug?
I'm using Chicken 5.4.0.
Thank you for any clarification on this!
Best,
Rolando