Live data from Hacker News

Java 8’s new Optional type doesn't solve anything

medium.com

111–120 of 197 posts

Re: Java 8’s new Optional type doesn't solve anything

#111
I've been using Swift for over a year now, which has had an Optional implementation from day one. I see a lot of people defending Java's implementation in this thread, can someone check my understanding? I did Java in a past life but am not super familiar with Java 8.

In Swift, types are non-optional by default. You can never end up with a null, the compiler makes it impossible. Optionals are out of the way until you need them, and if you use them properly (i.e. avoid the .get() equivalent), it's still impossible to crash from a null.

In Java 8, things can still contain null by default and you might not know about it, right? You can express that something is Optional in your API, but that's only marginally better than documentation, doesn't solve "unexpected nulls" whatsoever, and makes this only halfway to a solution and therefore broken entirely. Why not just use annotations?

Are my assumptions and understanding correct?

Re: Java 8’s new Optional type doesn't solve anything

#112
post #18

The author is missing the point. The fact that Optional can result in a nullpointer doesn't mean you should use in the same manner as null-checks. You shouldn't replace: if(x == null) { y = x.doSomething(); } with if(optionalX.isPresent()) { y = x.doSomething(); } You should replace it with: y = Optional.ofNullable(x) .map(ClassX::doSomething) .orElse(null);

I agree. Having programmed in java for the past 15 years, I can attest that NullPointerExceptions are a constant source of errors. The main benefit I've experienced with Optional is that it documents the fact that a method might return a null value. Without this, the client has to guess whether or not to add defensive null checks.

Re: Java 8’s new Optional type doesn't solve anything

#113
post #93
post #80

Earlier quoted context omitted.

>Gonna have your function return an Err if an internal invariant is broken? Absolutely you should return an error. Whether the caller wants to panic or handle it or print unicorns should be left up to the caller, not your function. Functions should not be expected to tear down the thread in case of an error. Nothing that panics should belong anywhere in exported code

This seems a bit too unpragmatic. Would you also require the user to explicitly handle: * Index out of bounds on every array op * Integer overflow on every arithmetic op * OOM on every allocating op Maybe if you're writing an ironclad RTOS for a critical system without any good redundancy? Otherwise these are such pervasive operations that most have accepted that they're not worth handling everywhere they happen. Req…

>Requiring that really dilutes the value/meaning of errors.

No. You have already diluted the meaning of errors, and you want them elevated to _your_ standard.

>Index out of bounds on every array op

These are removed if you build a rust program with --release.

>Integer overflow on every arithmetic op

Add the Wrapping class if you expect overflow. Overflow _shouldnt_ normally happen on an Integer operation. It is a hardware error when it happens, and can cause massive pain-in-ass bugs when it happens unexpectedly.

I'd rather get errors when it does happen, rather then find out 6 months into a production run.

>OOM on every allocating op

C does this also.

Re: Java 8’s new Optional type doesn't solve anything

#114

I've been using Swift for over a year now, which has had an Optional implementation from day one. I see a lot of people defending Java's implementation in this thread, can someone check my understanding? I did Java in a past life but am not super familiar with Java 8. In Swift, types are non-optional by default. You can never end up with a null, the compiler makes it impossible. Optionals are out of the way until you…

I don't think anyone thinks that Optional as it is in Java right now is the perfect solution. The article seems to be making the case that Optional isn't an improvement of what came before, which is what people are having issues with.

Re: Java 8’s new Optional type doesn't solve anything

#115
post #38

Earlier quoted context omitted.

I am not sure I understand. I guess you are either saying (A) to treat every return type as possibly null or (B) to use your judgment when doing null checks of return types. In case of (A): Do you want to write null-checks for methods like String.toUpperCase() or for user.getLastName() ? That would lead to a lot of bloated, dead code. Also do you want to write error handling for all these cases you know can never hap…

I would say that every return type that can be NULL should be checked for being NULL. In C++, this is possible, because you most functions are return-by-value or return-by-reference. This leaves only return-by-pointer that need to be explicitly checked. In Java, all functions that do not return primitives are return-by-pointer, and are therefore nullable. This, as you mentioned, makes it infeasible to apply null-chec…

A consistent API written with Optional should make it such that if an Optional is returned, then a null value could have been returned. If an Optional is not returned (including for references), then you can assume that null will not be returned. This is a contract that can be documented as part of the API documentation.

To me, this is much clearer than having to guess on every call and I would prefer this use of Optional or not in an API to an API without Optional and having to check everything.

Re: Java 8’s new Optional type doesn't solve anything

#116
post #45

Earlier quoted context omitted.

