4 ms·
The distinction here is that those implementations aren't a type system, they are types in the existing c++/java type system. In many languages that support Op
by fwip 8y ago
The distinction here is that those implementations aren't a type system, they are types in the existing c++/java type system.
In many languages that support Optional types as first-class citizens, it is a compile-time error to ignore the fact that it may be null/none. Your code must deal with this, and you won't have any surprise exceptions, even if you are lazy.
- Rebelgecko 8y agoWhich languages? In the languages that I'm somewhat familiar that support Optionals (Kotlin and Swift) you can still get NPEs, there's just some nice syntax that makes it harder to do accidentally (e.g. by using !! or ! on a null/nil optional)
- UK-Al05 8y agoMost ML(Ocaml) languages I use will tell you if you haven't handled all the cases.
- jayshua 8y agoElm is an example of a language that literally can not produce NPEs. I use Rust on a daily basis and while it "technically" can produce one, I've never seen one.
- ajanuary 8y agoThe idiomatic way to use optional types is pattern matching (e.g. when in kotlin, switch in Swift). These pattern matching constructs tend to have a requirement that your cases are exhaustive. This makes it impossible to miss the None case. However, they also tend to provide escape hatches for getting at the type directly, which defeats that and will still let you NPE.
- timw4mail 8y agoRust does not allow null values without resorting to unsafe code.
- cesarb 8y agoTechnically, it does: std::ptr::null and std::ptr::null_mut are not unsafe. (Of course, you cannot try to dereference the resulting pointer without using unsafe.)
- bunderbunder 8y agoTo that end, I find that the value of optional types depends heavily on the language they're being used in. Might as well beat up on Java: One of the best belly laughs I had during a debugging session was tracing a `NullPointerException` to the source, and finding that the reference was to an `Optional<T>` that was being used to handle a value that might not be present. Of course, the null reference here was to the `Optional<T>` itself. There are also also some ergonomic issues. Obvious ones like the lack of pattern matching making them a bit more verbose to work with, of course. But also deeper, more annoying problems, such as Java's standard library lacking a really well-thought-out equivalent to the various abstractions on sequences that are standard in functional languages, and, by extension, functions for operating on them. Though it does have plenty of bits and bobs that were diligently cargo culted on without really capturing the essence of what this stuff is supposed to be about. So, for example, while (at least in Java 8) `Optional<T>` does have its own method called `flatMap`, it doesn't implement `Stream<T>` or offer an easy method for producing a stream. So the idiom of flatmapping a function that returns `Optional<T>` over a sequence to yield a (possibly shorter) sequence of items for which the function returned something, which is so simple and readable in an ML-like language, becomes hopelessly verbose, awkward, and even error-prone in Java. (Also, Java Streams are, by design, not referentially transparent, so much so that they cannot be made to behave in a referentially transparent way. Which is a total tangent from what I'm talking about here, but does at least give another angle from which to see the depths to which Java misses the point on these sorts of things, and possibly isn't even able to catch it.) All of which kind of leaves me thinking, "When in Rome, do as the Romans do." Yeah, in hindsight, the ALGOL family of languages' standard method of dealing with cases where a value might not be available is hopelessly fraught with problems. But importing a second approach from a separate language family that split off about 40 years back and started going in a whole different semantic direction into an existing language that already has its own ways of doing things doesn't appreciably improve that situation. It just introduces two competing ways of doing things that end up interacting poorly with each other. So, to wrap it up: I'm inclined to say that keeping null and just improving the error message when it happens unexpectedly probably is the best band-aid for this problem.