I am a newbie for clojure and a little bit confused with the use of contains?
form to different data structures.
The result of applying contains
to a vector, set or a map is just what I expect, it tests if a key (or index) is present in the collection. But when it comes to a list, such as
(def li '(1 2 3)) ; define a list
(contains? li 1) ; returns false !!??
I know it is NOT that straightforward to understand how contains?
works with a list, since its document says the implementation operates in a constant or log time. So here it doesnt really make sense to test in less than log time if 1 is in a list or its index range.
But in that case why doesnt it just raise an exception like when applying assoc
with a list. In the assoc
case the philosophy is the same - the assoc
should NOT be applied to a list since it doesnt support fast-enough random-access of its elements.
I feel it inconvenient because a lot of forms in clojure return a general collection as the results, such as (vals a-map)
, so to test if an element exists in the value set of a map, different methods give different results - but to me they are just the different ways of saying the SAME thing.
(def a-map {:one 1 :two 2})
(contains? (vals a-map) 1) ; returns false!!
(contains? (set (vals a-map)) 1); returns true!!
So after the long explanation, my question is - what is the rational behind this design? How should we say it natively when we want to test if an element is in a value set of a map in clojure, i.e., more importantly, how should I convince myself so that I will not make stupid bugs in practice? Thanks!