Hacker News new | past | comments | ask | show | jobs | submit login

> For instance, nulls are clearly a problem. After countless rants we're seeing languages that have better ways to deal with missing or optional values enter the mainstream (Swift, Scala, Rust).

No they are not. They are a state of an object. What is the problem is a lack of documentation.

One thing I've seen coming up, at least in some code I've looked at, is the @Nullable and I've not seen any complaining about null from those who use this tag.

The idea is to always document when a variable or type can be null. This way you know, with 100% certainty (given a strict type system adherence) that you're not going to erroneously see a null object where it isn't expected.

From this, you have a huge benefit: a performant error state or a better method of representing an issue without throwing an exception.

Riddle me this, how would a Map be implemented if Null was stripped from Java? Should it throw an exception if a key is not found? If that is the case, then you should always need to check for this exception, otherwise you're prone to bugs. You've also increased the execution time of your code by in some a huge performance hit [0] that is more cumbersome.

This is why I think rants are a big problem. They don't describe the opposition to a statement accurately. They are one person's opinions and after reading them, if it all sounds nice, you're usually willing to take it all as fact. "Hey, they're writing an article! They must be smarter then me. I'll take their word for it." As a result, our communities don't really evolve we just spew memes back and fourth dictating what someone else thought.

What really matters, in every sense, is reading a discussion had between two experts in opposing camps. That way you can see both sides of the arguments, their weak points, and make an educated choice on what side to agree with.

That being said, what do you think of my points? Can you address them? My oppinion is that NPEs can be easily avoided by using very simple measures AND null more closely resembles most problems while being more performant and less cumbersome then throwing exceptions willy nilly. I'd love to hear how you feel about this.

Also...

> J2EE's original idea to configure a system through separate XML files was heavily criticised for being too bureaucratic. After countless rants we got configuration by convention, better defaults and annotations as part of the source language.

I'd say that is a good example of discussion, brain storming, and coming up with a much more accurate representation of the ideas we are trying to convey (the use of annotations to configure methods).

[0] - http://stackoverflow.com/a/299315




The problem with null as implemented is that it type-checks as a value of any type. This means that anywhere you have a value of some type, it may be a valid value of that type, or it may be null. If you think about it, this is very odd. What if the number 42 were considered a valid value of every type, such that it were usually necessary to check whether you actually have 42 before using a value? That seems ridiculous, but it's almost exactly how null works.

I'm someone who uses @Nullable and complains about null, so now you've met one of us! The problem with @Nullable is that it's mostly useful when all your code uses it, but the compiler will not force you to do so. It is a Sisyphean task. (But at least Java has @Nullable - most languages with null don't have anything like that.)

In a parallel universe version of Java with no nulls, a Map implementation would return Optional.<Foo>empty(). This seems similar to null, but with uglier syntax, but critically, it is not of type Foo. In order to get a valid Foo, for instance to pass to a method that takes one, you must unwrap the Optional you have and if it is empty you simply can't call that method with a Foo because you don't have one. The advantage here is that this method taking a Foo now knows for sure it has one and does not need to bother checking that assumption. How pleasant!


> Riddle me this, how would a Map be implemented if Null was stripped from Java?

Obviously you would use an Optional<T> (for a Map<K,T>)

See https://docs.oracle.com/javase/8/docs/api/java/util/Optional...


Which would have been a great idea if it had been in Java 1.0 :-(

Alas, the horse has left the barn.

Much like immutability: if it had been the default, with a "DANGER: mutation ahead" keyword required otherwise, that would arguably have been good. But it's too late, now. (Java) Beans, beans, the magical fruit...


Yeah, it's a bummer dealing with backwards compatibility. Don't get me started on guava Optional vs JDK8 Optional.

But at least you can stick to just using Optional and no nulls in new code you write, and only using nullables to communicate with existing libraries.


I mean when people say Nulls are bad I don't think they necessarily mean they are categorically bad, only that allowing every single object in a system to have a null value without any supporting language features requires a lot of discipline. I don't know anyone that's used something like Maybe[String] and felt it was categorically no better than 'null' values, but on some level they are both features that express the same thing. Just one of them is more coherent and targeted.

When people say that null was a billion dollar mistake I don't think they were referring to any possible implementation of a value that indicates nonexistence.


> Riddle me this, how would a Map be implemented if Null was stripped from Java?

Optionals.


Riddle me this, how would a Map be implemented if Null was stripped from Java?

  map.getOrThrow(key)
  map.getOrDefault(key, defaultValue)


So I can either throw an exception and take a speed hit in my performance critical code or I can remove a possible value from my map?


It's not "removing a possible value from your map", it's having your type system explicitly check that you're handling the edge case at compile time. This works in practice in a wide variety of languages.


Maps should do whatever ArrayList does when your index is out of bounds. And so long as null is a value that could be in the collection, lookup should definitely not return null.

If a lookup fails, it is often a bug or a violation of a constraint that you shouldn't be handling. Throw an exception. If a lookup is expected to fail in normal execution, you can use an Optional to mash together a check and lookup in a typesafe way. Lookup failures should not be allowed to propagate as nulls only to be caught as NullPointerExceptions in disparate parts of the code.


Tony Hoare, the computer scientist who introduced null, called it a billion dollar mistake. He's pretty accomplished in his field, and there are better options than null for signifying that a Map doesn't have a particular value, like Option types.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: