Re: Need help improving a macro

Philip McGrath <philip-HuI0B06iylScIzJqBAPImwC/[email protected]>
Newsgroups gmane.comp.lang.racket.user,gmane.lisp.scheme.plt
Message-ID <CAH3z3gasU=Fw_z0LpLHtHcz-b-d48Xr+fgFD8X_0Mh-oBSWP4A@mail.gmail.com>
On Wed, Aug 30, 2017 at 11:08 AM, <[email protected]> wrote:

> How did other people learn Racket meta programming?
>

I don't consider myself a huge expert in macros, but personally I found the
"Examples" section of the syntax/parse documentation very helpful (
http://docs.racket-lang.org/syntax/stxparse.html), as well as Greg
Hendershot's "Fear of Macros" (
http://www.greghendershott.com/fear-of-macros/). As with everything else,
though, there's no substitute for just getting experience actually writing
and debugging some macros.


> It looks like your macro is turning strings into symbols.
>

It looks like that because strings `display` without quotation marks (try
`(displayln "I am a string.")`). If you want use `syntax->datum`, try
`println` instead.

(Also, probably obviously, I only defined `register-nvim-function!` as a
macro for illustrative purposes.)

The `#:with` directive mathes the `opt ...` pattern against a syntax
> object which has been constructed out of all the non-name pairs.


Yes. The two tricky things are that I include the keywords themselves as
well as their value expressions for easy destructuring later and that drop
any clause that doesn't appear. Using a `#:defaults` declaration is an
alternative, but personally I've come to the point of view that you should
avoid having the default value expression repeated both in the function and
in the macro.


> But how does the `name` attribute get its value? Because it's not an `opt`?
>
The name attribute gets its value from the `name` pattern variable. The
`#:attributes` declaration is strictly optional, but I like it both for my
own ease of understanding later and because it is checked.


> The `raw-lhs` is the thing we want defined. How does it know to match
> both `foo` and `(foo bar baz)`?
>
> I don't understand why we need this. It takes apart a definition we
> built on the fly, takes it apart, but in the template we put thing back
> together in the same order:
>

Because `raw-lhs` is annotated as an `expr`, it matches anything that isn't
a keyword, including both `name` and `(name arg1 arg2)`, as well as keyword
and optional arguments, for example. Then `normalize-definition` handles
converting the `define`-like form into a plain identifier to be defined and
a single `λ` expression, including checking for other subtle errors like
duplicate argument identifiers. With `syntax-parse` it's much easier to
write those sort of checks yourself than it was with just `syntax-case`,
but I personally still like the library function.

-- 
You received this message because you are subscribed to the Google Groups "Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/[email protected]
For more options, visit https://groups.google.com/d/optout.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.