On Wed, Aug 30, 2017 at 11:08 AM, <hiph...@openmailbox.org> 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+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.