9 ms·
I think this would actually be a good addition. I'd like to use 'or' more often, but it always makes me stop to think "Could this get passed a falsey value?" I
by hexane360 4y ago
I think this would actually be a good addition.
I'd like to use 'or' more often, but it always makes me stop to think "Could this get passed a falsey value?" I've seen a lot of Python bugs because people used "x or 5" when they needed the much uglier "5 if x is None else x".
- kazinator 4y agoThat's like Lisp versus Scheme: Lisp: (or x 5) Scheme: (if (null? x) 5 x)
- ok_dad 4y agoMaking anything other than false and none falsy was a mistake; it’s much easier in Lua, for example, there you just say “x or 5” because only nil and false are falsy.
- pansa2 4y ago> Making anything other than false and none falsy was a mistake Yes. That's how you end up with messes like this one: https://lwn.net/Articles/590299/ https://lwn.net/Articles/590299/
- parentheses 4y agoWhattttttttt?!? TIL!
- dtech 4y agoIt's no longer the case, was changed in Python 3.6
- just_boost_it 4y agoWow! That's UTC as well, so where I am it'd be like having an exception for exactly 4pm, it wouldn't even occur to me that it was a zero!
- eru 4y agoFun fact: In most people's Haskell code, you can only use actual Booleans when you need true or false. (As you might expect from a well-disciplined, strongly typed language.) But it's actually really easy to add your own version of eg `if` etc that accept nearly anything, and automatically convert it to True or False. You can do this as a normal library for use in anyone's code.
- mananaysiempre 4y ago... Until you encounter a case where false is a valid value, in which case it’s ~= nil all over again. (Tip: on LuaJIT, x == nil is also true for FFI pointers that happen to be null, which can sometimes force an FFI temporary to be allocated; using type(x) == 'nil' instead may help.) If your language supports a genuine nil and not just a distinguished singleton token (AFAIK only Lua does that consistently, though perhaps “undefined” in non-strict-mode JavaScript also counts), I’m actually leaning towards having operators for dealing with it specifically. Icon does something like that, arguably, although its behaviour (for a “failing” expression that yields no values) is more like a propagating NaN / relational NULL / poison value than a nil. Nix (though it has a faux null like everybody else, as well as a poisoning bottom typical of lazy languages) has a slick partial solution: the field access operator is optionally ternary, expr.name [or expr], so you can write things like systems.flakeExposed or systems.supported.hydra when you want to fall back from one to the other, even though in the fallback case the value of systems.flakeExposed by itself is not nil, it’s an error. (Using or outside of field access is a syntax error, the Boolean operator is spelled ||.)
- ok_dad 4y agoGood point, I still have to check nils on some stuff in Lua, but way way less than I do in my Python day job! I liked Kotlin's null-handling when I worked in it because there were some tools there to handle nulls in a reasonable manner. I think the `something?.prop` would do null checking on `something` before trying to access `prop` and then you could use `?:` (Elvis operator, haha) to check a null and do something if it was null, like `something ?: executed_if_null` and combining those would effectively deal with nulls in a simple and readable way.
- luagjnsj 4y agoLua? You’re kidding right? Lua is so full of gotchas that using it is an exercise in frustration. Tack on LuaJIT, and you’ve got yourself a twelve gauge footgun. Lua is JavaScript-level stupid, minus the useful ecosystem.
- ok_dad 4y agoI like Lua but it’s not my religion or anything. Your use of a throwaway for this signals I probably shouldn’t even engage with you, but why do you hate it so much? I’ve found it to be concise, yet powerful.
- coldtea 4y agoProbably forced to use it for some job plus learning aversion?
- coldtea 4y ago>Lua? You’re kidding right? Lua is so full of gotchas that using it is an exercise in frustration. Which is irrelevant, as the author mentioned a specific feature of Lua that's designed better than Python's same feature, didn't say everything is better in Lua. (Not to mention it's not really true anyway, Lua is fine).
- mixmastamyk 4y ago0 and 1 are iconic for true and false.
- ok_dad 4y agoBecause true and false used to just be 1 and 0, not for any good or thoughtful reasons (much of tech is the way it is because of constraints we no longer have). Today, new languages should avoid pitfalls like truthiness and null values.
- mixmastamyk 4y agoThey are both good and thoughtful, fundamental to how computers work.
- ok_dad 4y agoI guess it wouldn’t matter much without null values, or if they made null values neither true nor false then it might fix it. If not for null then truthiness wouldn’t seem as dangerous to me, I think. As far as zero and one; if you compare equality on a machine you’re generally doing an xor type operation between the two values and if they’re equal you get zero, so that’s flipped. If you’re comparing two numbers it might even result in a ternary value of LT, EQ, and GT. I think true and false are high level programming language or mathematical concepts that don’t map directly to the low level testing results. So, I don’t really consider the traditional “true is 1, false is 0” to be anything more than convenient abstractions in programming based on things that some folks did for convenience at the beginning of software development.
- coldtea 4y ago0 perhaps. 1 doesn't mean much regarding true, if every other non-zero integer is also true.
- mixmastamyk 4y agoBinary numbers and electronics would like a word with you.
- tialaramex 4y agoI'm happy to assert that making anything other than false be false is a mistake. The problem is sum types. Specifically, languages which "don't have" sum types often secretly do have sum types, absolutely everywhere, but no language facilities to deal with them because they "don't have" sum types. That's what the billion dollar mistake is, it's sum types (thing | NULL) with no language facilities. In Python that's (thing | None) but the same penalty accrues. Now, PEP 505 introduces a bunch of actual language facilities. They might be a good idea for Python, other languages successfully did this, but I think as a lesson going forward what we should take away is that we do want Sum types and we should stop pretending we (sometimes?) don't, which means new languages need to be designed for them.
- Tainnor 4y agoIt seems like most more modern languages actually have facilities for expressing proper sum types (even if it is in some languages more verbose than in others). Certainly Kotlin, Swift, Rust, etc. do have them. Even Java, I believe, is planning to add them, though I suspect that many people won't necessarily understand why they're useful even when they land. It's probably helped by functional programming becoming more mainstream and "obvious" sum types needing to be implemented (Optional and Result, mostly).
- Spivak 4y agoI agree. It's absolutely silly that there's nothing to make statements like something['nested']['blah']['bloop'] some.namespace.with['stuff'] safe with None. Your options are using jmespath, your own similar function, or wrap it in a try block. Otherwise the whole syntax is essentially unusable. And because of the quirks of how __getitem__ is evaluated you can't even hack an infinite defaultdict to do the right thing because you can't detect the "last" access to return None so it's only good for when you want to assign to it.
- mjburgess 4y agobut python is simple /s
- baq 4y agosomething.get('nested', {}).get('blah', {}).get('bloop') works just fine but is mighty ugly. ...which is a hint to use something else in this case. dataclass, typed dictionary, deserialize properly, whatever.
- ok_dad 4y agoUltimately there’s some things that are best done with dictionaries, so it would be nice to have a simple tool to do this. Something like ‘x.?y.?z[“something”.?]’ would be nice, where the ? might pass any None through to the end without causing attribute and key errors.