5 ms·
Clojure: Truthy and Falsey
- andrewvc 16y agoErrrm, I'm going to bitch about this. This is a great article to stumble across in google. But front page material?
- doorhammer 16y agoIt's a concise tid-bit on an intellectually interesting, semi-esoteric, but still useful language. I think it qualifies pretty well, personally.
- adobriyan 16y agoConcise? All it could say is that "nil" in boolean context is equivalent to false, but nothing else is.
- ScottBurson 16y agoBy 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 16y agoI'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.
- riffraff 16y agoFWIW 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 16y agoLisp: nil and the empty list '() are equivalent and are falsey. C: 0 is falsey, the rest not.
- riffraff 16y agowhat 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 16y agoYes, 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 ...
- weavejester 16y agoPossibly Scheme, where #f and '() are the only non-true values, and these are equivalent to false and nil in Ruby. I'm not sure if there are any earlier examples of this.
- kanak 16y agoActually in Scheme, #f is the only false value. (e.g. the documentation for "if" in racket [1] says: "If it produces any value other than #f, then then-expr is evaluated, and its results are the result for the if form. Otherwise, else-expr is evaluated, and its results are the result for the if form. The then-expr and else-expr are in tail position with respect to the if form.") [1] http://docs.racket-lang.org/reference/if.html?q=if&q=false#(form._((quote._~23~25kernel)._if) http://docs.racket-lang.org/reference/if.html?q=if&q=fal...)
- devin 16y agoAt least for the examples provided in the article true/false behaves like Ruby.
- route66 16y agoWhile 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
- jerf 16y agoThis 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.
- dmoney 16y agoI remember reading about the interface for making a class act as a boolean the last time I messed with Python. I thought it was neat that you could make any object act as a boolean, function, whatever. I can't seem to find the docs for it though.
- danielparks 16y agoI believe this is what you're talking about: http://docs.python.org/py3k/reference/datamodel.html#object.__bool__ http://docs.python.org/py3k/reference/datamodel.html#object....
- dmoney 16y agoThat's the one. Thanks.
- kbd 16y agoI like Python's approach. Anything null, zero, or "empty" is false (+ False of course), but it won't do any type conversion, so you don't get cases like "0" being true. Edit: though I wish the standard library used its configurable truthiness a little more. I'd like a closed filehandle to evaluate to False, for instance.
- 16y ago