I'm running Chez Scheme 9.5 and am trying to define a syntax transformer in a library. Here's an example:
(library (forlib)
(export for)
(import (rnrs (6)))
(define-syntax for
(syntax-rules (in)
[(for x in lst body1 body2 ...)
(for-each (lambda (x) body1 body2 ...) lst)])))
I save this in a file forlib.ss
and run chez
from the same directory.
Then in the REPL, I get this:
> (import (forlib))
> (for x in '(1 2 3) (display x))
Exception: invalid syntax (for x in (quote (1 2 3)) (display x))
Type (debug) to enter the debugger.
If I change the syntax definition to
(define-syntax for
(syntax-rules ()
[(for x lst body1 body2 ...)
(for-each (lambda (x) body1 body2 ...) lst)])))
(without the in
keyword), everything works:
> (import (forlib))
> (for x '(1 2 3) (display x))
123
> _
Back to the old definition with the in
keyword.
If I put the test code into a test file:
;;; test-for.ss
(import (rnrs (6))
(forlib))
(for x in '(1 2 3) (display x))
and try to execute this file, the result depends on how I execute the file.
If I run this program using chez --program
, it works as expected:
$ chez --program test-for.ss
123
$ _
If I run it using chez --script
, I get the same error as above:
$ chez --script test-for.ss
Exception: invalid syntax (for x in (quote (1 2 3)) (display x)) at line 6, char 1 of test-for.ss
$ _
This raises two questions:
- Why is the REPL and
--script
fine with importing syntax forms without special keywords but refuses to accept syntax forms that do have special keywords in them? - What exactly is the difference between
--script
and--program
? The user manual says that--program
means that the file content is interpreted as an rnrs top-level program but is silent as to what the semantics of--script
are.
Finally, to make my consfusion complete, if I enter the above syntax definition directly in the REPL, then everything works as expected:
> (define-syntax for
(syntax-rules (in)
[(for x in lst body1 body2 ...)
(for-each (lambda (x) body1 body2 ...) lst)])))
> (for x in '(1 2 3) (display x))
123
> _
So what is different in the REPL between syntax transformers imported from a library and syntax transformers defined directly in the REPL?
in
as you suggest, I get an error because there is no name defined inforlib
to be exported. As pointed out by @gmw below, for this to work, it is necessary forforlib
to create a dummy namein
that can be exported. – Greedy