4 ms·
The trouble is that `if(value)` or `value && ..` ends up getting used as an idiomatic shorthand for "if value is present" even in languages (such as javascript
by SEMW 7y ago
The trouble is that `if(value)` or `value && ..` ends up getting used as an idiomatic shorthand for "if value is present" even in languages (such as javascript and python) where 0 is falsey. Because most of the time it works, so people do it. And then inevitably get bugs when the value happens to be 0.
This can get increasingly hard to reason about the more datatypes you add which interpret 0-ish values as falsey -- as there's always the temptation to do, for 'consistency' with integer truthiness, e.g. https://lwn.net/Articles/590299/ https://lwn.net/Articles/590299/ about the python behaviour of dates being falsey in the first second after midnight.
If `null` and `false` are the only falsey values (ala clojure, ruby, elixir etc), that's a rule that's really easy to internalise and reason about, so you never have to worry about things like whether your data type might be falsey in the first second after midnight (and also `if(values)` is actually a correct idiom).
- np_tedious 7y agoHere's another prime python example. The response object in the requests library has a truthiness equivalent to request success. Can easily trip you to with `res and res.content` https://github.com/psf/requests/blob/master/requests/models.py#L668 https://github.com/psf/requests/blob/master/requests/models.... https://stackoverflow.com/questions/48347290/why-does-requests-response-object-bool-check-for-200-status-400 https://stackoverflow.com/questions/48347290/why-does-reques...
- raverbashing 7y agoI disagree with this rationale (not with your specific explanation, with the rationale) You can make your types be interpreted as True/False (in Python at lest) as you want. The issue here is that a date should never be "false". > that's a rule that's really easy to internalise and reason about Python's rule is simple, it's JS that came up with confusing rules. The issue here are types that are inconsistently false (and I disagree with the Python module on that)
- hibbelig 7y ago> Python's rule is simple, it's JS that came up with confusing rules. I think Perl was there first: in addition to 0 and "" being falsy in Perl, "0" is also falsy. Then there is this nifty Perl value "0 but true": if you stick it into a condition, it will evaluate to true, but if you do math with it, it behaves like the number zero.
- mikeash 7y ago"The following values are considered false: * None * False * zero of any numeric type, for example, 0, 0L, 0.0, 0j. * any empty sequence, for example, '', (), []. * any empty mapping, for example, {}. * instances of user-defined classes, if the class defines a __nonzero__() or __len__() method, when that method returns the integer zero or bool value False." This really does not strike me as being simple. I personally don't find these shortcuts to be worthwhile. The best approach is that boolean is a separate type, true is true, false is false, and any attempt to use any other type as the predicate of a control flow statement is a (preferably compile-time) error. Writing `if x != 0` is not a large burden.
- raverbashing 7y ago> I personally don't find these shortcuts to be worthwhile They are, because they are the difference between driving with the parking brake on or not. Other languages don't have this so that's why people might not see the value in it first. > Writing `if x != 0` is not a large burden If you're comparing what can only be an int value, then it's not a burden. When your variable can assume multiple values, explicitly comparing it with multiple possibilities is a burden: Examples: - Your variable is optional and/or is a sequence that might be empty - You're using .get() in a dictionary One of the signs someone is unfamiliar with Python is doing multiple comparisons when only `if x:` would suffice
- mikeash 7y agoI've worked in a lot of different languages, from ones that work the way I prefer all the way to Python-style languages where anything is a predicate and there are a bunch of semi-arbitrary rules about what qualifies as "false." This isn't a lack of familiarity talking. Regarding your examples, having an optional sequence is probably not the correct move anyway. Is there actually a semantic difference between no sequence and an empty sequence? If not, the variable should be non-optional. If so, then glossing over those differences by writing `if x` to implicitly check both conditions is unclear. Not sure what you're referring to with get() in a dictionary. I understand that good Python style is considered to be one where you take advantage of the language's notion of truthiness, but I disagree with its whole approach.
- cheez 7y agoBeen bitten many times by 0 being falsey. Only a problem in languages with loose typing and nulls though.
- jancsika 7y ago> as an idiomatic shorthand Suppose a fantasy language has an ergonomic syntax to check existence. It returns a boolean. Additionally, implicit conversions to boolean for objects in the language is randomized for each runtime. Isn't such a weirdo language still preferable to implicit conversions, even when compared to a language where "null" and "false" are the only falsey values? Because even in those languages the new user must internalize the simple rule and learn from context how it works and why it can be used with impunity. Whereas with my weirdo language the syntax explicitly conveys to all classes of user what is happening in the code. Furthermore, I'd bet that even in your preferred languages there are less readable idioms that ninjas can leverage in the implicit conversions. In my weirdo language the randomized conversions would thwart the ninjas and keep the entire class of users free from their unreadable tyranny.
- a_lieb 7y agoDue to exactly this issue, an increasing number of languages have an operator just for "if exists and not null": the null coalescing operator[0]. What "exists" means depends on the language; it can be as loose as checking if the variable has ever been set (PHP), but generally has nothing to do with truthiness/falsiness status. [0] https://en.wikipedia.org/wiki/Null_coalescing_operator https://en.wikipedia.org/wiki/Null_coalescing_operator