Where has the map method on Optional moved?

Paul Sandoz paul.sandoz at oracle.com
Wed Feb 27 02:50:15 PST 2013

On Feb 26, 2013, at 10:05 PM, Jed Wesley-Smith <jed at wesleysmith.io> wrote:

> On 26 February 2013 23:40, Paul Sandoz <paul.sandoz at oracle.com> wrote:
>> On Feb 26, 2013, at 12:33 PM, Jed Wesley-Smith <jed at wesleysmith.io> wrote:
>>> FlatMapper is a bizarre Frankensteinian beast, relying as it does on
>>> mutation to do all of its things.
>> You mean mutation as in mutation of state? or mutation in the sense of Frankensteinian mutation due to indirection?
> Mutation of state – FlatMapper is passed things that it accumulates internally.

FlatMapper impls should pass 0 or more mapped elements downstream via the consumer. For example:

List<List<String>> ll = ...
List<String> l = ll.stream().flatMap((l, c) -> l.forEach(c)).collect(toList());

FlatMapper is less convenient than the corresponding Stream based method but is more efficient when one does not have a Stream, or Collection, handy.

> The usual form of flatMap/bind is to return the thing being mapped
> across. No mutation is required (at least at the interface level,
> under the covers local mutation is ok).
>>> It would be a service to all to
>>> rename it to something – anything – else, as it does not resemble the
>>> notion of flatMap/bind that other functional programming languages or
>>> libraries implement.
>>> As to consistency across the interfaces, Java doesn't have the ability
>>> to generalise across Optional and Stream, lacking Higher Kinded Types.
>>> The fact that Stream has named some feature that resembles a monadic
>>> bind flatMap ideally should not then preclude the ability for Optional
>>> to also have this feature.
>>> As to additional potential functionality, you are quite correct, the
>>> restriction of inheritance/OO to be the sole mechanism for adorning
>>> functionality on a data-structure means that the temptation exists to
>>> implement it directly, and these (filter/fold/reduce/foreach etc) are
>>> all sensible suggestions. I do not profess to have definitive answers
>>> to these library design decisions, given the constraints that the
>>> designs are under.
>> The problem being Optional would stick out like a sore thumb. It's not a Stream. There is no direct way to get a Stream from it and if there were, which is quite easy to do, it would not give you what you really want.
> I don't understand why that is a consideration. Stream is not the only
> monadic thing in the world, there are many others, Future for instance
> is an obvious one.

I am sure if we look hard enough we can find monads everywhere! :-) 

Joking aside this is a slippery slope and i don't think we are ready to systematically modify the JDK APIs in this direction.

The goal is to create an API for bulk modification of data, sequentially and in parallel, leveraging the new language features. The goal is not to create a functionally-oriented Java.

> Optional has little to do with Stream. It can be seen as a collection
> of zero or one elements and therefore could implement Iterable, but
> this is not necessary. More useful would be the fold catamorphism:
> interface Option<A> {
>  B fold(Supplier<B> ifNone, Function<A, B> ifSome);
> }
> This is a jack of all trades combinator that can be used to implement
> almost any other functionality you want.

I personally like it. But i don't think we are gonna go there for JDK 8.


More information about the lambda-dev mailing list