Live data from Hacker News

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

medium.com

91–100 of 197 posts

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

#91
I think in this thread when we talk about "pattern matching" (which _is_ awesome) were caught up with two notions: pattern based destructuring of input and type enforced exhaustiveness checks. Java 8's Optional does give the latter:

> maybeT.map(t -> ...).orElse(...)

The author does make a good point that 'get' is unsafe. I think it was a necessary concession to team members who are learning how to program in this manner.

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

#92
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);

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…

The point of the new Optional type in Java isn't to prevent NPEs, it's to make using the new Streams API cleaner. Since you can now flow through optional values in a stream you can ignore whether the stream contains optionals or not and only deal with them at the end. It's certainly possible that in a future version of Java the optional type might be paired with something like pattern matching to prevent NPEs with some syntax sugar, but that's not the reason that the Optional type exists today.

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

#93
post #80
post #73

Earlier quoted context omitted.

Just to clarify since `unsafe` is a special term in Rust: `unwrap` still checks for None and panics, it doesn't blindly assume it's valid. That said, I think you're too dismissive of "can never fail" assumptions. There's tons of places where something is optional in general, but based on various invariants you know it won't be. For instance, if you successfully acquire the first element in an array, you know you can…

>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. Requiring that really dilutes the value/meaning of errors.

Given this signature:

fn do_thing() -> Result

There's a clear signal that there's legitimate error conditions that you probably want to think about today. If every function that accessed arrays, worked with integers, or allocated memory returned a Result, it would border on meaningless. It would be like if there was no Throwable/Exception distinction in Java. Everything would `throw Exception`, eliminating the value of even noting that something can fail.

I think the only way such a system could be tolerable is if the language in question had really good dependent type support (but that wouldn't handle the OOM issue -- which you can't even reliably handle on some systems).

Unwinding/crashing is valuable in a truly robust system, because it needs to handle crashes anyway. Might as well punt obscure problems to that level of the reliability system. (This is basically the basis of Erlang's task system, AFAIK)

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

#94

Earlier quoted context omitted.

Allowing unsafe unwraps defeats a core purpose of rust, Definitely, but you can also still do this in Haskell ( fromJust ). But it's better than nullable types since you explicitly have call an unsafe method. (Assuming that you have set non-exhaustive pattern matching to be a warning/error.)

unwrap() is not unsafe in Rust, and I don't think Haskell has anything similar?

Sorry for the confusion! I meant 'unsafe' as in partial (not safe for all inputs). Not as in Rust's unsafe keyword.

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

#95

Earlier quoted context omitted.

unwrap() is not unsafe in Rust, and I don't think Haskell has anything similar?

Sorry for the confusion! I meant 'unsafe' as in partial (not safe for all inputs). Not as in Rust's unsafe keyword.

Ah, right. It's really important in the context of Rust. :) People sometimes claim that unwrap() violates memory safety, which isn't true.

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

#96
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

The idea is that Err is good if it's a recoverable error, but if it's not recoverable, you should panic!. Most errors are recoverable. panic! is an antipattern in a library. Or at least, provide both a panic-ing and a non-panic-ing variant.

We specifically recommend against providing panicing and non-panicking. This causes horrible combinatoric explosions. There's very few exceptions to this (array indexing being the major exception). We do of course recommend non-panicking, but there's a few cases where the burden of checking for errors is too high (indexing, refcell).

We're actually in the midst of arguing whether to violate this convention and do it for RefCell: https://github.com/rust-lang/rust/issues/27733

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

#97
I love Haskell, but the existence of a bottom type throws all run time guarantees out the window.

    import Control.Monad
    ex1 = Just 1 :: Maybe Int
    ex2 = undefined :: Maybe Int
    inc = liftM (+1)
    main = do
      putStrLn . show $ inc ex1
      putStrLn . show $ inc ex2
Yes, you should never use `undefined`. Now replace `undefined` with `null` and it becomes apparent that Maybe and Optional have exactly the same amount of power.

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

#98
post #96

Earlier quoted context omitted.

The idea is that Err is good if it's a recoverable error, but if it's not recoverable, you should panic!. Most errors are recoverable. panic! is an antipattern in a library. Or at least, provide both a panic-ing and a non-panic-ing variant.

We specifically recommend against providing panicing and non-panicking. This causes horrible combinatoric explosions. There's very few exceptions to this (array indexing being the major exception). We do of course recommend non-panicking, but there's a few cases where the burden of checking for errors is too high (indexing, refcell). We're actually in the midst of arguing whether to violate this convention and do it…

Yeah, I was thinking of things like array access. The stuff that's on the wrong end of the cost/benefit ratio.

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

#99
post #19

Earlier quoted context omitted.

Exactly, it forces the programmer to think about whether something can be null or not and actually had a behavioural change in my java coding.

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

def foo(x:Option[String]) = x.filter(_.lengthIf the function returns None if it receives either None or a string longer than 10 characters, and if we got Some("short "), foo will return Some("short More data"). The alternatives without an option type, involve at least a couple of branching statements, even if you have a non nullable type, to convert from nullable to not nullable, while Option does it all for us.

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

#100
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);

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…

Not entirely true from what little I know about Haskell. Haskell might put MORE of the burden on the compiler but it doesn't put ALL of it there. The following generates a runtime exception. (not a compile time type error)

head []

Post reply on HN