Optional != @Nullable

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Mon Oct 1 02:42:08 PDT 2012


Please do not use this mailing list for language/library design 
discussions. This mailing list should be used only for reporting 
experiences/issues in the reference implementation (see [1]).

[1] - 
http://mail.openjdk.java.net/pipermail/lambda-dev/2012-September/005775.html

Maurizio

On 30/09/12 15:40, Stephen Colebourne wrote:
> 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