On Fri, Jun 5, 2015 at 4:53 AM, Jordan Schatz <jor...@noionlabs.com> wrote:

> Hello!
>
> So here is a short example:
>
>
> -----------------------------------------------------------------------------------------------------------------
> ;; Story:
> ;; I have an EDN data structure from an external API
> ;; I extract several patterns of records from it.
> ;; I would like to treat the patterns as data, pass them around, modify
> them etc.
>
> (def sample-data {:tracks {:items [1 2 3 4 5]}})
> (def pattern [:tracks :items count])
>
> ;; Thread first -> should be what I need, but I need to "apply" it...
> (apply -> (cons sample-data pattern)) ;; Can't take value of a macro:
> #'clojure.core/->
>
> ;; So make a new macro that reuses ->
> (defmacro get->> [data pattern]
>   `(-> ~data ~@pattern))
>
>
;; This raises an error
> (macroexpand-1 '(get->> sample-data pattern))
> ;; Don't know how to create ISeq from: clojure.lang.Symbol
>
>
This raises an error because it's attempting to treat "pattern" as a
sequence for the purposes of splicing it.

If you put a println in your macro definition:

(defmacro get->> [data pattern]
  (println "pattern:" pattern) ;; run at expansion time
  `(-> ~data ~@pattern))

you'll be able to see what the macro is working with as it tries to do the
expansion. It gets the literal tokens you pass in, *not* what those values
evaluate to (which is why you can do control-flow manipulation in a macro),
so here it's getting just the symbol "pattern".


> ;; But this works correctly
> (macroexpand-1 '(get->> sample-data [:tracks :items count]))
> ;; As does
> (get->> sample-data [:tracks :items count]) ; => 5
>

Here you're passing in a sequence, not a symbol, so the macro expansion can
splice correctly.

In this case, fwiw, you can just do this:

user=> (def pattern [:tracks :items count])
#'user/pattern
user=> (def sample-data {:tracks {:items [1 2 3 4 5]}})
#'user/sample-data
user=> (defn get->> [data fs]
  #_=>   (reduce #(%2 %1) data fs))
#'user/get->>
user=> (get->> sample-data pattern)
5

-- 
Ben Wolfson
"Human kind has used its intelligence to vary the flavour of drinks, which
may be sweet, aromatic, fermented or spirit-based. ... Family and social
life also offer numerous other occasions to consume drinks for pleasure."
[Larousse, "Drink" entry]

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to