5 ms·
Now that I've worked professionally in a whole bunch of languages that attempt to delete implicit nullability out of existence, I long for it's return. Option m
by zzbzq 6y ago
Now that I've worked professionally in a whole bunch of languages that attempt to delete implicit nullability out of existence, I long for it's return. Option monads are a two billion dollar mistake.
The fact is when you're working with any data coming from any other system, the data is or will become null, somehow, some way, and your program code which treats this as impossible is just literally wrong in a way that is complete jibberish. Additionally, programmers don't want to pass huge lists of parameters to every function, but instead bundle things into structs to be easily passed around, however this model makes it impossible to treat a value as Optional at an early part of the callstack and Non-optional later in the callstack after it's been checked and verified. So you either pass everything as a separate parameter, copy things into different structs all over the place, or just make the value Optional everywhere, deleting the usefulness of making Optionals.... Optional. Just let it be null everywhere, and if it's null somewhere it shouldn't be, the program throws an error--like it should, because there's an error.
Actually, javascript is the only language that has it right. Not only can anything be null, anything can be undefined, (which isn't even remotely similar and anyone who doesn't understand why doesn't belong in the conversation,) AND values you don't know about can exist.
- novok 6y ago> Just let it be null everywhere, and if it's null somewhere it shouldn't be, the program throws an error--like it should, because there's an error. Optionals everywhere makes that explicit, vs. something implicit that you can forget.
- cies 6y ago> Actually, javascript is the only language that has it right. Not only can anything be null, anything can be undefined I think they are very similar in that there are now 2 nully things to guard for. Option types suck in Java as they were tagged on later. Maybe in Haskell, or even nicer, Maybe in Elm is were the party's at. It is build in at the center of the language. And getting a value (v) from a list by an index should give you a "Maybe v", as you could be out of bounds. That's the strong typing that basically keeps me safe when viciously attacking a code base I have not touched for some time (or is not written by me to begin with).
- mc10 6y agoI don’t see how any of the points you made is a great defense of keeping nulls around. > The fact is when you're working with any data coming from any other system, the data is or will become null, somehow, some way, and your program code which treats this as impossible is just literally wrong in a way that is complete jibberish. Your program and the other program has to agree on some protocol. That can have optionality built into it if you expect them to not send certain fields. If that protocol is violated then either you made a mistake (protocol was not accurate) or they did (sent poorly formatted data); either way, you can handle the error without nulls. > however this model makes it impossible to treat a value as Optional at an early part of the callstack and Non-optional later in the callstack after it's been checked and verified. I think what’s being described here could be easily encoded as variants/sum types, or you could have functions that give optional fields default values. Without a specific example it’s hard to discuss what you’re really trying to say.
- pjungwir 6y agoI've been experimenting with Rust's Rocket webapp framework, and as much as I like it, I agree it's very annoying how a struct can't permit nulls in one context but not another. I wish there were an easy solution that didn't require near-identical struct definitions and excess copying memory from one place to another.
- wtetzner 6y agoSeems like a good opportunity for a custom derive.
- sdfsfsf3kjdf 6y agoIn Rust you can solve this via derive or a macro. Typescript's conditional types and the associated utility types are a nice solution to this problem as well. You can do a ton with Partial, Required, Pick, Omit, Exclude etc.
- pjungwir 6y agoThank you both for these tips. I'll see what I can figure out! :-)
- cactus2093 6y ago> copy things into different structs all over the place Sanitizing input is a very common pattern and I don't see why this option is such a deal breaker. And it would normally just be needed at the system boundary, rather than "all over the place". Or, you share types between different services using something like grpc or thrift, and then you really can trust that the values coming in are not going to be null. I definitely don't agree that settling for implicit null is the best option.
- acoard 6y ago>Actually, javascript is the only language that has it right. Not only can anything be null, anything can be undefined, (which isn't even remotely similar and anyone who doesn't understand why doesn't belong in the conversation,) AND values you don't know about can exist. If you mean `unknown`, that's a TypeScript thing.[0] And personally I love working on a code-base and with coders that differentiate between null and unknown. But there's no denying it's a footgun and many get no value besides bugs from these two. It's kind of similar to how JS gets boolean comparisons weird, which is worked-around by convention [0] https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-0.html#new-unknown-top-type https://www.typescriptlang.org/docs/handbook/release-notes/t...
- pkulak 6y ago> and your program code which treats this as impossible is just literally wrong That's fine though. The program that treats it as possible but fails to handle it in every possible spot is wrong too, but wrong in a completely unpredictable place, way and even number of times. It's freeing to start out assuming "title" can never be null. If it is, you get a quick failure at the very edge of your application where the data comes in. You make it nullable, and the compiler tells you all the places where you made the wrong assumption and now need a fix. Or even better yet, you give it a default value, even an empty string, and nothing more is required.
- beoh 6y agoThis is not an issue with Option at all. When you receive data from an external system, you should always parse it before making assumptions. By parsing I don't mean read property x as string, but make it a CustomerId for example, considering your constraints before accepting the value.
- slammin 6y ago> The fact is when you're working with any data coming from any other system, the data is or will become null, somehow, some way, and your program code which treats this as impossible is just literally wrong in a way that is complete jibberish. i don't really understand this part. you can't treat it as impossible, because `Optional[T]` is a different type than `T`. anywhere you try to use an `Optional[T]` as a `T` is a type error. i think you're saying "there are some cases where `T` can also be null that are now unaccounted for," which i don't think is really relevant. that's more a matter of API design; a hypothetical function that receives data from a server should return an `Optional[T]`. one that treats the operation as infallible would throw an exception just like in an implicitly null language, right?
- alisonatwork 6y agoI kind of agree, when working on a large team. Adding optional arguments everywhere is a bit like declaring checked exceptions everywhere. It's true that optionals make the code more explicit, and they force developers to handle every situation, but in the end you still need developers who actually care about writing readable and maintainable code for it to be a net gain. Something I have come across a fair bit is code where too many values are declared as optional, so the developers try to build an elegant solution by mapping functions over these optional values, returning a default at the end. If there is a value, then the expected code path gets called, else it just silently skips the rest of the code and returns back up to the top layer. This causes a similar issue to what can happen with promises - you lose the context of where the first "error" happened. This could be avoided by eagerly throwing an exception in the first absent case, but that takes us back to where we started with null. I think the "best practice" way of using optional values is to get buy-in from all the developers on the project that basically nothing should be optional, ever. The goal, then, is to explicitly throw an exception (or return an error) at the very top level and ensure that only actual values enter into the main part of the project's code. But enforcing that is more of a management problem than a technical problem.
- dragonwriter 6y ago> Additionally, programmers don't want to pass huge lists of parameters to every function, but instead bundle things into structs to be easily passed around, however this model makes it impossible to treat a value as Optional at an early part of the callstack and Non-optional later in the callstack after it's been checked and verified. No, it doesn't; there's a couple easy, obvious ways to do that depending on how you get the data components and how far it is useful to pass them as a group without ensuring none are null. It's not even mildly challenging, much less impossible.