Optional != @Nullable

Stephen Colebourne scolebourne at joda.org
Sun Sep 30 07:40:16 PDT 2012


As I was travelling during the main discussions, I didn't write up my POV.

I oppose Optional<T> for general use in Java. Its a solution that is
hugely invasive into the type system and results in much a larger
generic surface are - Map<Integer, Optional<List<Optional<String>>>.
My rule is that no more than two levels of generics are acceptable in
code I review - beyond that it should be a class.

This is all the more important given how poor generics is in Java.
Generics fail my needs over 50% of the time when I'm writing code.
They are hugely built on shaky foundations and are just plain
unreliable. Adding a huge increase in the load on the generics
subsystem is not tenable to me,

I don't have the time to really find an alternate solution here, or
truly understand why its being proposed at all. AFAICT its necessary
for a couple of odd use cases. As such, I appeal that if it is added,
it is given a weird long and horrible name to ensure that it is not
widely used. If developers want their own Optional they can write one
or import a jar, but the JDK must not provide one.

Stephen
PS. the right solution is a type system like Fantom and others, with
Elvis and ? on types. Yes, I understand the compatability issues.

On 30 September 2012 01:13, Jed Wesley-Smith <jed.wesleysmith at gmail.com> wrote:
> Having only recently caught up with the fact that the JDK is getting an
> Option/Maybe/Optional type – as well some of the other standard FP kit – I
> have been also catching up with the discussion around it and some of the
> misconceptions about how such a type relates to the use of null.
>
> Firstly, Option does not replace null. This idea is brought about due to
> the fact that as null inhabits all types in Java, it is often used as a
> convenient way to encode optionality. This is an unfortunately pervasive
> technique (see Map.get for example) and is significantly problematic as it
> is outside the type-system. A parameter or return value that is optional is
> of type T, while a non-optional one is of type T. While there are various
> documentation, annotation and static analysis techniques to provide some
> safety to programs using this encoding – the type cannot tell you alone.
>
> A method with the following signature on Sometype<A>:
>
>   <A, B> Optional<B> test(Mapper<A, Optional<B> m)
>
> is orthogonal to the following signature:
>
>   <A, B> @Nullable B test(Predicate<A> p, Mapper<A, B> m)
>
>
> or given the following interface: interface Partial<A, B> extends
> Predicate<A>, Mapper<A, B>
>
>   <A, B> @Nullable B test(Partial<A, B> m)
>
> Where calling the Mapper with an A that fails the predicate would throw an
> exception. In other words, it encodes in the type system totality for a
> partial function. As it is both a Predicate and a Mapper/Function it also
> both filters and maps!
>
> So, Option is a type-level encoding of optionality. Some people find this
> idea a bit difficult due to the presence of the get() method, and it is
> true that this is a dangerous and unsafe method from a type pov – x.get()
> brings back partiality to the type. It is better replaced by:
>
> interface Optional<A> {
>>   void foreach(Effect e) // for side-effecting using the value
>   <B> Optional<B> map(Mapper<A, B> m) // map the raw value
>   <B> Optional<B> flatMap(Mapper<A, Optional<B>> m) // map and optionally
> return
>   Iterator<A> iterator() // integrate with the usual for-each loops and
> Collections code
> }
>
> These colletively give you all the semantic The flatMap operation is the
> most important, it allows you to sequence together many operations without
> ever leaving the confines of the Optional. Consider for instance:
>
> String address(Session session) {
>   InetSocketAddress socketAddress =
> session.getIoSession().getRemoteAddress();
>   if (socketAddress != null) {
>     InetAddress inetAddress = socketAddress.getAddress();
>     if (inetAddress != null) {
>       return inetAddress.getHostAddress();
>     }
>   }
>   return null
> }
>
> implemented with Optional.flatMap:
>
> Option<String> address(Session session) {
>   return optional(
>     session.getIoSession().getRemoteAddress()
>   ).flatMap(socketAddress -> optional(socketAddress.getAddress())
>   ).flatMap(inetAddress -> optional(inetAddress.getHostAddress()));
> }
>
> This version has no conditional statements, only an adapter method to go
> from null to None/EMPTY.
>
> The FP communities such as ML/Haskell and Scala programmers have all used
> these constructs very successfully for years, it is well worth looking to
> them for some guidance and experience on them.
>
> For further reading on why Guava's lack of flatMap is problematic see
> http://benhutchison.wordpress.com/2012/06/05/a-rant-on-jdroids-and-wilful-ignorance/
>
> For a general presentation on the topic of Option (and why a disjoint union
> type would be invaluable too) see http://cofarrell.bitbucket.org/optional/
>
> For an alternate implementation example of an Option class see
> https://bitbucket.org/atlassian/fugue/src/master/src/main/java/com/atlassian/fugue/Option.java
>
> There are many other resources available but these are quite digestible for
> those with a Java background.
>


More information about the lambda-dev mailing list