> - use contains? instead of using sets as functions,
[snip]
> An example. To understand this piece of code you need to know that possible-states is a set:
(when (possible-states state)
... )
> By contrast, to understand following code you don’t need any context:
(when (contains? possible-states state)
... )
I disagree. In the first example, it's clear from context that possible-states is a function (to be precise, an object that implements IFn) that returns a truthy or falsy value depending on the value of state; the name possible-states suggests it's checking that the value of state is valid, according to some criteria.
To determine what those criteria are, you'd have to look at the definition of possible-states: but that would also be true even if you used the more verbose contains? construct.
By not using contains?, you also retain the option to replace possible-states with an actual function, should you later discover you need further validation or processing not possible with a simple set.
For example, if state is a text string, and you find out further down the line that sometimes it's in the wrong case or has unwanted leading or trailing white space, you can replace
(def possible-states #{"foo" "bar" "baz"})
with
(defn possible-states [state]
(->> state
clojure.string/trim
clojure.string/lower-case
#{"foo" "bar" "baz"}))
without needing to change code elsewhere.
Even if you don't feel that this flexibility is worth the ambiguity, contains? offers little comfort, as it can take many things other than a set:
(contains? #{"foo"} "foo") ; true
(contains? {"foo" 1} "foo") ; true ("foo" is a key of the map)
(contains? {:bar "foo"} "foo") ; false ("foo" is a value but not a key)
(contains? ["foo" "bar"] 1) ; true (vectors are keyed by integers)
(contains? '("foo" "bar") 1) ; false (but lists aren't)
(contains? "foo" 1) ; true (but strings are)
> - use contains? instead of using sets as functions,
[snip]
> An example. To understand this piece of code you need to know that possible-states is a set:
> By contrast, to understand following code you don’t need any context: I disagree. In the first example, it's clear from context that possible-states is a function (to be precise, an object that implements IFn) that returns a truthy or falsy value depending on the value of state; the name possible-states suggests it's checking that the value of state is valid, according to some criteria.To determine what those criteria are, you'd have to look at the definition of possible-states: but that would also be true even if you used the more verbose contains? construct.
By not using contains?, you also retain the option to replace possible-states with an actual function, should you later discover you need further validation or processing not possible with a simple set.
For example, if state is a text string, and you find out further down the line that sometimes it's in the wrong case or has unwanted leading or trailing white space, you can replace
with without needing to change code elsewhere.Even if you don't feel that this flexibility is worth the ambiguity, contains? offers little comfort, as it can take many things other than a set: