On Jul 13, 2018, at 2:01 PM, Joel Dueck <dueck...@gmail.com> wrote:I get this for a doc → '(body (p () "Hello, " (em () "world") "!"))How can I then re-run this x-expression through all of my tag functions?I.e., so that in the above example I get instead, '(body (p () "Hello," (my-em () "--Never a dull moment!--" "world") "!"))
Or in the definitions window, you have to include a namespace:(require pollen/top)(define-namespace-anchor nsa)(eval '(body (p "Hello " (em "world") "!")) (namespace-anchor->namespace nsa))However, even with `pollen/top` to catch undefined tags, an X-expression can still have elements that don't make sense in terms of `eval` — for instance (), which will throw an error, or an attribute list like ((foo "bar")).
I think you'd end up having to pick through the x-expr to find the tags you want to re-process, but that just sounds like a `decode` operation.
On Jul 14, 2018, at 8:20 AM, Joel Dueck <dueck...@gmail.com> wrote:Maybe what I’m really looking for is a decode (like scribble's?) that can take a tagged X-expression just apply any existing tag functions to it and its elements.
On Jul 14, 2018, at 4:37 PM, Matthew Butterick <m...@mbtype.com> wrote:On Jul 14, 2018, at 8:20 AM, Joel Dueck <dueck...@gmail.com> wrote:Maybe what I’m really looking for is a decode (like scribble's?) that can take a tagged X-expression just apply any existing tag functions to it and its elements.AFAICT this does what you want. It descends the xexpr and sniffs the tags to see if they have bindings (using `identifier-binding`). If not, it subs in a `default-tag-function` for the tag. It also handles the special case of avoiding ().
(define (reapply-tags stx)(syntax-case stx ()[((ATTR-KEY ATTR-VAL) ...) #''((ATTR-KEY ATTR-VAL) ...)][(TAG . XS) (with-syntax* ([XS (map reapply-tags (syntax->list #'XS))][TAG-FUNC (if (and (symbol? (syntax->datum #'TAG)) (identifier-binding #'TAG))#'TAG#'(default-tag-function 'TAG))])#'(TAG-FUNC . XS))][OTHER #'OTHER]))
On Jul 15, 2018, at 8:16 AM, Joel Dueck <dueck...@gmail.com> wrote:Just tried it out, and this does exactly what I was struggling to imagine. The major “aha” for me in understanding what you’ve done here is that syntax-case can take a simple datum as well as a full-blown syntax object—I did not know that! Which in turn means syntax-case can be useful at run time as well as at compile time, which to me is kind of huge.
On Jul 15, 2018, at 10:03 AM, Matthew Butterick <m...@mbtype.com> wrote:
On Jul 15, 2018, at 8:16 AM, Joel Dueck <dueck...@gmail.com> wrote:Just tried it out, and this does exactly what I was struggling to imagine. The major “aha” for me in understanding what you’ve done here is that syntax-case can take a simple datum as well as a full-blown syntax object—I did not know that! Which in turn means syntax-case can be useful at run time as well as at compile time, which to me is kind of huge.
On Jul 15, 2018, at 7:03 PM, Matthew Butterick <m...@mbtype.com> wrote:One more (perhaps) simplifying idea — the bound-identifier sniffing is exactly what `#%top` from `pollen/top` does. So we could also wrap a `let-syntax` around the x-expression to rebind `#%top` to the special `pollen/top` version (using `make-rename-transformer`, which just means "treat the syntax on the left as if it were the syntax on the right")
On Jul 18, 2018, at 8:19 AM, Joel Dueck <dueck...@gmail.com> wrote:Reading ‘Beautiful Racket’ really helped me get what #%top was all about. As I mentioned, I was originally trying to attach pollen/top to a parameterized current-namespace for use with eval.
I guess I wasn't fully digesting what things (specifically attribute lists and empty lists) need to look like before eval takes a crack at them, because eval will try to evaluate inner expressions before outer ones.