4 ms·
Null definitely has a meaning, as missing value, encoded often by Optional types. What many of the programming languages got wrong is that is NOT a subtype of a
by GolDDranks 8y ago
Null definitely has a meaning, as missing value, encoded often by Optional types. What many of the programming languages got wrong is that is NOT a subtype of all of the other types. (It's not a bottom type.) Subtypes are required to fulfill the same interface as their supertypes but null fails at this because it doesn't have the same minimum set of fields, it doesn't respond to the same methods etc.
The only way I can think of making this sound and well-typed, is that null supports any fields and any methods, returning always null. This doesn't fit well how many of the languages actually do.
- deleted 8y ago[deleted]
- jakear 8y agoThat is what Objective C provides (the author here calls it “viral null”). It works, but I think a better approach is the Swift way. In this a nullable type is precisely an Optional, as you stated, and they don’t respond to anything besides “isNull?” and “get” (the latter crashing the program if the former returns true). This way when you need to say “I might not know”, your type signature will express that, and the type system will guarantee everyone abides by it.
- hboon 8y agoThat Objective-C behaviour is called Message eating nil (or null in other languages).
- greiskul 8y agoAgreed, the swift way is the correct way. For cases where you do want the Objective C behavior, you can just use the ?. operator. This way you get compile times guarantees by the type system, and where you actually want to use the "viral null" you can, and it's very explicit for people reading the code what it's doing.
- 0xcde4c3db 8y ago> The only way I can think of making this sound and well-typed, is that null supports any fields and any methods, returning always null. That sounds a lot like NaN, which is often conspicuously absent from diatribes against NULL.
- jerf 8y agoNumeric computation, which I distinguish from simple addition or something to place windows to describe something where you are doing "serious math" of some sort, is too exceptional to be a useful contribution to this discussion, I think. It's a very rigorous mathematical space, but it's not the mathematical space most of the rest of our code is in, which is generally simpler. Another place where I consider math code an exception is that I'm find with numeric operator overloading, but generally think it's a bad idea for "normal programming". Being able to multiply a 5x3 matrix by a 3x8 matrix makes sense. Being able to scrape a web page by multiplying a string by a web scraper does not. "Normal programming" lacks the structure necessary to lay down such a rigorous stack on top of it. (And it's not just because of "lazy programmers"; it truly lacks the requisite structure. Even a very Haskell-y Haskell program in the "normal programming" space doesn't have something that looks like a complicated numeric stack... this is where the applicatives and monads and profunctors come in. Well-structured "normal programming", even very "mathematical" "normal programming", is not structured like heavily-numeric code. That's a sort of "complicated stack" of its own, but even then I'd characterize those abstractions as having a structure where you are almost always building properties up as you go "up" the stack. Contrast with the numeric tower where as you build up, you are generally losing properties; numbers are fully ordered, until you add complex numbers. Complex numbers multiply commutatively, until they become quaternions. Any number can be multiplied by any other until the "numbers" become matrices. Etc. The numeric tower builds in the opposite "direction" from the "normal programming" tower. There's a sense in which you could turn it upside down, but it's not one most people are even going to wrap their head around, let alone want to use.)
- barrkel 8y ago"The only good NaN is a signalling NaN." Delphi's RTL set the FPU flags to default to signalling NaNs, causing some havoc when linked against C and C++ libraries (usually gaming libraries) that assumed otherwise. You usually don't want a divide by zero poisoning your data, for the same reasons you don't want unnoticed nulls infecting your data structures. Exceptions can be made for scoped blocks of code, but it's not a good default.
- simias 8y agoI completely agree. In particular the problem of having NULL as a bottom type is that many languages (like C) don't have a way to express that a certain type is not nullable in the type system. The nullable aspect is effectively dynamically typed, so you either add NULL checks every time you dereference a pointer or you have to make sure by yourself that a given pointer can never be NULL at a given position in code. For this reason in general when I receive pointers from third party libraries in C I generally always have an `assert(ptr != NULL)` just in case. In C++ references fill that role but it's not very difficult to get a reference to a NULL or stray pointer by mistake, unless you make sure to forbid raw pointers altogether. NULL effectively ruins your type system by making all your reference types de-facto optional. TFA points that out but concludes by saying that "Either approach will work", that's a bit curt I think. It's like saying that if the seatbelt doesn't stop you the windshield will, "either approach will work".
- barrkel 8y agoInfectious nulls mean that the source of your nullness propagates through your data graph, following data flow, until you finally notice some time later, some way downstream, whereupon it's usually a problem. You generally want problems to be noticed close to their origin, and not hide latently in lists and maps, waiting to be tripped over.
- GolDDranks 8y agoI agree. I advocate for Optional types. What I meant to argue is that it's possible to have a type-safe, sound null-everywhere. Not desirable, though.
- latte 8y ago> The only way I can think of making this sound and well-typed, is that null supports any fields and any methods, returning always null. This doesn't fit well how many of the languages actually do. This is what Clojure does to an extent - in Clojure, it is called nil-punning and implicitly handling nil values by using the functions that return null on null input makes the code concise and is considered idiomatic practice. In other Lisp dialects, this is even more common, as far as I know.
- deleted 8y ago[deleted]