Closed BracketMaster closed 3 years ago
There is no defmacro
but you can use explicit renaming macros if you want something quick and dirty, EG:
(define-syntax when
(er-macro-transformer
(lambda (exp rename compare)
(if (null? (cdr exp)) (error/loc "empty when" exp))
(if (null? (cddr exp)) (error/loc "no when body" exp))
`(if ,(cadr exp)
((lambda () ,@(cddr exp)))))))
Thanks. I also wonder if there's a way to "preview" the results of a macro expansion before things get evaluated. This would help with debugging.
There are a few ways to do that:
You can compile a file with the -t
option which will write all of the intermediate transformations - including macro expansions - out to the .c
file.
From the interpreter you can use expand
, EG:
cyclone> (expand '(when #t (+ 1 2 3)) global-environment '()) (if #t ((lambda () (+ 1 2 3))) )
Alternatively when developing an ER macro, since its just a Scheme function, you could define it as a lambda
and pass it your own quoted expression to debug.
it seems expand
has three arguments, what is the third for?
https://justinethier.github.io/cyclone/docs/api/scheme/cyclone/macros#macroexpand
It also seems er-macro-transformer
is implicitly defined within define-syntax
.
https://github.com/justinethier/cyclone/blob/7f4f67f612bcccd2d13a75cbe1e3f282e649a26b/scheme/eval.sld#L533
it seems
expand
has three arguments, what is the third for? https://justinethier.github.io/cyclone/docs/api/scheme/cyclone/macros#macroexpand
Good question. The third argument is an environment of variables renamed directly by macros. For simple testing you can just pass '()
to indicate an empty environment.
Let me see about putting together some documentation to better explain how to use this function.
It also seems
er-macro-transformer
is implicitly defined withindefine-syntax
. https://github.com/justinethier/cyclone/blob/7f4f67f612bcccd2d13a75cbe1e3f282e649a26b/scheme/eval.sld#L533
That is true. Do you have concerns?
Not a problem, just something I observed.
Also, your macro docs are down: https://justinethier.github.io/cyclone/docs/api/scheme/cyclone/macros
Lastly, the following seems to not work:
; myfile.scm
(define-syntax while
(syntax-rules ()
((_ condition . body)
(let loop ()
(cond (condition
(begin . body)
(loop)))))))
(define x 0)
(expand '(while (< x 3) (set! x (+ x 1)) (display x)) *global-environment* `())
(exit 0)
icyc -s myfile.scm
complains Error: Invalid type: expected pair, found : ()
Thanks for the feedback on this :)
The (scheme cyclone macros)
module is no longer used. expand
is documented here: http://justinethier.github.io/cyclone/docs/api/scheme/eval#expand
In your example, the macro expansion itself seems fine. The issue is with calling expand
. You know, when debugging I generally use the other methods and do not call expand
directly. But it would be helpful if we had a way to reliably debug macro expansions from the REPL. Let me take a closer look and see what can be done.
Apologies, the appropriate call is:
(expand '(while (< x 3) (set! x (+ x 1)) (display x)) *global-environment* (env:extend-environment '() '() '())
That works but is a lot to type and remember... So expand
has been updated on master
to only require a single expression argument:
(expand '(while (< x 3) (set! x (+ x 1)) (display x)))
This is available now if you are building from source and will be included in the next release.
Sometimes I like to write quick and dirty macros, but it seems cyclone doesn't support this? It seems SCM will allow you to make macros hygenic with
gentemp
for example. Is this available in cyclone?