On Thu, Sep 13, 2012 at 12:02 AM, Matthew O. Smith <m0sm...@gmail.com> wrote: > > On Wednesday, September 12, 2012 8:03:58 AM UTC-6, jarppe wrote: >> >> I have a function that generatwed unique ID's, something like this: >> >> (def k (atom 0)) >> (defn generate-id [] (swap! k inc)) >> >> and I try to use it like this: >> >> {(generate-id) "foo" >> (generate-id) "bar"} >> >> How ever, I get >> >> IllegalArgumentException Duplicate key: (generate-id) >> clojure.lang.PersistentArrayMap.createWithCheck (PersistentArrayMap.java:70) >> >> >> This works as expected. >> >> (let [id1 (generate-id) >> id2 (generate-id)] >> {id1 "foo" id2 "bar}) >> >> Should I be able to call generate-id in map literal? >> >> -- >> -jarppe >> > > This also fails: > > { (gensym) "foo" > (gensym) "bar" } > > From the stack trace I get it looks like the reader macro that handles map > literals is only looking at the function call, not the result of the > function call. This makes sense as it is the reader, not the evaluator.
Figuring out what is and what isn't a compile time constant is tricky, huh? *headdesk*... But, what's really going on is that you're running into a consequence of how Clojure and other lisps work. The first thing they do is 'read', which means converting the text of the program into data structures. Then it evaluates those data structures as a program. Then it prints the result. (REPL) So, here it's building a map which contains the key "a list containing the symbol gensym" twice. Clearly, that can't work. It's only *after* the reader has done its work, and returned the map that compilation/evaluation take place. Consider a simpler example with a vector, which doesn't produce an error since it's allowed to have duplicates: (def k (atom 0)) (defn generate-id [] (swap! k inc)) Now when the reader reads this: [(generate-id) (generate-id)] It returns a vector containing two lists, each of which contains the symbol generate-id. It's only when this data structure is evaluated, that the functions generate-id get called. In some order. I wouldn't rely on getting [1 2] and not [2 1]. // Ben -- 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