The author is missing the point. Is he? The point is that in Java you are still able to treat x unsafely, while languages with stronger typing do not. E.g. in Haskell, if a function returns a Maybe a , it will always be a Just a or Nothing value. Moreover, such languages allow you to make non-exhaustive matching against all constructors a compiler error. tl;dr: Haskell, Rust, et al. put the burden on the compiler. Ja…

>tl;dr: Haskell, Rust, et al. put the burden on the compiler. Java puts the burden to ensure safety on the programmer. (As can be witnessed in your snippet.) Actually, (much to my disappointment as I'm just learning rust) you can just take an Option or Result and .unwrap() and the compiler won't complain at you for not checking it. For such a "safe" strongly-typed language, I'm surprised that so much new rust code do…

>Actually, (much to my disappointment as I'm just learning rust) you can just take an Option or Result and .unwrap() and the compiler won't complain at you

unwrap() is a convenience method that still uses exhaustive pattern matching and will panic if no value is present. The developer is making a conscious decision to panic in a not-present scenario, and on a case-by-case basis. The compiler is still doing it's job. This is different than java, where a get() on a non-present value is a runtime violation.

Re: Java 8’s new Optional type doesn't solve anything

#117
post #68

Earlier quoted context omitted.

> That said, it's pretty rare to need exactly 0 or 1 of something. That's interesting and sort of hard to agree with. I think uniqueness is very often desirable and very often paired with a lack of certainty about existence. "Does a user with this identity exist?" certain is handled properly as a 0-or-1 question, e.g..

Is your method "getUserIfItExists(username)" or "doesUserExist(username)"?

It's pretty common to need to do something to your user object if it does exist. As a toy example, it's far better to have something like (using Scala syntax here):

    def getUserGreeting(userDao: UserDAO)(username: String): String =
      userDao.getOptionalUser(username) match {
        case Some(user) => "Hello, " + user.getFullName
        case None => "Not logged in"
      }
than:

    def getUserGreeting(userDao: UserDAO)(username: String): String =
      if(userDao.doesUserExist(username)) match {
        "Hello, " + userDao.get(username).getFullName
      } else {
        "Not logged in"
      }
For one thing, the first function probably only makes one database call, while the second (absent caching) makes two. Secondly, the second carries with it the (unlikely) possibility that the user is deleted between your DAO calls. Thirdly, I would argue that the first function is easier to read.

Re: Java 8’s new Optional type doesn't solve anything

#118

I think the main use of Optional is in a codebase which doesn't _ever_ allow "null". If every method call either returns an actual object then you can get rid of null checks, and not bother doing any checks on method returns that don't return an Optional.

That is exactly how we use Optional.

Re: Java 8’s new Optional type doesn't solve anything

#119
post #45

Earlier quoted context omitted.

>tl;dr: Haskell, Rust, et al. put the burden on the compiler. Java puts the burden to ensure safety on the programmer. (As can be witnessed in your snippet.) Actually, (much to my disappointment as I'm just learning rust) you can just take an Option or Result and .unwrap() and the compiler won't complain at you for not checking it. For such a "safe" strongly-typed language, I'm surprised that so much new rust code do…

I completely agree. unwrap() is a huge mistake in Rust. There are brilliant ideas implemented in Rust (primarily the borrow checker) but their advantages seem to be wiped out by the kludge of unwrap.

If we didn't provide it, someone would write it. (Actually, I suspect lots of libraries would just have it.) You can't force people to write good code.

This presupposes that the pattern that "unwrap" wraps is always a bad thing anyway, which it isn't. Sometimes the right thing to do is to panic your program if None is present. And sometimes the type system isn't sophisticated enough to express an invariant, and you need to use "unwrap" to work around it.

By the way, the borrow checker has nothing to do with unwrap().

Re: Java 8’s new Optional type doesn't solve anything

#120
post #99

Earlier quoted context omitted.

Wouldn't it be better to have a non-nullable type, akin to C++'s return by value? That way, instead of forcing the programmer to think, you are removing the problem that they would need to think about.

In other languages that use Option types more natively, like Scala, anything that isn't optional is assumed to just not be null: The compiler doesn't guarantee it (it's not as if it can, we are dealing with a JVM here) but it works in practice. I've not seen a NullPointerException in years. Option has other advantages, like its compositional qualities (thanks to Option being a monad). So imagine the following code de…

> I've not seen a NullPointerException in years [in Scala]

This sounds odd. Does your code never interface with Java libraries and frameworks? I envy you! It's all too easy to forget to wrap a suspect value from Java-land with an Option(..). And cumbersome even if you do remember.

And then, there's the code written by Scala novices who just love using nulls. Yes, yes, "code reviews", we all know they are always practiced all the time :/

Post reply on HN