5 ms·
A good, illustrative case for why falsiness, of any kind, leads to disaster. Boolean operations should require explicit mapping to boolean types. Make the inten
by mc4ndr3 4y ago
A good, illustrative case for why falsiness, of any kind, leads to disaster. Boolean operations should require explicit mapping to boolean types. Make the intent clear every time, instead of requiring the programmer to memorize umpteen different rules.
- tmm84 4y agoI agree that using a boolean or calling a function that returns a boolean is the best case for readable code. I think that familiarity with a language leads to using the falsy logic rules without explicit boolean logic. When script programming falsy logic can be broad and useful but for software that needs to be robust explicit boolean logic can not be beat.
- dgb23 4y agoThere's no disaster as far as I know. This is a old, well understood Lisp idiom. Clojure specifically has a ton of macros, functions and patterns around this concept, such as if-let, when-let, some->, looking up stuff in a map, just to name a few, much this goes under the umbrella of "nil-punning" and "logically true values" etc. Caveats and boundaries: It is typically clear whether something can return a nil or accepts a nil value one versus when it doesn't. A good example would be string methods and other Java interop, where you will make sure you don't pass in a nil value, you are crossing language boundaries here so to speak. Another boundary of nil usage would be sequences, which will not evaluate to falsy, even if empty, so you explicitly would call seq or empty? on them. The bottom line is that you are very aware of nil values and their falsiness in Clojure and that you program with them rather than against them.
- ramesh31 4y ago>A good, illustrative case for why falsiness, of any kind, leads to disaster. Yup. It took a decade of ES updates to overcome these issues with Javascript. The falsy zero in JS has probably created more bugs in aggregate than any other language feature in history.
- samatman 4y agoHow about two rules, or if you absolutely insist, three? "Values are falsey if they are `nil` or `false`, otherwise they are truthy". It's hard for me to map this rule to 'disaster', either in principle or in practice. It means that `if number then` does what you expect, if you expect that maybe number exists, maybe it doesn't.
- boardwaalk 4y agoThe “umpteen rules”, I presume, are the ones for all the languages you know and use, not just Clojure or what have you. I would wager most people don’t work in a single language bubble. It’s a bit optimistic that we’d ever have most languages working under the same rules though, no matter how sane it is and how dubious the value of falseyness (and the terseness you can get from it) is.
- samatman 4y agoSome people do work in a language bubble, probably even most developers by weight are producing exclusively one of Java, C#, and JavaScript, but let's leave that aside. What's the absolute minimum level of mental imposition on an if statement? I'd say it's "this must take a boolean", but that implies compile-time types, and I'm not here to litigate the mere existence of dynamic languages today. I would argue that the rule I sketched above is both the clearest and simplest rule which is compatible with a dynamic language. It imposes the least amount of mental burden in understanding or writing code.
- JamesSwift 4y agoExpanding "boolean-ness" and treating more things as expressions lets ruby give you more readable code. e.g. if user = db.query(id) user.update(...) end and user = db.query(id) || raise "UserNotFound"
- deleted 4y ago[deleted]
- toomanybeersies 4y agoFYI your second example isn't actually valid ruby. You need to either wrap the arg for raise in parens: user = db.query(id) || raise("UserNotFound") Or use the `or` keyword: user = db.query(id) or raise "UserNotFound"
- JamesSwift 4y agoAh, thank you. I knew about the issue, but I actually changed it from an initial `or` because I had them mixed up. Instead of changing the boolean rules, they should definitely address the different precedence rules for boolean operators : )