8 ms·
The framing of the original question is ill-posed. It says that C treats 0 as falsey in a boolean context, but early versions of C did not have booleans. Thinki
by lmkg 4y ago
The framing of the original question is ill-posed. It says that C treats 0 as falsey in a boolean context, but early versions of C did not have booleans. Thinking that C treats 0 as false is looking at it from a perspective deeply influenced by modern languages. The IF statement in C tests for zero, just like many assembly languages. The idea of "false" is a higher-level abstraction that was successfully back-ported to C.
My own thoughts is that what values should be falsey in a language depends on what your language is supposed to manipulate. C is a language designed for mucking about with machine data: bits, numbers, and pointers. And those are the data types that can be sensibly used in a boolean context in C. The Lisp family is designed for processing lists (it's in the name), and lists are the only type that some Lisps let be falsey (although many don't even allow that). It seems sensible to me that a fundamentally object-oriented language would treat a null object as falsey, or the empty string in a language for text processing. I dislike it when multi-paradigm languages have many falsey values.
- mikepurvis 4y agoIn my opinion if a language has False/None/Null/Nil as first class values, then the only sane path is for everything else to be True: the number zero, NaN, empty string, empty list, empty set, etc. All of those should evaluate to True.
- zasdffaa 4y agoYeah... ISWYM and it sounds good, then again it confuses the boolean concept with the list concept, the set concept etc. etc. etc. Doesn't mean it isn't useful, and maybe there's very little risk of mistakes but still.
- mikepurvis 4y agoIf every list or set or dict evaluates to true, even empty ones, what is there to confuse? Or is the argument that non-bool types shouldn't coerce to a bool at all, so that you're force to always explicitly call a bool-returning method, like "if my_list.empty() then" type of thing? In any case, the next thread down is making the same point, and specifically calling out languages that do exactly this and get it right: Clojure, Lua, Ruby, and others.
- zasdffaa 4y agoIt's a theoretical challenge to your idea, that's all. In fact IIRC from the distant past that lambda calculus is where this behaviour comes from so it is in fact theoretically well-founded. I withdraw my doubts.
- anamax 4y ago> if a language has False/None/Null/Nil as first class values, then the only sane path is for everything else to be True I very much disagree. Every type should have a false value. Note that False is a bool while None/Null are pointers/references and Nil is Lisp's empty list. (Python's empty list is [] and it also has empty tuples.) Why should those types and no others have a false?
- sph 4y agoNot necessarily every type, but just those that obviously look false: False, 0, null. Empty string iff it's a very high level language. Empty list iff it's a lisp. But better yet, `if` should only accept a boolean expression. Passing a string to `if` should be a type error.
- Espressosaurus 4y ago0 shouldn't be false. 0 compared to something can be false. Null isn't false. Null compared to something can be false. The entire concept of "falsey" makes my teeth ache. Non-boolean expressions in a boolean context is asking for a runtime error.
- anamax 4y ago> Non-boolean expressions in a boolean context is asking for a runtime error. And yet, it doesn't, in strongly-typed languages that define which values are "false" and "true" for types such as strings, sets, dictionaries, and yes, even numbers.
- anamax 4y agoIt's unclear why empty strings or lists should be considered false yet it's somehow evil for empty sets to be considered false. The purpose of type checking is to help people write correct programs. It's unclear that requiring "if {string}.isempty() ..." does that better than "if {string} ..." in a strongly-typed language.
- joe-collins 4y ago
- Someone 4y agoThat opinion rules out many strongly typed languages where booleans are strictly separate from other types, just as, in such languages, floats are separate from doubles, and any assignment of a value of type T1 to a variable of type T2, or passing a variable of type T3 to a function taking an argument of type T4 requires explicit conversion, even if that conversion could be lossless. For example, in Swift let f: Float = 1.0 let d: Double = f is invalid code. You have to write let f: Float = 1.0 let d: Double = Double(f) In such languages, true is true, false is false, and all other values are neither true nor false. I think that, certainly for booleans, that’s the sanest choice.
- mlazos 4y agoI tend to think the only sane path is a type error and anything else is arbitrary. It isn’t that hard to have converters which make sense in a standard library. isNone, isNil ..
- zasdffaa 4y ago> The idea of "false" is a higher-level abstraction that was successfully back-ported to C. You're pushing 'back-ported' a bit much. It's just a blatant equivalence that 0 is a conceptual false, when a zero caused a particular behaviour if used in an if/while/etc. 'false' as a concept has always been in C afaik whether it had that name (via #DEFINE) or not.