On Jul 20, 2016, at 8:37 AM, Joel Dueck <[email protected]> wrote:
> 
> This is a big help for my understanding of macros, thanks. I felt that eval 
> was a bit of a hack, but I had not understood that with-syntax could use 
> `...` to produce repeating patterns that aren't tied to the syntax pattern 
> passed in by `syntax-parse`. I guess I might have been able to infer this 
> from Hendershott's explanation that `with-syntax` can be considered as simply 
> a rearranged `syntax-case`.

`syntax-case`, `with-syntax`, and `syntax-parse` all rely on syntax patterns 
[1] to destructure syntax objects (though `syntax-parse` supports some extra 
options that the others do not [2]).

You can think of syntax patterns as a mini-language for parsing syntax, similar 
to how regular expressions are a mini-language for parsing strings. And, like 
regexps, you often have more than one option for how you break down a syntax 
object.

In the case of a list-shaped syntax object like `(foo bar baz)` you can:

+ match the whole thing with a single-term pattern like `THE-WHOLE-LIST` 
+ match each element with a list pattern like `(FIRST-ELEMENT SECOND-ELEMENT 
THIRD-ELEMENT)`
+ match each element with an ellipsis pattern like `(LIST-ELEMENT ...)` or 
`(FIRST-ELEMENT LIST-ELEMENT ...)`
+ match the head and tail of the list with a dot pattern like `(FIRST-ELEMENT . 
OTHER-ELEMENTS)`

Getting the hang of the ellipsis is the most important skill, I think, because 
it's a very clever operator that lets you write tight syntax templates.

[1] http://docs.racket-lang.org/reference/stx-patterns.html?q=syntax%20pattern
[2] http://docs.racket-lang.org/syntax/stxparse-patterns.html?q=syntax%20pattern



> I'm still curious as to why one can't `eval` a symbol matching the name of a 
> function in a Pollen file though, even when that function is defined in the 
> same file. I will probably never absolutely need to use it that way, but it 
> runs counter to my understanding of Pollen files as full-fledged Racket 
> programs

When you use `eval` in a program (as opposed to in the REPL, which allows more 
casual `eval`ing), you have to specify a namespace for resolving identifiers. 
That's why this code will fail with a "bold: unbound identifier" error:

#lang racket
(require rackunit)
(define (bold . xs) "this is bold")
(check-equal? ((eval 'bold) "hi") "this is bold")

If you just want to use the surrounding namespace, you can use a namespace 
anchor to capture the namespace and pass it to `eval`. That's why this code 
works:

#lang racket
(require rackunit)
(define (bold . xs) "this is bold")
(define-namespace-anchor nsa)
(check-equal? ((eval 'bold (namespace-anchor->namespace nsa)) "hi") "this is 
bold")


Though in general, when you find yourself using `eval` it's a sign that you're 
taking an unnecessary detour.

-- 
You received this message because you are subscribed to the Google Groups 
"Pollen" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to