7 ms·
> So, sure, you got rid of null from the language. Does your program handle the case where it was handed a negative number correctly? All positive values? All u
by Dewie 12y ago
> So, sure, you got rid of null from the language. Does your program handle the case where it was handed a negative number correctly? All positive values? All unicode?
Aren't you just moving the goal post? You can play the 'OK so you can eliminate that from the equation, but can you ...' indefinitely. Well, perhaps only until you get to the question of cosmic rays.
> So, fine, we'll make our programs where they handle all cases... Rapid prototyping probably just flew out the window. As did worrying about actual honest to goodness use cases.
The topic is a few special cases, like null, not every conceivable case. If things like null and undefined cause the majority of crashes, and they are simple to handle with a 'proper' language (and they are), then you already have gotten a lot of bang for your buck.
For rapid prototyping: if handling null cases is too much, use a function that unwraps nullable values directly, and if they are null, crashes (and no, this is not the same as a null pointer exception). Then go back and clean up the program when you are not prototyping quite as rapidly anymore.
- taeric 12y agoThat is my point, that this is really just moving some goal posts. So, we know that many programs didn't make it across the line with null as an option. Will they really do much better without it? I'm not convinced it is a sure thing. So, for example, a place where null comes up. When you create a file. Programs that didn't check just threw up on an exception now. It is just as likely that without that option, the code would have just checked for a value, or thrown an error. So... what changed?
- scott_s 12y agoMaybe they don't throw an exception immediately. Maybe that null value gets stored somewhere, and you don't hit it until three hours later, when the system goes to save data to disk. Now your exception gets thrown far away from where the error occurred, both in terms of code and actual time. (For the record, I'm assuming an interface such as: fileOpen -> FileHandle Where the FileHandle object can be null, and it being null is used to indicate that the call to fileOpen failed.)
- taeric 12y agoCouldn't that happen with an optional type, as well? Especially if you let it get inferred. Only when you go to use it would you realize you have to map over the value. And then you are back in the world of messed up.
- scott_s 12y agoIt depends on the language, and the API of the libraries you use. If we have a Haskell-like Maybe type, you should be able to create functions that refuse to take a Maybe. That would force you to determine soon after the fileOpen call: did it succeed or not? To be clear, this would involve the static type system for your language forcing certain things to happen, or not compiling. The sequence: 1. fileOpen returned a Maybe<FileObject> 2. You want to store the FileObject somewhere, and it expects an actual FileObject. 3. Maybe<FileObject> is not itself a FileObject, so you have to figure out: is it Nothing, or a FileObject? 4. You have to handle the Nothing case (language forces you to, even if you do nothing about it - you explicitly decided to do nothing). 5. If it is indeed a FileObject, you store it for later use, and you are guaranteed it is, indeed, a FileObject.
- taeric 12y agoRight. This makes sense. Though, I would have thought the lazy semantics of Haskel would trip you up here. Ultimately doesn't matter, my main argument is that I see people proliferate "Optional" values all over the bloody place. So, I would expect to find that they just put the optional ref up and used it later when necessary. And I should note that I don't necessarily dislike the optional types and such. I just also don't have the major disdain for null that the internet seems to send through a massive echo chamber nightly.
- wtetzner 12y agoThe problem with languages that have null is that they don't let you write non-nullable types. That means any variable at any time could be null. You don't have the option of guaranteeing something won't be null.
- chongli 12y agoThat is my point, that this is really just moving some goal posts. Yes, they will. You could make the same statement about crime: "We'll never get rid of all crime, so why bother having police at all? Having police is just moving some goal posts." Does that make it clear enough how silly this sort of reasoning is?
- Dewie 12y agoThat kind of reasoning seems to be known as the perfect solution fallacy.
- taeric 12y agoNote that I am not actively arguing against adding some of these solutions. I just don't have an idyllic vision of a world where we have better software simply because null doesn't exist. Specifically, I'm not convinced "all of the null pointer bugs" would have simply been erased and replaced with good working software. Rather, I tend to think they would have just been replaced with similar bugs.
- Dewie 12y ago> Specifically, I'm not convinced "all of the null pointer bugs" would have simply been erased and replaced with good working software. Rather, I tend to think they would have just been replaced with similar bugs. This reads to me like eliminating null pointer bugs would just create a void that something else would fill? I don't see how that would work, at all. Is eliminating a null pointer exception going to introduce a divide by zero exception/bug? Is it going to introduce program logic bug? ... If you're thinking about unwrapping a nullable value and throwing an exception if it really is null; I don't think of that as a conceptual null pointer exception, at least not in the usual sense. It's a deliberate decision along the lines of "I know [because of the control flow up to this point] that this value can not be null" or "if it is null, just throw an exception". It is NOT "this value can never be null... I think... well let's check the documentation, OK I'll assume that it isn't being misleading (documentation can easily 'lie' about a value being null in a nullable-by-default language, since non-nullable is not expressible in the language). In a language with nullable-always, you can always pass a value (probably reference, but still) as null. In a language with explicitly nullable types, this is impossible. That's why unwrap functions throw an exception if the value is null: there is no other way to handle that case in a typed manner (well, I guess you also could loop forever...). In a nullable-by-default language? It is always fine to pass null. And it will not necessarily fail if a null is passed that shouldn't have been passed: it will only error when the reference is (tried to be) dereferenced.
- Dewie 12y ago> So, for example, a place where null comes up. When you create a file. Programs that didn't check just threw up on an exception now. It is just as likely that without that option, the code would have just checked for a value, or thrown an error. So... what changed? What changed is that you are unable to propagate a null-that-shouldn't-be-null value to the rest of the program. If you have a value V that might be null, and you are supposed to return that value itself (not wrapped in an Option or anything like that, ie a 'nullable type'), all you can really do is: actually return a value of type V, or throw an exception. That's it! (To throw an exception is also something that can be done at any time in most statically typed languages, for any reason whatsoever. Throwing exceptions is usually not a question of the type correctness of a program (maybe it is in the case of checked exceptions?).) You can not give null as an output: you are supposed to give V as the output, not a nullable V. So you know exactly where in your program you are doing something 'unsafely', i.e. where you are not rigorously handling every case of the value of some type. Though 'unsafe' is a bit misleading, since you may very well intend to just throw an exception in the (perhaps deliberately possible) case that a value is null.