I have a clojure map. Name it opts. I know 2 ways to get values from this map such that if there is no key get some default value:
(let [opts {}
title-1 (or (:title opts) "Default title")
title-2 (:title opts "Default title")]
(println title-1 title-2))
I saw some libraries (quil, incanter) use first approach with or. It seems to me that second approach is more concise and cleaner. Is there advantages in the first approach?
Disadvantage of using (or (:title opts) "Default value") is that we cannot pass false and nil as values anymore, default value is always used in this case.
A crucial difference between
(or (:key hash) default)and(:key hash default)is the fact that the former evaluatesdefaultonly if it is necessary. In the latter case it is always evaluated. Therefore you should useorif an evaluation ofdefaultis expensive.Another difference becomes apparent when your hash contains values which are false in a boolean context. In cases of such values
(or (:key hash) default)will be evaluated todefaultinstead offalseornilwhich you expect. In contrast to theorexpression,(:key hash default)will yield correct results. As a side note, think twice before storingnilas values in a hash.Fine, those were the important differences. Now let’s move to minor ones.
is expanded by the reader to
Arguably, it is less efficient than to simply evaluate
Of course without any benchmarks it is hard to estimate the difference is speed, however I believe that it should be marginal.
On the other hand, at first glance
(or (:key hash) :default)seems to be easier to understand for someone not used to the(:key hash :default)idiom. Consider programmers coming from other languages. In Ruby for instance the typical approach to handling a non existant element of a hash isHence, the first expression might be easier to parse by humans not accustomed to certain Clojure’s idioms.