Live data from Hacker News

What is wrong with NULL

lucidchart.com

61–70 of 147 posts

Re: What is wrong with NULL

#62
> 4. NULL makes poor APIs

Then don't use it. The example given is a bad design. No phone number and not in cache should not return the same value. That bad design has nothing to do with nil, Return '' for no phonenumber.

Re: What is wrong with NULL

#63
post #49
post #3

This mistake is fixed in Haskell.

Not completely. non-nullable by default is nice, ignoring possible nulls is nice, but Haskell's Maybe still suffers from premature generality by conflating all forms of absence. A 'Maybe T' is fundamentally, context-sensitively, not equivalent to any other 'Maybe T' in the same way all 'T's are. This is bad. edit: carsongross beat me to what I'm talking about with a better explanation: https://news.ycombinator.com/it…

When you need to distinguish missing values, that's why Haskell has Either. Maybe is for when you only care if there is a good result are not, Either covers the case when you need to distinguish different kinds of "not".

Re: What is wrong with NULL

#64

Earlier quoted context omitted.

Pretty good, but I've never had a problem with an XMLHttpRequest being inconsistent. Everything else seems spot-on though.

I think they're joking about the capitalization of the name.

Yeah. That's what I was going for ;)

Re: What is wrong with NULL

#65
post #12
post #4

For statically typed languages this is definitely an issue, but for dynamic languages less so. In Python, I wouldn't use an optional value, x is None seems to be just fine. I'm still waiting for std::optional for C++.

It's only not an issue in dynamic languages in the sense that you have the same issue anyway without null because you have no type safety at all.

You have a ton of type safety in Python, which is one reason why Python programmers are cranking out large bodies of working code representing all kinds of applications that Just Work.

"No type safety at all" means you can misuse a value of one type using an operation that is appropriate for a different type, and some nonsensical behavior silently occurs (or perhaps some nonportable behavior that you sneakily intended). This characterizes assembly languages, certain machine-oriented languages like BCPL, and some immature dynamically typed languages which omit run-time-type checks (the type information is there, but not checked, so that string_length happily tries to operate on an integer, so that a type problem occurs in the interpreter's kernel itself.)

Re: What is wrong with NULL

#66
post #56

We don't need to get rid of null, we need more, type-specific and context-carrying nulls: types need a way to signal various error states via an enumeration of instance constants that carry the error state in a type-compatible manner without some syntactically crappy mechanism like Maybe. class Connection { //Error instances BAD_ADDR("The given address was not correct...") ... } These constants should throw, just lik…

If you have a language with enum types (Haskell, ML, etc., or any of the languages inspired by them like Rust, Scala, etc.), that's straightforward. In e.g. Rust, you'd have enum Connection { ValidConnection {fd: RawFd, address: SockAddr, ...}, BadAddr, BadPort, ... } In fact Rust's representation of the maybe type is just a generic enum Option { Some(T), None, } so all you're doing is getting rid of the two layer Op…

You shouldn't have to specify the error states in each method, this is why what I'm advocating is different than a simple enum:

- You don't need to define a constructor to take the error string

- You don't need to implement method dispatch (all methods of an error state instance automatically throw, like null does)

Enums are close, but not quite right.

Re: What is wrong with NULL

#67
post #34

It's worth noting that having a NULL, somewhere, is not so much a problem as forcing types to have a NULL. In this respect, e.g. Python and Rust both get it right: while Python has a None, and Rust has std::ptr::null(), an object that is a string cannot be any of those, because those are different types (NoneType and raw pointer, respectively). C's problem is that a string could be null, and there's no syntax for a n…

I also think that Go did pretty well to fix NULL. It didn't get rid of it completely, but it (nil) is only valid for pointers and interfaces, so it's not possible to use it in place of a string, integer, etc. It's not as bulletproof as Rust or Haskell, but something as simple as disallowing nil strings can make a world of difference.

Re: What is wrong with NULL

#68
post #50
post #34

It's worth noting that having a NULL, somewhere, is not so much a problem as forcing types to have a NULL. In this respect, e.g. Python and Rust both get it right: while Python has a None, and Rust has std::ptr::null(), an object that is a string cannot be any of those, because those are different types (NoneType and raw pointer, respectively). C's problem is that a string could be null, and there's no syntax for a n…

" 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.

Re: What is wrong with NULL

#69
post #34

It's worth noting that having a NULL, somewhere, is not so much a problem as forcing types to have a NULL. In this respect, e.g. Python and Rust both get it right: while Python has a None, and Rust has std::ptr::null(), an object that is a string cannot be any of those, because those are different types (NoneType and raw pointer, respectively). C's problem is that a string could be null, and there's no syntax for a n…

You make a good point. I removed the mention of std::ptr::null, since it really isn't really a NULL like other languages. Like you said, it's for FFI.

Re: What is wrong with NULL

#70
Well the article doesn't talk about performance, but at least for the double-maybe in the store example, there is one level of extra indirection in the machine code: return pointer to maybe, then return pointer from string from it.

If you care about performance, you really need two predicate values to cover this case. You could have (void * )0 for no entry, and (void * )1 for entry exists, but is blank.

Post reply on HN