Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the idiomatic Clojure for "foo = bar || baz"?

Tags:

idioms

clojure

I want to supply a default value which can be overridden. I know I can use a ternary, like this:

(def foo (if (not (nil? bar)) bar baz))

But surely there is a more idiomatic way in Clojure to say "use bar, or baz if bar is nil.

Any suggestions?

like image 337
Josh Glover Avatar asked Apr 14 '12 08:04

Josh Glover


2 Answers

This will assign bar unless it is nil or false, and baz otherwise.

(def foo (or bar baz))

EDIT

If you wish to check for nil precisely, you can slightly optimize your original code, like this:

(def foo (if (nil? bar) baz bar))

I believe, this is the shortest possible way, though not idiomatic.

like image 81
bereal Avatar answered Nov 10 '22 05:11

bereal


Your question doesn't specifically ask about multiple vars, but if you did want this defaulting for more than one var the idiomatic way to do it is to use destructuring on map with :or defaults.

e.g. Take this function that takes a map argument m, the expected map has keys of :a, :b, & :c but if :b and/or :c are not supplied then the defaults are taken from the :or clause

(defn foo [m]
    (let [{:keys [a b c], :or {b 100 c 200}} m]
      (println "a:" a)
      (println "b:" b)
      (println "c:" c)))

user> (foo {:a 1 :b 2})
a: 1   ; no default, use supplied value
b: 2   ; value supplied, default ignored
c: 200 ; no value supplied, use default from :or
nil
like image 45
sw1nn Avatar answered Nov 10 '22 06:11

sw1nn