5 ms·
>But making zero elements evaluate to falsy is problematic. "" would be falsy as well then. In Python 0, [], and "" are all falsy. In my experience it's only b
by bitcurious 7y ago
>But making zero elements evaluate to falsy is problematic. "" would be falsy as well then.
In Python 0, [], and "" are all falsy. In my experience it's only been useful - why do you consider it problematic?
- jarfil 7y agoThe problem lies in what question does it answer: * Does it exist (true) or not (false)? * Does it have a defined value (true) or not (false)? * Is it non-zero (true) or not non-zero (false)? * Does it have non-zero length (true) or not non-zero length (false)? I think using zero as a magic number is less consistent than not using any magic numbers at all. If you want to check the length, or whether something equals zero, just check for that, not for whether it's "truthy".
- bb88 7y agoSo here's an example where it matters in python: def f_to_c(deg_f=None): if deg_f: return (deg_f - 32) * 5 / 9 else: raise TypeError('Invalid value passed in') The problem is that it works for all numbers, except 0, because 0 is falsy, and will return a TypeError exception. There are lots of different solutions to this issue, but I wouldn't write the pedantic if statements. I would just do this: def f_to_c(deg_f): return (deg_f - 32) * 5 / 9 And let python raise the TypeError.
- taeric 7y agoYeah, I don't get it. Your solution is better in near every way. The if statement should be doing a type check, not a value check. And it is redundant since the math will do it. Right?
- bb88 7y agoRight, because the minus operator will look for the __sub__ attribute.
- fiddlerwoaroof 7y agoA better example would be something like: def my_calc(x, scale = None): if not scale: scale = 1 return (x + 4) * scale where the (x + 4) bit stands for some interesting calculation whose result is being scaled: this code makes it unclear whether or not scale == 0 is intentionally conflated with scale == None or whether this is a programming error. It would be better to do this, if this is intentional: def my_calc(x, scale = None): if scale == 0 or scale is None: scale = 1 return (x + 4) * scale Or, if it's unintentional, one should have written: def my_calc(x, scale = None): if scale is None: scale = 1 return (x + 4) * scale
- taeric 7y agoWhy not just default scale to 1? I get that you might want to know if it was supplied or if it is the default, and common lisp has a way to do that. It is very niche to need, thought. That all said, I think this is just suffering the fate if anything with examples. I accept there are places where zero as false can be annoying.
- bb88 7y agoYes. Or set scale to 0 or something. Generally speaking we're creating contrived examples because in all fairness, I've only seen this once I can remember in the last 5 years of writing business logic in python. Usually language purists would prefer us to be explicit in our languages. And type safety is the best thing since sliced bread. But effectively that's why python has taken off. Types do matter, but for most things they don't Lots of good software has been written using python.
- pierrec 7y agoThey're saying that it's problematic because it's inconsistent. So that problem doesn't exist in Python.
- fiddlerwoaroof 7y agoWhen I wrote python regularly, I’d always use explicit equality checks like foo == false or foo is None after being bitten by unexpected falsy values.
- ledauphin 7y agoFor what it's worth, I am generally in agreement with you, so you're not alone. I do think it would've been better to have 0, specifically, not be falsy - unlike the other cases, 0 is not 'the absence of any actual data' but rather a special case of the data. I assume Python stuck with tradition on this one mostly because it is so tightly tied to C and UNIX-style scripting that changing it would've been confusing for most early users.
- fulafel 7y agoI'm not sure Python would do that today without backwards compatibility reasons. Python's True and False are late additions to the language, before that 0 and 1 served their functions. I think this is one of the symptoms of the changing priority of simplicity in Python language design, at some point the design decision about 0/1 for simplicity became dated enough to change it despite being a big change and requiring backwards compatibility hacks with 0/1.