~ # clojure
Clojure 1.10.1
user=> #{(symbol ":?") (keyword "?")}
#{:? :?}
user=> (map type #{(symbol ":?") (keyword "?")})
(clojure.lang.Symbol clojure.lang.Keyword)
user=> (apply = #{(symbol ":?") (keyword "?")})
false
user=>
They certainly can, if you make them look like each other. I doubt anyone will be surprised if they hear the suggestion “don’t do that – that way lies madness”.
That arose at work in a large map composed from a spreadsheet,
and puzzled someone who is (quickly) learning Clojure.
Calling symbol
or keyword
on arbitrary strings can easily lead to things like this. If you have a choice, considering keeping them as strings instead. Strings can be used as keys in Clojure maps, just fine, and round-trip well between writing them out as data, and reading them back, using the appropriate Clojure code for printing them (which I don’t keep off the top of my header, but might be pr
).
Historical context: This question was raised in 2008 and cataloged in the Clojure Jira as issue No.17: https://clojure.atlassian.net/browse/CLJ-17 “Validate in (keyword s) and (symbol s)”. In the end, a way was not found to do it without causing slowdowns disproportionate to the benefit.
Thanks guys.
I don’t think this is a problem to be fixed.
It’s just a thing that beginners can stumble on.
Here’s a related thing that I remember having lost a few hours struggling with in the early days.
(keyword nil "b/c")
The example might look silly but again it came from mechanically constructing keywords from data. It took me a while to work out why the result wouldn’t equal :b/c
that I typed in
Thanks. I have not debugged that one … yet.
This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.