[plt-scheme] Newbie question: using a macro to create a top-level variable?
On Aug 21, Gregg Williams wrote:
>
> (define ideas (infoml:make-rack-manual 'ideas))
>
> I need the variable named "ideas" so I can manipulate the rack from
> the command line. I need the symbol 'ideas (which goes into the rack
> data structure) so that I can, for example, print a list of all
> existing racks.
>
> The thing is, I would like to be able to write the simpler
> "(infoml:make-rack-manual 'ideas))" and let it create a top-level
> variable with the same name as the symbol given as an argument. I
> can't do that within a simple function definition, but I thought I
> could do it within a macro. Here's what I tried at first (which of
> course didn't work):
>
> (define-syntax-rule (infoml:make-rack rack-symbol)
> (define rack-symbol (infoml:make-rack-manual rack-symbol)))
>
> When I did a macro expand in DrScheme, I could see why it didn't work--
> the expansion was:
>
> (define (quote rack-symbol) (infoml:make-rack-manual rack-symbol))
>
> Obviously, it was important to get precisely the right thing after the
> keyword "define". I tried unquoting the symbol; I tried converting the
> symbol into a string--neither worked.
The thing is that you want to quote one place only. An easy way to do
this is:
(define-syntax-rule (infoml:make-rack rack-id)
(define rack-id (infoml:make-rack-manual 'rack-id)))
(infoml:make-rack ideas) ; no quote
You can do this with the quote:
(define-syntax-rule (infoml:make-rack 'rack-id)
(define rack-id (infoml:make-rack-manual 'rack-id)))
(infoml:make-rack 'ideas)
This looks like it's working, but what's really happening is that the
scheme reader sees:
(define-syntax-rule (infoml:make-rack (quote rack-id))
(define rack-id (infoml:make-rack-manual (quote rack-id))))
and `quote' is just a pattern variable that matches anything. So if
you enter
(infoml:make-rack (add1 ideas))
it actually expands to
(define ideas (infoml:make-rack-manual (add1 ideas)))
To make this way work, you can use the more explicit `syntax-rules',
and specify `quote' as a keyword:
(define-syntax infoml:make-rack
(syntax-rules (quote)
[(_ (quote rack-id))
(define rack-id (infoml:make-rack-manual (quote rack-id)))]))
and doing this should make it clear that this is all redundant since
the `quote' requirement is just an arbitrary piece of syntax that
isn't really doing anything.
--
((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:
http://barzilay.org/ Maze is Life!