Live data from Hacker News

What is wrong with NULL

lucidchart.com

121–130 of 147 posts

Re: What is wrong with NULL

#121
post #97

Here is what is wrong with Option. option.ifPresent(x -> System.out.println(x)); So instead of just checking to see if it is NULL you want me to create an instance of a specialized class that holds my variable that has a method that acts like an "if" statement that I need to pass an anonymous function to that receives the value I already have? Why not just do: x && System.out.println(x) or: System.out.println(x) if x…

> it is extremely rare for experienced programmers working in dynamic languages to have bugs related to type

That's a good one. I really needed that ;)

Re: What is wrong with NULL

#122

No mention of SQL, where NULL's behavior in the standard can lead to some quirky behavior that I've seen bite back in poorly designed systems. I've included a brief illustrative example. The expectation is that the UNION of two WHERE clauses, one using IN and the other using NOT IN should be equivalent to the same SELECT without any WHERE: WITH NullCTE AS (SELECT a.* FROM (VALUES (NULL), (1), (2)) a (Number) ) ,One A…

I thought of including SQL NULL. Unfortunately, I felt I would do such a poor job of enumerating the problems or describing them in a somewhat comprehensive way, I didn't even try.

Re: What is wrong with NULL

#123
post #7

Earlier quoted context omitted.

Rust, too! Edit: Btw, I disagree with how the article categorizes Rust in comparison to Haskell. It shows that Rust has std::ptr::null, but neglects the fact that Haskell has Foreign.Ptr.nullPtr. Either both should be "5 stars" or both should be "4 stars".

Author here. I didn't know that about Haskell. Admittedly, the "rating" is pretty rough, maybe even a bad idea. I've seen std::ptr::null more than I ever have Foreign.Ptr.nullPtr. But really, both are usually used for compatibility with external libraries/programs/runtimes, not for idiomatic language programming. Both great languages in my book :)

FYI, I fixed it. std::ptr::null isn't really comparable, so I removed it. You can't really use it in Rust like you could in other languages.

Re: What is wrong with NULL

#124

One of the problem's Maybe still has is in the deeper question of "why are you expecting None to be here?". Don't get me wrong, there are valid cases for this, and Maybe is certainly preferable to null across the board, but I think the movement to Maybe in the greater programming space will in many cases practically result in trading one set of explicit errors (crashes) for (a more subtle?) set of errors (behavioral)…

> Obj-C had a form of this with nil calling of methods silently doing nothing (so you end up with methods that "conveniently" don't happen, and don't crash! when the receiver is nil).

For me it is the worst part of Objective-C. Instead of getting a crash at nil, you will get a weird program behavior later because something wasn't called.

And I never use this feature because it complicates code flow and brings no benefits.

Re: What is wrong with NULL

#125

Earlier quoted context omitted.

Composability comes from functions, macros, and inheritance. What does that have to do with types? "In fact, composibility is really the fundamental issue behind many of these problems. For example, the Store API returning nil for non-existant values was not composable with storing nil for non-existant phone numbers." That's only because you invented some abstraction that got in your way in the first place. NULL is a…

This is not contrived. (1) A cache returns something or NULL. It's generic; i.e. implementation doesn't care what it is storing: integers, strings, etc. (2) A particular value of interest may be NULL or non-NULL. But now I can no longer use my generic cache and my values of interest together. A very real example of this is Java's Map interface. It's completely up to implementation on how they handle null, making inte…

You're conflating the meaning of NULL in that case. That's not a problem of NULL, you're using NULL to represent multiple different things. You can use exceptions to handle that scenario.

  cache = {}
  getFromCache = (key) ->
    return cache[key] if cache[key]?
    throw "not found"
  
  doSomethingWithValue = (key) ->
    try
      value = getFromCache(key)
    catch
      value = getValueFromNonCache(key)
    return _doSomethingWith(value)

Re: What is wrong with NULL

#126

One of the problem's Maybe still has is in the deeper question of "why are you expecting None to be here?". Don't get me wrong, there are valid cases for this, and Maybe is certainly preferable to null across the board, but I think the movement to Maybe in the greater programming space will in many cases practically result in trading one set of explicit errors (crashes) for (a more subtle?) set of errors (behavioral)…

This is a concern, but the advantage to Maybe is it makes this concern very explicit. SML/NJ code will not compile if you don't have a binding to handle the None for an option 'a type. The programmer does of course then have the option of doing None => raise Error but practically speaking, when deciding it's time to make your code more robust, it's a lot easier to text search for instances of "None => raise" than to…

Exactly. You can still get errors due to things not being there. But your assumptions are explicitly stated.

You see None => raise Error, and a little alarm goes off in your head, and you look around for a reassurance that we really want to do that.

In contrast, you don't give x.toUpperCase() a second glance.

Re: What is wrong with NULL

#127

The mistake is an unsafe null: making every object type carry a value in its domain which says "Oops, though my type says I'm a Foobar, I'm not actually an object, la la la! Have a free exception on me, in your face!" Lisp's NIL is brilliant. It's in its own type, the null type! And it's the only instance of that type. No other type has a null instance. Null references in the language simply reflect the tension betwe…

NIL is fine ... as long as you have some container for the opposite. There should be a way to express Maybe >, aka an optional optional value. The Store article in the article is an example of when this would be needed: a cache optionally has an optional phone number for a person. If Lisp has the equivalent of Maybe > (perhaps a singleton list of a singleton list?), then the optionality is composable. Otherwise, the…

The optionality is composable, because we can have the nonexistence of a cache entry (cache lookup fails, perhaps indicating so by returning nil instead of a cache entry) paired with the possibility that cache entry which exists (successful lookup) has a nil value for a phone number.

Re: What is wrong with NULL

#128

Earlier quoted context omitted.

I think your failure to use Option correctly cannot be blamed on Option alone, given that many people use it successfully.

I think your failure to use NULL correctly cannot be blamed on NULL alone, given that many people use it successfully.

The whole problem with NULL is that practically no one can use it correctly.

Re: What is wrong with NULL

#129
post #98
post #57

Earlier quoted context omitted.

Came here to say this. In fact, I think every language that they give 5 stars to has some form of "foreign pointer", "raw pointer", "unsafe pointer" or the like that is nullable, for FFI and other low level tasks. I think that anything which has no null in normal, idiomatic code, outside of "unsafe", "ffi", or similar subsets, should get 5 stars. The distinction is really about whether you need to worry about any pos…

> Likewise, I think that in Scala and Swift, null is only present for compatibility purposes, and idiomatic code does not use them. I'm not sure about F#. I believe though that with the exception of Swift, null can infect these language's quite easily via the FFI, and the guarantees aren't as strong. I haven't used them much though, so I could be wrong.

Yeah, I guess it depends on how often you use the FFI, and I'm not familiar enough with these languages in practice to know how often that comes up. Part of the point of each of these is that they can utilize an existing ecosystem in which null is common (Java/JVM for Scala, C#/CLR for F#, Objective-C/Cocoa for Swift).

I know that in practice in Rust, the general approach is to write safe wrapper around any C libraries you're using, so the use of nullable pointers is generally confined to those wrappers.

Re: What is wrong with NULL

#130
post #50

Earlier quoted context omitted.

" In Python, you can also pass 42, [], or the sqlalchemy module. None isn't special here... " ...the interpreter's environment, my left elbow, the magic unicorn that lives under my steps,...

Sorry, no. You can only pass a stable, property typed Python representation of your left elbow, or the magic unicorn, not the elbow or unicorn itself.

If it quacks like a unicorn then it's still a duck
Post reply on HN