Live data from Hacker News

NULL: The worst mistake of computer science? (2015)

lucidchart.com

171–180 of 377 posts

Re: NULL: The worst mistake of computer science? (2015)

#171

Yet `Maybe | Option | ...` is not an option (pun intended), as Rich Hickey explains here: https://www.youtube.com/watch?v=YR5WdGrpoug . In effect, his argument is: 1) You have `public X Do(Y y)` changed into `public X Do(Option y)`. This will break your API. 2) You have `public X Do(Y y)` changed into `Option Do(Y y)`. This will break your API. Thus, do not use Option or equivalent in your API's. Only use a language-…

This is a spot where I've got to respectfully disagree with Mr. Hickey.

Changing a public API call that used to guarantee that it returned a value so that it might now return nothing is a breaking change, and, as an API consumer, I want my APIs to broadcast that change loudly. Compiler errors are a good (but not the only) way to do that.

Changing a public API member so that its arguments are now `Maybe[T]` is just silly. There's no need to introduce a breaking change there. Just overload it so that you now have versions that do and do not take the argument and get on with life.

If there's an argument to be made here, it's that statically and dynamically typed languages require different ways of doing things. In a statically typed language, I expect the compiler to keep an eye on a lot of these things, and I'm used to leaning on the compiler to catch things like a function's return value changing. In a dynamic language, I'm not.

I'm also, when working in a dynamic language, used to having to deal with the possibility that, at all times, any variable could contain data of literally any type. Removing nullability there changes the set of possible "this reference does not refer to what I expected" situations from (excuse the hand waving) a set with infinite cardinality to a set whose cardinality is infinity minus 1. If you think of NULL as effectively being a special type with a single value (call it "void"), then eliminating it reduces the number of classes of errors I have to worry about in a dynamic language by 0. I'm hard pressed to see any value there.

Re: NULL: The worst mistake of computer science? (2015)

#172
post #135

Earlier quoted context omitted.

Completely agree, this is CS theory gone off the deep end...

A simple, safe way of tracking nulls like option is "CS theory going off the deep end?" Implicitly allowing all code to return nothing, and manually trying to remember what can return null and what can't, and checking that value, is incredibly error prone. It's really crazy that this has been the dominant way of handling the problem for many decades when their is a dead-simple way of ensuring it can't happen. Null po…

The NULL pointer errors yo're referring to in most cases resource issues. i.e. malloc returning NULL.

This is not the source of the vast majority of pointer errors.

Checking for (and trapping) NULL pointer dereferences is trivial, what is more difficult is the rest of the pointer range that doesn't get checked but is equally invalid, i.e. the other 4-billion (32-bit) possibilities.

Non-NULL-pointer checks are much more important than NULL checks.

The world of pointer issues is very much greater than "ASSERT(ptr!=NULL)".

...and as for correct error-recovery (not error-detection), well, don't get me started.

Re: NULL: The worst mistake of computer science? (2015)

#173

You know who works on a platform with NULL but doesn't have quite so many problems with it? DBAs. There's some need to draw a distinction between the basic idea of NULL, and the way that NULL has been implemented in most high-level programming languages. In most RDBMSes, values can't be null unless you say they are. Sometimes explicitly, as in table definitions, sometimes implicitly, when you select a JOIN type. Eith…

Lua's version of NULL, called nil, once bit me badly due to behavior in a sqlite library. The sqlite library I was using represented SQL NULL as nil, a perfectly reasonable choice. However, in lua there is also a convention to use nil as the end of table sentinel.

This meant innocent looking code using ipairs() would stop iterating on a row of results once it hit a nil, which could occur in anywhere. It meant we were missing data (the lua code uploaded locally collected data to a server) until I figured out the cause and explicitly iterated over the expected size of the table.

Re: NULL: The worst mistake of computer science? (2015)

#174

To someone who has been using Asm and C for decades, these arguments just make no sense. Reading this article reminds me of the arguments against pointers, another thing that's frequently criticised by those who don't actually understand how computers work and try to "solve" problems by merely slathering everything in thicker and thicker layers of leaky abstraction. It's not far from "goto considered harmful" either.…

> ...which immediately tells you to go fix the code.

But which code? The point where you observe the error could be many compilation units away from the code that's broken; it might be in a separate project, or even 3rd-party code.

> ...because it indicates the absence of a value, which is a special case.

Why does it need to be a special case? Is your language incapable of modelling something as simple as "maybe the presence of this kind of value, or maybe absence" with plain old ordinary, userspace values?

> Seriously? A "nullpo crash" is one of the more trivial things to debug, because it's very distinctive and makes it easy to trace the value back (0 stands out; other addresses, not so much.) What's actually hard to debug?

"Tracing the value back" is decidedly nontrivial. And totally unnecessary if you just don't allow yourself to create that kind of value in the first place.

