Live data from Hacker News

Null References: The Billion Dollar Mistake

infoq.com

71–80 of 158 posts

Re: Null References: The Billion Dollar Mistake

#71

"Making everything a reference: The Billion Dollar Mistake" is the talk I want to see

You may be interested in http://canonical.org/~kragen/memory-models then. I don't think it's necessarily a mistake but it's definitely taken for granted far too much.

Re: Null References: The Billion Dollar Mistake

#72

"Making everything a reference: The Billion Dollar Mistake" is the talk I want to see

Everything in Python is a reference, and there's no null pointer issues.

If you've never seen this message, you haven't been programming in Python for very long:

    AttributeError: 'NoneType' object has no attribute 'foo'
Not to mention UnboundLocalError and cases of AttributeError that stem from trying to use attributes before they've been initialized. Some of these have slightly better ergonomics than Java’s pernicious null initialization, for example by crashing your program earlier, but the upshot is that everything you do in Java that will crash with a NullPointerException will also still crash your program in Python.

Oh, I guess except for shadowing an outer-scope variable with a local that you never initialize. That just gives you the wrong answer in Python, because there exists no local without an initialization. But it's a pretty marginal case.

Re: Null References: The Billion Dollar Mistake

#73
post #3

This comes up again and again in one form or the other, yet new languages still seem to be making the same mistake. Of all languages I've touched, Rust seems to be the only one that mostly circumvents this problem. Are there other good examples?

The reason they come up again and again is that it's hard to design an imperative language without them (try, assuming you want to provide generic user-defined data structures that allow for cycles). As a result, calling them a "mistake" is reasonably dishonest, as it implies there was an obvious, better alternative.

Can you give some more details on what the design problem is here?

It seems to me that nullable references are isomorphic to having an option type with non-nullable references, but prevent accidental unchecked dereference. What are some of the difficulties that you'd expect to come up if you took an imperative language with nullable references and replaced them with options of non-nullable references?

Re: Null References: The Billion Dollar Mistake

#74
post #69

Earlier quoted context omitted.

This comment would be much improved with a list of those languages. Kotlin and Swift come to mind, what are others?

If we're limiting ourselves only to new languages, then nulls are statically excluded not only by Kotlin and Apple’s imitation of it, Swift, but also by F#, Agda, Idris, Elm, and (sort of) Scala. But the zozbot didn't seem to be talking only about new languages, so Haskell, Miranda, Clean, ML, SML, Caml, Caml-Light, and OCaml are also fair game. (It wouldn't be hard to list another dozen in that vein.) Moreover I thi…

Good list.

I've found the consequences of a nil type are less severe in dynamic languages, where all variables have the Any type, since nil is just one of the options one needs to account for.

Static languages where everything is nullable are reneging on the promise; you say something is a String but that just means Option, and it saps a lot of the reasoning power which static typing should give.

Re: Null References: The Billion Dollar Mistake

#75
post #25

Earlier quoted context omitted.

Plus also doesn’t the stack need to be small to fit into the CPU cache?

There is absolutely no requirement from the hardware that the stack be any particular size

If you start allocating multi-kilobyte objects in your stack frames, they are not going to fit into L1.

Re: Null References: The Billion Dollar Mistake

#76
post #69

Earlier quoted context omitted.

If we're limiting ourselves only to new languages, then nulls are statically excluded not only by Kotlin and Apple’s imitation of it, Swift, but also by F#, Agda, Idris, Elm, and (sort of) Scala. But the zozbot didn't seem to be talking only about new languages, so Haskell, Miranda, Clean, ML, SML, Caml, Caml-Light, and OCaml are also fair game. (It wouldn't be hard to list another dozen in that vein.) Moreover I thi…

Good list. I've found the consequences of a nil type are less severe in dynamic languages, where all variables have the Any type, since nil is just one of the options one needs to account for. Static languages where everything is nullable are reneging on the promise; you say something is a String but that just means Option , and it saps a lot of the reasoning power which static typing should give.

Concur.

Re: Null References: The Billion Dollar Mistake

#77
Out of all possible gotchas in programming languages I still find null pointers the easiest one to discover and fix. You directly see when and where it happens, and the fix is usally straightforward.

Compared to that invalid pointers (stale references) are a lot more painful, since programs might continue to work for a while. Managed languages do at least prevent those.

Multithreading issues are imho the biggest pain points, since they are introduced so easily and often go unnoticed for a long time. The amount of languages that prevent those is unfortunately not that big (Rust plus pure singlethreaded languages like JS plus pure functional languages).

Re: Null References: The Billion Dollar Mistake

#78
post #34

Earlier quoted context omitted.

> Rust seems to be the only one that mostly circumvents this problem. The Rust hype is getting ridiculous here. There are plenty of languages with non-nullable references as first-class, and optionals for the nullable case. (...And I say this as a Rust fan myself, for what it's worth.)

Imho, Rust is an awkward language because it positions itself as a systems language but it makes low-level stuff more difficult (there's even a book teaching how to implement doubly linked lists in Rust [1]), hence prone to mistakes. At the same time, people are using Rust to build non-systems programs, where other languages would be more appropriate (e.g. those with garbage collectors). I don't think it is a good id…

Rust is a force for good but I think Andrei Alexandrescu was right when he said Rust feels like it "skipped leg day" (in the sense that it has its party piece and not much else) - from the perspective of the arch metaprogrammer himself at least.

Rust is obviously good for safety but for everything else (to me at least) it seems unidiomatic and ugly, admittedlty I've never really sunk my teeth into it (I've read a fair amount into the theory behind the safety features but never done a proper project)

Re: Null References: The Billion Dollar Mistake

#79

Earlier quoted context omitted.

With stack allocation you then encounter problems with object lifetime. Rust solves this problem by binding references to scope, and Go solves this by invisibility changing an allocation to the heap (and uses ref-counting? I think?). I wish C had a feature that would let you allocate something on the stack and then return to the parent stack frame without popping the stack-pointer - that would be handy for self-conta…

Regardless of whether it's on the stack or heap the point still stands. If all your objects are randomly allocated then an array is just references to those objects and will start out null. If you're using value types then your array of objects will never be null (empty instead) and you will benefit from CPU caching the data.

Fortunately, objects in modern GC are almost guaranteed to be layed out sequentially in memory of they are allocated sequentially or if they are referenced sequentially and a GC pass has run, because of the way copying GCs work. The much bigger problem is the memory and CPU overhead of storing pointers and following them, though that should be mitigated somewhat by the prefetcher.

Re: Null References: The Billion Dollar Mistake

#80

Out of all possible gotchas in programming languages I still find null pointers the easiest one to discover and fix. You directly see when and where it happens, and the fix is usally straightforward. Compared to that invalid pointers (stale references) are a lot more painful, since programs might continue to work for a while. Managed languages do at least prevent those. Multithreading issues are imho the biggest pain…

> You directly see when and where it happens, and the fix is usally straightforward.

This is not true in most dynamic languages, especially ones where I/O is not typed. You have to be extremely dilligent about verifying input. JavaScript comes to mind.

Post reply on HN