Truthiness tricks

Posted: August 20, 2012 in Uncategorized
Tags: , , ,

In Clojure, any value can be considered as “truthy” or “falsey” for the purposes of a conditional expression.

The rule is very simple:

  • nil and false  – are “falsey”
  • everything else – is considered “truthy”

This rule may seem strange if you come from a world with a strictly defined boolean type (like Java). But it turns out that it enables some neat tricks in Clojure code that are well worth knowing.

1. Acting on non-empty collections

Often you want to perform some actions on a sequence of items in a collection if and only if the collection is non-empty. The important thing to note is that (seq coll) returns nil if a collection is empty, so you can use it directly with if-let as follows:

(if-let [s (seq coll)]
  (do-something-with-sequence s)
  empty-result)

2. Providing default values

Often you want to provide a default value if one is not provided. Since non-presence is generally defined as nil, you can use the short-circuiting or macro to fill in a default value.

(or value default-value)

If a value is provided it will be used directly. If value is nil then the or operator will proceed to use the default value

3. Cond handling of :else

Since the keyword :else is truthy, it can be used as a catch-all at the end of a cond expression:

(cond 
  (condition-1? args) 
    "Result 1"
  (condition-2? args) 
    "Result 2"
  :else 
    "Default result")
Advertisements
Comments
  1. xvzf says:

    Is the first one in some way better than:

    (if (seq coll)
    (do-something-with-collection coll)
    empty-result)

    ?

    • mikera7 says:

      It’s pretty much equivalent – though quite often you want to operate on the seq rather than the collection so it is convenient to bind the result with if-let. There is also potentially a (very slight) performance advantage in doing this since it may avoid the need for seq to be called twice.

  2. Fun! It’s nice to note that Ruby shares the same definition of truthiness, which is handy as e.g. Array#index returning 0 (the object requested was found in the first position) is still truthy.

    • mikera7 says:

      Indeed – it’s very helpful that non-nil means “found”! You just have to watch out for the gotcha cases where nil is an actual value in vectors / sequences etc. :-)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s