> if you reserve the special null value to indicate absence then you can make do with just one value instead of a pair, of which half the time half of the value is completely useless.

What do you mean? If you're talking semantically, you want absence to be a different kind of thing from a value: it should be treated differently. If you're talking about runtime representation, you can pack an Option into the same space as a known-nonzero type if you want to (Rust does this), but that's an implementation detail.

(Confusing sum types with some kind of pair seems to be a common problem for programmers who haven't used anything but C; sum types are a different kind of thing and it's well worth understanding them in their own right).

> If you can check for absence/null, you will have no problems using Maybe/Optional. If you can't, Maybe/Optional won't help you anyway --- because it's ultimately the same thing, using a value without checking for its absence.

Nonsense on multiple levels. Maybes deliberately don't provide an (idiomatic) way to use them without checking. By having a Maybe type for values that can legitimately be absent, you don't have to permit values that can't be absent to be absent, and therefore you don't have to check most values - rather you handle absence of values that can be absent (the very notion of "checking" comes from a C-oriented way of thinking and isn't the idiomatic way to use maybes/options) and don't need to consider absence for things that can't be absent.

Re: NULL: The worst mistake of computer science? (2015)

#175
post #148

Earlier quoted context omitted.

Nobody does full path coverage, not even NASA.

sqlite is 100% branch test covered https://www.sqlite.org/testing.html

Full path coverage is much more difficult than 100% branch coverage. It's next to impossible in any non trivial codebase that wasn't designed specifically for formal verification.

Re: NULL: The worst mistake of computer science? (2015)

#176

Earlier quoted context omitted.

No, the problem with null is the inability to enforce, at the type level, that a particular value is not null. C simply does not have a type for "guaranteed valid pointer to x".

C allows defining new types though, so it can be done.

Unless I'm misreading OPs statement, it can't be done by defining a new type since C (unlike, say, Ada) doesn't support subrange types.

Re: NULL: The worst mistake of computer science? (2015)

#177

NULL can mean and be different things in different domains of computer science. NULL in the database world isn't the same thing in the programming world. In the programming world, null is a result of the system architecture, systems programming, etc. In SQL, NULL is a result "lack of data". There have been debates on whether there should be different types of NULL. A NULL type for "data that is available but we don't…

All of those different nulls can be solved by not having null as a special case of your database specification, but as a first class type construct.

    data MightBeData a = Yes a | Unavailable | NotApplicable | NeverApplicable

Re: NULL: The worst mistake of computer science? (2015)

#178
post #113

Earlier quoted context omitted.

> ...which immediately tells you to go fix the code. Assuming your code isn't deeply nested. I've seen cases where null was triggered years after code went into production. In that case you have to: A) Assume value isn't null and have more readable code B) Litter the code with null checks. e.g. if (a.getStuff().getValue() == "TEST") becomes if (a != null && a.getStuff() != null && a.getStuff().getValue() == "TEST) Th…

But expanded null checks could be automated by the compiler if so desired right? Without having to change the nature of null into an optional. @MAYBE if(a.getStuff().getValue() == "TEST")

You could check every value for null, sure. But a) why would you want to? (and wouldn't it be bad for performance) and b) how would you handle it? Knowing that a value somewhere in your program was null doesn't really help you any.

Re: NULL: The worst mistake of computer science? (2015)

#179
post #166

Earlier quoted context omitted.

Yes. Most Haskellers will sneer at it, while personally I think it's the right thing to do because it conveys the programmer's ideas about invariants. But syntactically an explicit unwrapping function is still a lot of noise. Simple null pointers as we have in C, with an unmapped segment at address zero so that it throws a segmentation fault, are much better.

I haven't drank all my coffee yet this morning, but are you saying that throwing a segfault can be a good thing? Either you unwrap the Option, or you have to remember to do an manual null check. The second option is more verbose.

> but are you saying that throwing a segfault can be a good thing?

Sure, what's bad about it? A logic bug was detected, so the program should be terminated. Or how do you intend to continue?

Segfault is not so different from what happens if you do "fromJust Nothing" in Haskell or get a NullPointerException in Java. You can even write a handler for the segfault, but I guess that's rarely a good idea.

Re: NULL: The worst mistake of computer science? (2015)

#180

NULL can mean and be different things in different domains of computer science. NULL in the database world isn't the same thing in the programming world. In the programming world, null is a result of the system architecture, systems programming, etc. In SQL, NULL is a result "lack of data". There have been debates on whether there should be different types of NULL. A NULL type for "data that is available but we don't…

All this is true. I immediately took it to mean the Tony Hoare invention of Null. That of the zero memory pointer. Other types of null usually have other names with the notable exception being databases. Also Go uses nil for its null which puzzled me for a while then realized its behaviour is different, you can work with them to a point, e.g. len() or append().
Post reply on HN