Shameless self plug "Comparing Optionals and Null in Swift, Scala, Ceylon and Kotlin" http://codemonkeyism.com/comparing-optionals-and-null-in-swi...
FYI your Scala example doesn't work. Welcome to Scala version 2.11.6 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_45). scala> var h:Option[String] = "Hello".some :7: error: value some is not a member of String var h:Option[String] = "Hello".some
Java 8’s new Optional type doesn't solve anything
151–160 of 197 posts
Re: Java 8’s new Optional type doesn't solve anything
#152 public Optional badIdea() { return null; }
I think the fact that this compiles is all the argument necessary. What java needed was a ThisWillDefinatelyExist. Not the opposite, but java just can't do that.Re: Java 8’s new Optional type doesn't solve anything
#153Earlier quoted context omitted.
> Optional myOptional = null That hasn't been a problem for me in practice. It's pretty clear that a reference to Optional should never be null. It can be statically or dynamically checked with @Nonnull or a precondition. > but the same was true for nullable properties. It's inconvenient to have to treat everything as possibly null. It's a lot nicer to create the convention, within one's codebase, that references are…
> That hasn't been a problem for me in practice. It has for me. Functions have multiple return points, some of them returning "null". Lead developer insists we use Optional to clarify that these functions can return null. People go over the function, replacing each instance of "return null" with "return Optional.empty()", but forget some instances. Now we have Optionals that are sometimes null.
By applying these techniques you can quickly create a "demilitarized zone" for null, allowing you to use Optional confidently on the other side. Errors are caught quickly and locally by analysis and assertions. In a large codebase it's not an all at once upgrade, unless you refactor checked by static analysis, but you can be confident in the parts you've upgraded.
Re: Java 8’s new Optional type doesn't solve anything
#154Earlier quoted context omitted.
>>Yes, you can write get() and risk an exception. So don't do that. >Yes, you can dereference a null pointer and risk an exception. So don't do that. Except these aren't at all the same. With a reference, you have no good way of telling whether your reference IS nullable. With Optional, it's ALWAYS optional. Therefore it is trivial to a) train developer habits to always check before fetch, and b) enforce an isPresent…
>Except these aren't at all the same. With a reference, you have no good way of telling whether your reference IS nullable. As the article mentions, we have annotations to do just that. >Therefore it is trivial to a) train developer habits to always check before fetch, and b) enforce an isPresent check with static checks. Again, if we're using static analysis to verify the correct use of Optional, why are we using op…
1) A reference is @NonNull in my code, and I pass it to a component that accepts a regular reference as input. The annotation semantic is simply lost, and I may not even realize it as I'm writing that code. By comparison, if I need to pass an Optional reference where a T reference is needed, then the type system reminds me to consider the present and absent cases. Optional does not allow the programmer to forget.
2) The fact that a component or library was written with annotations does not mean that all usage of the library will properly check the annotations. Sometimes people forget, or sometimes they interact with a component in a dynamic way like through Spring and the semantics get lost. An Optional makes this impossible to forget. You can confuse a @Nullable T with a T, or forget to check upon conversion, but there is no failure case that causes an Optional to turn into a T without handling the present and absent cases.
More choice is better than less choice. You could design an Optional type to omit the get() method. That's less useful than what we have now. Like goto, it has rare but legitimate uses, and it's easy to avoid for the "right way" in the average case (don't use it, flag it during code review, and document the reason why when it's being used).
Re: Java 8’s new Optional type doesn't solve anything
#155I 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.
Null is encouraged and pervasive in Java, undefined is sometimes used as a placeholder and could be forgotten. You can't say that Maybe and Optional have the same amount of power because of this.
Re: Java 8’s new Optional type doesn't solve anything
#156Earlier quoted context omitted.
>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.…
The distinction is there but the runtime behavior is not remarkably different. This feels more like a philosophical argument with no real purpose, to be honest.
Re: Java 8’s new Optional type doesn't solve anything
#157In any case, the concept of null as a primitive is fundamentally broken. Due to Java's backward compatibility requirements, it's too late to resolve this in that language. However, newer languages don't need to make this mistake. However, there are "interoperability" requirements for new languages interfaces with legacy runtimes that tempt language designers to build escape hatches. These escape hatches exist in Swift, Kotlin, Rust, etc even though they're not recommended and their usage presents edge cases.
Ceylon and Haskell seem to be the only two languages to get this completely right. Ceylon expresses optionality as the union between the present value type and null, which is an actual type separate from Object. An optional String is therefore a String|Null, or a String? Haskell accomplishes this with the Maybe type.
All this to say that null should not be a primitive but should be banished to its own corner of the type system with clear compile-time semantics for dealing with the absence of values.
Re: Java 8’s new Optional type doesn't solve anything
#158Optional (either JDK or Guava) is not perfect but is infinitely better than hand-checking for null. Among other things, it expresses the intent of the API writer that their method may or may not return an absent value and this is expressed via the type system. This is in stark contrast to using null as a primitive, which has no such transparency. For instance, there is no difference in Java's type system between a me…
Re: Java 8’s new Optional type doesn't solve anything
#159Earlier 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.
The problem is that a function cannot know whether or not the caller can recover from a particular error, so there's no point in making that distinction in the first place.
Re: Java 8’s new Optional type doesn't solve anything
#160The 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);
(Also I assume the first is intended to be x != null)