Kevin Kostlan
Kevin Kostlan

Reputation: 3519

clojure generating a vector vs a map literal expression

This seems paradoxical:

(def foo ["some" "list" "of" "strings"])

`[ ~@(apply concat (map (fn [a] [a (symbol a)]) foo)) ]
; ["some" some "list" list "of" of "strings" strings]

; Changing only the outer [] into {} 
`{ ~@(apply concat (map (fn [a] [a (symbol a)]) foo)) }
; RuntimeException Map literal must contain an even number of forms

; However, this works:
`{"some" some "list" list "of" of "strings" strings}
; {"list" clojure.core/list, "of" user/of, "strings" user/strings, "some" clojure.core/some}

Whats going on?

Upvotes: 2

Views: 269

Answers (2)

Alan Thompson
Alan Thompson

Reputation: 29958

Unless you are writing a macro, it may be easiest to say:

(into {} (map (fn [a] [a (symbol a)]) foo))
;=> {"some" some, "list" list, "of" of, "strings" strings}

Upvotes: 0

Leon Grapenthin
Leon Grapenthin

Reputation: 9266

The exception is triggered by the reader because it can't read a literal map with one element which is your unsplice form before evaluation.

Workaround:

`{~@(apply concat (map (fn [a] [a (symbol a)]) foo)) ~@[]} 

Upvotes: 2

Related Questions