
Clojure: Truthy and Falsey - DanielRibeiro
http://blog.jayfields.com/2011/02/clojure-truthy-and-falsey.html?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+jayfields%2FmjKQ+%28Jay+Fields+Thoughts%29
======
ScottBurson
By way of contrast: a friend of mine was once working on a contract job in
Visual Basic. One day he edited an "if" statement which basically said (I
don't know VB syntax, but this will give you the idea):

    
    
      (0) if foo() then do_something() else do_something_else()
    

It turned out that it was unnecessary to do anything in the "then" branch:

    
    
      (1) if foo() then no_op else do_something_else()
    

My friend, quite naturally, changed that to this:

    
    
      (2) if not foo() then do_something_else()
    

After several hours of frustration, my friend finally realized that the
transformation from (1) to (2) is not valid in Visual Basic. How can this be?
As I recall, there is some false value in VB such that its negation is also
false.

This is the kind of hell languages create when they try to be helpful by
having lots of different false values (0, the empty string, the empty list,
and of course "false") and at the same time have lots of implicit conversions.

So, be glad that Clojure has only two "falsey" values.

~~~
snprbob86
I'm not sure what particular issue your friend ran into, but here's one
strange fact about booleans in pre-.net versions of Visual Basic:

True is defined as -1.

This allowed there to be a single, type-agnostic "not" operator. There was no
distinction between binary and logical negation.

C, of course, has ~ and ! operators and uses 0 and non-zero for truthiness.
When calling into non VB "Classic" modules, the mapping of boolean values can
be unnecessarily confusing.

------
jerf
This strikes me as a worst-of-both-worlds approach. I've come to prefer
explicit booleans vs. C-style truthiness, but if you're going to limit
falseness so strictly you ought to make it a type error to have anything but a
Boolean in the if statement. Even a run-time type error would be fine, Erlang
mostly works that way ("true and 0" results in a bad argument exception,
unfortunately the "if" construct is less picky). Making an interface such that
any object can declare a reasonable definition of truthy and therefore the if
can take anything seems like another valid choice, I've had good success with
that in Python. This intermediate approach seems to combine the badness of
both approaches, not the goodness.

~~~
weavejester
Clojure isn't unusual in how it handles nil and false. Scheme, Ruby and Lua
all use the same system, and I'm sure they're not the only ones.

I actually prefer this system in dynamically typed languages, as it seems to
get the right balance between simplicity and practicality.

A system that just uses explicit true and false values would result in more
redundancy in conditionals, e.g.

    
    
        (if (not (nil? x)) ...)
    

Compared to:

    
    
        (if x ...)
    

On the other hand, a boolean system that's any more complex tends to be hard
to remember. For instance, I could never remember whether a blank string was
considered true or false in Python, and I certainly can't remember all of the
Javascript edge conditions relating to booleans.

~~~
jerf
While you can construct ugly-looking scenarios, ugly conditionals comes up way
less often that you would think in languages that have a strict requirement
for booleans in if statements. Usually they also have pattern matching;
extensive use of "if" in a pattern matching language is a code smell.

Your example is also sort of a degenerate case for Lisp syntax. (Hey, it can't
all be upside with no downside.) In languages that actually have a syntax it
is, again, not something that is anywhere near as bad as you might think. I
generally only notice when I actually want to have 0 be the false case and
there is something to be said for putting the == 0 there anyhow; someone once
said explicit is better than implicit.

~~~
weavejester
Statically typed languages generally need to have strict requirements for
booleans, unless you have a weak type system like C. But for dynamically typed
languages, the only one that I can think of with strict booleans is Erlang.
Are you aware of any others?

I'm also not convinced this is a special case for Lisp syntax. In Ruby, one
often finds code like:

    
    
        hash[key] ||= value
        find_resource(key) or not_found
    

And even if it is a special case, aren't we talking about how suitable this is
for Clojure specifically?

~~~
jerf
"...type system..."

"Weak" and "strong" type system are meaningless terms if you don't define them
for your local usage. As I suggested, I don't care if the check occurs at
runtime or compile time.

"And even if it is a special case, aren't we talking about how suitable this
is for Clojure specifically?"

You may be. I'm talking about it in general.

The reason I brought up "degenerate case of the lisp syntax", since apparently
nobody had a clue :-/, is that you complained about the "redunduncy" in

    
    
        (if (not (nil? x)) ...)
    

and what I meant is that that may be how Clojure spells it, but Clojure is
being very verbose here. On the macro scale you don't pay much for Lisp's
syntax with the parentheses because other languages need punctuation too and
it tends to just come out in the wash, but sometimes you do get hammered on
the micro scale. (And sometimes Lisp says something concisely few other
languages can. But you never get pure win in the real world.) If you spell it
something more like

    
    
        if !nil(x): ...
    

there's much less redundancy. Assuming you mean "verbosity" by that, which I'm
not sure of, since I don't see anything redundant in the Clojure example
except too many parentheses but generally we don't call that redundancy in a
Lisp program.

Again, _I'm_ talking about the principles of managing conditionals in general,
not just Clojure. And again, across the several languages I've used that
require booleans and only booleans it just doesn't come up as an actual
problem that often to actually check for the relevant falsity if you need to.
Besides, the real problem is that there is no universal idea of truthiness and
falsyness, you _should_ have to say exactly which one you are using. A lot of
bad mistakes get made precisely because people don't think about it. How many
times have I seen conditionals break because they got passed an empty string
when they meant to check for nil/NULL/None/whatever and do something
frightfully wrong as a result? I've long since lost count.

~~~
weavejester
Even in a language that has a relatively rich syntax, like Ruby, treating nil
as false can make code more concise and understandable. For example:

    
    
        hash[key] = value if !hash[key].nil?
    

Can be written as:

    
    
        hash[key] ||= value
    

And:

    
    
        response = find_resource(key)
        response.nil? ? response : not_found
    

Can be written as:

    
    
        find_resource(key) or not_found
    

I also can't think of any instance where a function has used an empty string
to denote a failure condition. In a language that treats nil as being false,
generally functions are quite careful as to the value they return.

------
andrewvc
Errrm, I'm going to bitch about this. This is a great article to stumble
across in google. But front page material?

~~~
doorhammer
It's a concise tid-bit on an intellectually interesting, semi-esoteric, but
still useful language. I think it qualifies pretty well, personally.

~~~
adobriyan
Concise? All it could say is that "nil" in boolean context is equivalent to
false, but nothing else is.

------
riffraff
FWIW this is the same in ruby (nil and false are the only non-true values) but
I believe this comes from some older language, does anyone knows which one?

~~~
route66
Lisp: nil and the empty list '() are equivalent and are falsey. C: 0 is
falsey, the rest not.

~~~
riffraff
what i meant is that there are two falsey values, in lisp (I assume CL) I
believe there is no different "false" value which is not equal to nil/empty
list, I think?

~~~
route66
Yes, nil and '() are the same. Alas I'm of no more help for your quest. Also
SQL with false and NULL does not it the picture as NULL means unknown and is
treated as such , not as false ...

------
devin
At least for the examples provided in the article true/false behaves like
Ruby.

~~~
route66
While we're at it... this piece of ruby is about operator precedences. Not
strictly in the truthy falsey department but still slightly in topic. The
participants are 1, nil, or, ||, assignment and puts ...

    
    
      puts (i = nil || 1) => 1
      puts  i => 1
      puts (i = nil or 1) => 1
      puts  i => nil
      puts  i = nil || 1  => 1
      puts  i => 1
      puts  i = nil or 1  => nil
      puts  i => nil

