Some new Guava classes targeted for release 10

1,037 views
Skip to first unread message

Kevin Bourrillion

unread,
Apr 25, 2011, 2:06:59 PM4/25/11
to guava-discuss

JR Boyens

unread,
Apr 25, 2011, 2:33:26 PM4/25/11
to guava-discuss
Excerpts from Kevin Bourrillion's message of 2011-04-25 14:06:59 -0400:> <http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Ranges.html>
> http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/util/concurrent/Futures.html
>

The Optional javadoc refers to a Holder class will this be released as
well or was this an unintentional leak of things to come?
-- JR

Kevin Bourrillion

unread,
Apr 25, 2011, 2:35:18 PM4/25/11
to JR Boyens, guava-discuss
Ahh, yes, broken link.  We'll either get it released or clean that link up.


Colin Decker

unread,
Apr 25, 2011, 4:57:43 PM4/25/11
to guava-discuss
My comments are here. Range and Optional are great!

-- 
Colin

Kevin Bourrillion

unread,
Apr 25, 2011, 5:22:30 PM4/25/11
to Colin Decker, guava-discuss
Thanks!

To address your points in discussion,

1. Serialization.  You're right.  I keep forgetting that we don't make any guarantees about portability of serialized forms across versions, so serialization is actually a lot easier than it was back when we were actually shooting for that.  Would anyone be able to pull together a list of *all* the types that make sense to be serializable and file an omnibus feature request?

2. I'm not sure it was that important for us to implement ImmutableSortedSet at all; or if we just did it because, hey, it's immutable.  We could back that out.  If we don't, then perhaps DiscreteDomain will have to get the "add this distance to this point" method you describe, because asList() is too scary otherwise.  At one point we were hoping DiscreteDomain would support "partial" domains like "prime integers" or "Wednesdays", and under that model the method you describe didn't necessarily make sense, but we had to back away from that and settle for a DiscreteDomain only representing the entire type that it's parameterized on.

3. Yep, we just noticed that mistake, and Equivalence.wrap() will come soon.

4. Holder<T> can probably make it soon, I think.

5. Whoops, I'm sure we mean to let you create your own DiscreteDomains.  Note that it may not work for what you want (a subset of the possible values of a type).

6. Thanks for the idea of using Optional in DiscreteDomain; the Optional class is one of the newest things we have and we have yet to think through where we might want to self-adopt it.

Colin Decker

unread,
Apr 25, 2011, 6:39:18 PM4/25/11
to Kevin Bourrillion, guava-discuss
On Mon, Apr 25, 2011 at 5:22 PM, Kevin Bourrillion <kev...@google.com> wrote:
1. Serialization.  You're right.  I keep forgetting that we don't make any guarantees about portability of serialized forms across versions, so serialization is actually a lot easier than it was back when we were actually shooting for that.  Would anyone be able to pull together a list of *all* the types that make sense to be serializable and file an omnibus feature request?

I'll try to do this when I get a chance.
 
2. I'm not sure it was that important for us to implement ImmutableSortedSet at all; or if we just did it because, hey, it's immutable.  We could back that out.  If we don't, then perhaps DiscreteDomain will have to get the "add this distance to this point" method you describe, because asList() is too scary otherwise.  At one point we were hoping DiscreteDomain would support "partial" domains like "prime integers" or "Wednesdays", and under that model the method you describe didn't necessarily make sense, but we had to back away from that and settle for a DiscreteDomain only representing the entire type that it's parameterized on.

That makes sense. Whatever you decide to do there is fine with me... I was just hoping for some way to iterate through a range, so being able to get a SortedSet instead is cool!
 
5. Whoops, I'm sure we mean to let you create your own DiscreteDomains.  Note that it may not work for what you want (a subset of the possible values of a type).

Well, the domain *would* cover all instances of my class that can be constructed (trying to make a FiscalYear with a value less than 1977 throws an exception) so I wouldn't think it'd be considered a subset even though it doesn't cover all years or integers. Plus, the way I'd be using it is very simple... just relatively small closed ranges.

Kevin Bourrillion

unread,
Apr 25, 2011, 9:10:41 PM4/25/11
to Colin Decker, guava-discuss
On Mon, Apr 25, 2011 at 3:39 PM, Colin Decker <cgde...@gmail.com> wrote:
Well, the domain *would* cover all instances of my class that can be constructed (trying to make a FiscalYear with a value less than 1977 throws an exception) so I wouldn't think it'd be considered a subset even though it doesn't cover all years or integers. Plus, the way I'd be using it is very simple... just relatively small closed ranges.

Oh, cool, you should be fine then.  I'll look into why it wasn't made public yet.

Jed Wesley-Smith

unread,
Apr 27, 2011, 1:44:39 AM4/27/11
to Kevin Bourrillion, guava-discuss
Kevin, it is fantastic to finally have a somewhat standard Option class in a common library, but almost every implementation I have seen follows the scala/haskell idiom of Option/Some/None. Is there any chance of following this convention rather than inventing a new mostly similar one?


I am not expecting all of the functionality, just the basic naming, use Option<T> with Some and None concrete implementations.

Minor points:
- it can implement Supplier<T>
- get(T defaultValue) reads better as getOrElse(T defaultValue)
- please (please) add Option<S> transform(Function<T, S> f)
- or implement Iterable<T> so we can wire that up ourselves

There are a few others, but these come off the top of my head.




--
cheers,
- jed.

Maarten Billemont

unread,
Apr 27, 2011, 3:37:40 AM4/27/11
to Jed Wesley-Smith, Kevin Bourrillion, guava-discuss

On 27 Apr 2011, at 07:44, Jed Wesley-Smith wrote:

> - get(T defaultValue) reads better as getOrElse(T defaultValue)

reads wrong, too. you're not getting the defaultValue. you're getting the provided value and only the default value if the provided value is null.

x.get(y) reads totally confusing when under normal circumstances you'd get the value contained by x, not y.
x.getOrElse(y) is a few more characters, but at least it's clear and transparent about what it really does.

Maarten Billemont

unread,
Apr 27, 2011, 4:02:18 AM4/27/11
to Jed Wesley-Smith, guava-discuss

On 27 Apr 2011, at 09:45, Jed Wesley-Smith wrote:

> Maarten, I'm a little confused – I was proposing getOrElse(T) instead of get(T) and you are +1 ?

Looks like I read your "as" as a "than" (blame my native language). Then for the reasons below, I am +1, yes :-)

> --
> cheers,
> - jed.

etorreborre

unread,
Apr 27, 2011, 7:58:48 AM4/27/11
to guava-discuss
I want to add a big +100 to what Jed wrote.

I'm currently using an Option class on a "legacy" java project and I
can see that my fellow developers are slowly getting used to it.
A huge part of what makes it possible is the availability of the
functionalities that Jed is mentioning. Iterable and transform (or
"map" or "to", or whatever you want to call it) are really
indispensable.

As a source of inspiration I suggest:

- https://github.com/npryce/maybe-java
- http://eng.wealthfront.com/2010/05/better-option-for-java.html

Thanks,

Eric.

On Apr 27, 3:44 pm, Jed Wesley-Smith <jed.wesleysm...@gmail.com>
wrote:
> Kevin, it is fantastic to finally have a somewhat standard Option class in a
> common library, but almost every implementation I have seen follows the
> scala/haskell idiom of Option/Some/None. Is there any chance of following
> this convention rather than inventing a new mostly similar one?
>
> http://www.scala-lang.org/api/current/scala/Option.html
>
> I am not expecting all of the functionality, just the basic naming, use
> Option<T> with Some and None concrete implementations.
>
> Minor points:
> - it can implement Supplier<T>
> - get(T defaultValue) reads better as getOrElse(T defaultValue)
> - please (please) add Option<S> transform(Function<T, S> f)
> - or implement Iterable<T> so we can wire that up ourselves
>
> There are a few others, but these come off the top of my head.
>
> On 26 April 2011 04:06, Kevin Bourrillion <kev...@google.com> wrote:
>
>
>
>
>
>
>
>
>
> > Here are some new things we're looking at including in release 10 of Guava,
> > slated for June 30:
>
> > Optional<T>:
>
> >http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/co...
>
> > Range<C>:
>
> >http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/co...
>
> >http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/co...
>
> > Uninterruptibles:
>
> >http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/co...
>
> > New allAsList() and successfulAsList() methods in Futures:
>
> > <http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/co...>
> >http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/co...
>
> > --
> > Kevin Bourrillion @ Google
> >http://guava-libraries.googlecode.com
>
> >  --
> > guava-...@googlegroups.com
> > Project site:http://guava-libraries.googlecode.com
> > This group:http://groups.google.com/group/guava-discuss
>
> > This list is for general discussion.
> > To report an issue:http://code.google.com/p/guava-libraries/issues/entry
> > To get help:http://stackoverflow.com/questions/ask(use the tag "guava")
>
> --
> cheers,
> - jed.

Tim Peierls

unread,
Apr 27, 2011, 9:53:31 AM4/27/11
to Jed Wesley-Smith, Kevin Bourrillion, guava-discuss
On Wed, Apr 27, 2011 at 1:44 AM, Jed Wesley-Smith <jed.wes...@gmail.com> wrote:
Kevin, it is fantastic to finally have a somewhat standard Option class in a common library, but almost every implementation I have seen follows the scala/haskell idiom of Option/Some/None. Is there any chance of following this convention rather than inventing a new mostly similar one?


I am not expecting all of the functionality, just the basic naming, use Option<T> with Some and None concrete implementations.

I think it's better not to raise the expectations of Scala and Haskell devotees by using such suggestive names.

 
Minor points:
- it can implement Supplier<T>

But should it? Anyone treating it as a supplier is bound to be disappointed by the way it can throw IllegalStateException.

 
- get(T defaultValue) reads better as getOrElse(T defaultValue)

Yes, or opt.getWithDefault(defVal) or opt.getDefaultingTo(defVal).

 
- please (please) add Option<S> transform(Function<T, S> f)
- or implement Iterable<T> so we can wire that up ourselves

Not sure what you're asking for here.

--tim

Blair Zajac

unread,
Apr 27, 2011, 10:07:52 AM4/27/11
to Jed Wesley-Smith, Kevin Bourrillion, guava-discuss

On Apr 26, 2011, at 10:44 PM, Jed Wesley-Smith wrote:

> Kevin, it is fantastic to finally have a somewhat standard Option class in a common library, but almost every implementation I have seen follows the scala/haskell idiom of Option/Some/None. Is there any chance of following this convention rather than inventing a new mostly similar one?
>
> http://www.scala-lang.org/api/current/scala/Option.html
>
> I am not expecting all of the functionality, just the basic naming, use Option<T> with Some and None concrete implementations.

You're suggesting renaming Optional to Option? I'm actually happy to see different names between Scala and Guava, it'll make it clearer in mixed code whose option it is.

>
> Minor points:
> - it can implement Supplier<T>
> - get(T defaultValue) reads better as getOrElse(T defaultValue)
> - please (please) add Option<S> transform(Function<T, S> f)

What about naming this map, to be consistent with Scala? I'm guessing transform() is the common name used throughout Guava?

> - or implement Iterable<T> so we can wire that up ourselves

You would want this in addition to transform(), if you don't care about transform()'s result?

Regards,
Blair

rwallace

unread,
Apr 27, 2011, 10:45:14 AM4/27/11
to guava-discuss
I would add a few other methods.

<B> B fold(Function<T, B> n, Function<T, B> s)
This is really the essence of the Optional type. With it, you can
implement everything else - get, getOrElse, isDefined, map/transform,
equals, hashCode, toString, everything else you can think of

<B> Option<B> flatMap(Function<T, Option<B>> f)
Call it flatMap or bind or whatever else you want, but this is another
fundamental, extremely useful method to have around as well.

Rich

On Apr 26, 10:44 pm, Jed Wesley-Smith <jed.wesleysm...@gmail.com>
wrote:
> Kevin, it is fantastic to finally have a somewhat standard Option class in a
> common library, but almost every implementation I have seen follows the
> scala/haskell idiom of Option/Some/None. Is there any chance of following
> this convention rather than inventing a new mostly similar one?
>
> http://www.scala-lang.org/api/current/scala/Option.html
>
> I am not expecting all of the functionality, just the basic naming, use
> Option<T> with Some and None concrete implementations.
>
> Minor points:
> - it can implement Supplier<T>
> - get(T defaultValue) reads better as getOrElse(T defaultValue)
> - please (please) add Option<S> transform(Function<T, S> f)
> - or implement Iterable<T> so we can wire that up ourselves
>
> There are a few others, but these come off the top of my head.
>
> On 26 April 2011 04:06, Kevin Bourrillion <kev...@google.com> wrote:
>
>
>
>
>
>
>
>
>
> > Here are some new things we're looking at including in release 10 of Guava,
> > slated for June 30:
>
> > Optional<T>:
>
> > New allAsList() and successfulAsList() methods in Futures:
>
> > <http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/co...>
> >http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/co...
>
> > --
> > Kevin Bourrillion @ Google
> >http://guava-libraries.googlecode.com
>
> >  --
> > guava-...@googlegroups.com
> > Project site:http://guava-libraries.googlecode.com
> > This group:http://groups.google.com/group/guava-discuss
>
> > This list is for general discussion.
> > To report an issue:http://code.google.com/p/guava-libraries/issues/entry
> > To get help:http://stackoverflow.com/questions/ask(use the tag "guava")
>
> --
> cheers,
> - jed.

Philipp Wendler

unread,
Apr 27, 2011, 11:51:50 AM4/27/11
to guava-...@googlegroups.com
Hi,

Am 27.04.2011 07:44, schrieb Jed Wesley-Smith:
> Kevin, it is fantastic to finally have a somewhat standard Option class in a
> common library, but almost every implementation I have seen follows the
> scala/haskell idiom of Option/Some/None. Is there any chance of following
> this convention rather than inventing a new mostly similar one?
>
> http://www.scala-lang.org/api/current/scala/Option.html
>
> I am not expecting all of the functionality, just the basic naming, use
> Option<T> with Some and None concrete implementations.

I like Optional<T> more than Option<T>. It reads more naturally like
"optional value of T". Also a class Option might be misunderstood to
designate configuration options, or it produces name clashes with
option-handling classes (for example, I have an annotation @Option that
is used for annotating fields which store configuration option values).

Greetings, Philipp

James Moore

unread,
Apr 27, 2011, 12:32:39 PM4/27/11
to Philipp Wendler, guava-...@googlegroups.com
On Wed, Apr 27, 2011 at 8:51 AM, Philipp Wendler <m...@philippwendler.de> wrote:
> I like Optional<T> more than Option<T>. It reads more naturally like
> "optional value of T".

I agree, but I think that's a problem, not a benefit.  Option to me implies that there is a fixed choice; you get A or B.  Optional is more vague.  To me it says maybe there may or may not be a thing there, possibly.

I think there's a general bias in favor of using nouns instead of adjectives for objects.

I also think there should be a small bias in favor of what other languages are already doing; Scala, OCaml/F# use Option.  Is there a reason to think those communities regret the choice and would rather have gone with Optional?

And I insist that the bikeshed be painted blue, even though I'm not doing the painting :-).

--
James Moore
ja...@restphone.com
http://jamesmoorecode.blogspot.com/

Colin Decker

unread,
Apr 27, 2011, 12:37:34 PM4/27/11
to guava-...@googlegroups.com
Er, "there may or may not be a thing there" is exactly what Optional is for!
.
-- 
Colin


James Moore

unread,
Apr 27, 2011, 12:46:00 PM4/27/11
to Colin Decker, guava-...@googlegroups.com
On Wed, Apr 27, 2011 at 9:37 AM, Colin Decker <cgde...@gmail.com> wrote:
Er, "there may or may not be a thing there" is exactly what Optional is for!

I'm trying to argue something that's very slightly different.  To me, it feels something like:

Optional: it may or may not be there.
Option: it is or is not there.

And I think the second is a slightly better match for the intention here.

Colin Decker

unread,
Apr 27, 2011, 1:01:30 PM4/27/11
to jamest...@gmail.com, guava-...@googlegroups.com
I don't think that "option" conveys that something is either there or not there at all though. An "option" is just one of any number of choices. "Optional" means that something is not required.

-- 
Colin

Kevin Bourrillion

unread,
Apr 27, 2011, 1:09:33 PM4/27/11
to Tim Peierls, Jed Wesley-Smith, guava-discuss
FYI.... Optional was the cause of possibly the single greatest conflagration on the internal Java libraries discussion lists ever.  Everyone, but everyone has a strong opinion on this thing.  I want to acknowledge the really awkward position it puts you all in to be presented with the result of all that churn without having the visibility into how it got that way.  Your fresh perspective on it is still beneficial, but often we're going to have to say... "sorry, we did think about this fully already, and decided against it" and I'm sorry if that's a drag.  It won't be like that every time....


On Wed, Apr 27, 2011 at 6:53 AM, Tim Peierls <t...@peierls.net> wrote:

Kevin, it is fantastic to finally have a somewhat standard Option class in a common library, but almost every implementation I have seen follows the scala/haskell idiom of Option/Some/None. Is there any chance of following this convention rather than inventing a new mostly similar one?


I am not expecting all of the functionality, just the basic naming, use Option<T> with Some and None concrete implementations.

I think it's better not to raise the expectations of Scala and Haskell devotees by using such suggestive names.

Tim nailed it.  We learned this lesson painfully.  We tried to appease the Haskell-and-such zealots, and found that our attempts to mimic their things only served to emphasize even more the remaining ways in which we still differ.  And it was pulling us away from just doing the best thing for Java.  At last, we settled on the decision you see in the Optional javadoc: "This class is not intended as a direct analogue of any existing "option" or "maybe" construct from other programming environments, though it may bear some similarities."

As a bonus, it lets us use the name Optional, which is practically an objectively superior name for this. :-)  Optional<Name> is an optional name.  That's exactly what it is.  It isn't an option name.  And note that the Java ethos values "prosiness" of code much more than other languages.


Minor points:
- it can implement Supplier<T>

But should it? Anyone treating it as a supplier is bound to be disappointed by the way it can throw IllegalStateException.

Tim, how do you do that?  Nailed it again; it would not be a well-behaved Supplier.  And in the case that you know it contains a value, it would then just end up being identical to Suppliers.ofInstance().  Just because something can implement an interface doesn't necessarily mean it should.


- get(T defaultValue) reads better as getOrElse(T defaultValue)

Yes, or opt.getWithDefault(defVal) or opt.getDefaultingTo(defVal).

I agree.  get(T) is the one method that bears a TODO comment in the source code saying that we need to still rename it.  Trouble is there are just too many possibilities to choose from.  :-)

  String callMeThis = optionalNickname.getWithDefault(firstName);
  String callMeThis = optionalNickname.getOrElse(firstName);
  String callMeThis = optionalNickname.getOr(firstName);
  String callMeThis = optionalNickname.or(firstName);
  String callMeThis = optionalNickname.orDefault(firstName);
  String callMeThis = optionalNickname.getOrDefault(firstName);
  String callMeThis = optionalNickname.getDefaultingTo(firstName);

More nominations?  I may actually just make a darn survey out of it.


--
Kevin Bourrillion @ Google

Kevin Bourrillion

unread,
Apr 27, 2011, 1:14:02 PM4/27/11
to jamest...@gmail.com, Philipp Wendler, guava-...@googlegroups.com
On Wed, Apr 27, 2011 at 9:32 AM, James Moore <jamest...@gmail.com> wrote:

I agree, but I think that's a problem, not a benefit.  Option to me implies that there is a fixed choice; you get A or B.  Optional is more vague.  To me it says maybe there may or may not be a thing there, possibly.

As pointed out, this seems to prove our point that Optional is the right name.

 
I think there's a general bias in favor of using nouns instead of adjectives for objects.

There's also a tendency to take the name that results from that -- OptionalReference -- and see if its level of "wieldiness" is appropriate for the kind of thing it's trying to be, and make concessions; like how the supremely "correct" Enumeration.getNextElement() got turned into Iterator.next().


I also think there should be a small bias in favor of what other languages are already doing; Scala, OCaml/F# use Option.  Is there a reason to think those communities regret the choice and would rather have gone with Optional?

That small bias was there; maybe even larger than small.  We paid the price.  Man, some people are really in love with their pet language.

 
And I insist that the bikeshed be painted blue, even though I'm not doing the painting :-).

Thank you for this. :-)

Of course, a bikeshed argument is one that isn't rooted in solid reasoning for why solution A is better than solution B, it's a "but I would have done it this way" kind of thing, motivated more by the speaker's desire to have had an influence on the outcome than by actual practical benefit, and I'm sure no one's doing that here!

--
Kevin Bourrillion @ Google

Kevin Bourrillion

unread,
Apr 27, 2011, 1:20:31 PM4/27/11
to Jed Wesley-Smith, guava-discuss
On Tue, Apr 26, 2011 at 9:11 PM, Jed Wesley-Smith <jed.wes...@gmail.com> wrote:

- please (please) add Option<S> transform(Function<T, S> f)

I hear you.  We felt it doesn't fit nicely on the Option class itself, though.  We are still hoping to finish up our FluentIterable, FluentFunction and FluentPredicate classes, and we suspect FluentFunction would be the "right" place for an apply(Optional<F>) method that returns Optional<T>.


- or implement Iterable<T> so we can wire that up ourselves

I'm personally receptive to the idea of an asList() method on Optional, but I'm not convinced one way or the other yet.


--
Kevin Bourrillion @ Google

Kevin Bourrillion

unread,
Apr 27, 2011, 1:25:35 PM4/27/11
to Jed Wesley-Smith, guava-discuss
On Wed, Apr 27, 2011 at 10:20 AM, Kevin Bourrillion <kev...@google.com> wrote:

I hear you.  We felt it doesn't fit nicely on the Option class itself,

Oh, no.

What have I done?


Kevin Bourrillion

unread,
Apr 27, 2011, 1:27:19 PM4/27/11
to jamest...@gmail.com, Colin Decker, guava-...@googlegroups.com
On Wed, Apr 27, 2011 at 9:46 AM, James Moore <jamest...@gmail.com> wrote:

On Wed, Apr 27, 2011 at 9:37 AM, Colin Decker <cgde...@gmail.com> wrote:
Er, "there may or may not be a thing there" is exactly what Optional is for!

I'm trying to argue something that's very slightly different.  To me, it feels something like:

Optional: it may or may not be there.
Option: it is or is not there.

I believe "option" much more strongly suggests something that can take on possibly many different values (I have an option for what color my new car should be) than does "optional".  Something being "optional" more strongly suggests a thing that can either be there or not ("an optional power moon-roof").


--
Kevin Bourrillion @ Google

Shimi

unread,
Apr 27, 2011, 1:49:08 PM4/27/11
to guava-discuss
I have been using nat pryce Maybe (https://github.com/npryce/maybe-
java) with guava everywhere. It goes so natural together. I find it
better then the proposed Optional.

Shimi

On Apr 27, 8:09 pm, Kevin Bourrillion <kev...@google.com> wrote:
> FYI.... Optional was the cause of possibly the single greatest conflagration
> on the internal Java libraries discussion lists ever. * *Everyone, but *
> everyone* has a strong opinion on this thing.  I want to acknowledge the
> really awkward position it puts you all in to be presented with the result
> of all that churn without having the visibility into how it got that way.
>  Your fresh perspective on it is still beneficial, but often we're going to
> have to say... "sorry, we did think about this fully already, and decided
> against it" and I'm sorry if that's a drag.  It won't be like that every
> time....
>
> On Wed, Apr 27, 2011 at 6:53 AM, Tim Peierls <t...@peierls.net> wrote:
>
> *
> *
>
> > Kevin, it is fantastic to finally have a somewhat standard Option class in
> >> a common library, but almost every implementation I have seen follows the
> >> scala/haskell idiom of Option/Some/None. Is there any chance of following
> >> this convention rather than inventing a new mostly similar one?
>
> >>http://www.scala-lang.org/api/current/scala/Option.html
>
> >> I am not expecting all of the functionality, just the basic naming, use
> >> Option<T> with Some and None concrete implementations.
>
> > I think it's better not to raise the expectations of Scala and Haskell
> > devotees by using such suggestive names.
>
> *
> *
> Tim nailed it.  We learned this lesson painfully.  We tried to appease the
> Haskell-and-such zealots, and found that our attempts to mimic their things
> only served to emphasize even more the remaining ways in which we still
> differ.  And it was pulling us away from just doing the best thing for Java.
>  At last, we settled on the decision you see in the Optional javadoc: "This
> class is not intended as a direct analogue of any existing "option" or
> "maybe" construct from other programming environments, though it may bear
> some similarities."
>
> As a bonus, it lets us use the name Optional, which is practically an *
> objectively* superior name for this. :-)  Optional<Name> is an optional
> name.  That's exactly what it is.  It isn't an option name.  And note that
> the Java ethos values "prosiness" of code much more than other languages.
> *
> *
> *
> *
>
> > Minor points:
> >> - it can implement Supplier<T>
>
> > But should it? Anyone treating it as a supplier is bound to be disappointed
> > by the way it can throw IllegalStateException.
>
> *
> *
> Tim, *how do you do that?*  Nailed it again; it would not be a well-behaved
> Supplier.  And in the case that you know it contains a value, it would then
> just end up being identical to Suppliers.ofInstance().  Just because
> something *can* implement an interface doesn't necessarily mean it should.
>
> *
> *
>
> > - get(T defaultValue) reads better as getOrElse(T defaultValue)
>
> > *
> > *
> > Yes, or opt.getWithDefault(defVal) or opt.getDefaultingTo(defVal).
>
> I agree.  get(T) is the one method that bears a TODO comment in the source
> code saying that we need to still rename it.  Trouble is there are just too
> many possibilities to choose from.  :-)
>
>   String callMeThis = optionalNickname.getWithDefault(firstName);
>   String callMeThis = optionalNickname.getOrElse(firstName);
>   String callMeThis = optionalNickname.getOr(firstName);
>   String callMeThis = optionalNickname.or(firstName);
>   String callMeThis = optionalNickname.orDefault(firstName);
>   String callMeThis = optionalNickname.getOrDefault(firstName);
>   String callMeThis = optionalNickname.getDefaultingTo(firstName);
>
> More nominations?  I may actually just make a darn *survey* out of it.

Maaartin G

unread,
Apr 27, 2011, 2:22:43 PM4/27/11
to guava-...@googlegroups.com
I like the name "otherwise" and the overload for otherwise(Maybe<T>), I like the integration with Predicate and Function. But the fact that unknown() creates always a new instance not equal to any other unknown() is strange and precludes the use as a null substitute in maps not allowing null. The public constructor may be a problem, too.

Kevin Bourrillion

unread,
Apr 27, 2011, 2:29:54 PM4/27/11
to Shimi, guava-discuss
Looks similar enough, but:

* As discussed, a name like "maybe" that perks up the ears of language zealots everywhere leads to pain and ruin
* Implementing Iterable directly, so as to allow "for" loops directly over it, might just produce misleading code.  When I see a for loop, I expect it's because I'm, you know, looping.  "If present, get" is probably just a clearer idiom.
* Given that, then a static method taking Iterable<Optional<T>> and returning Iterable<T> (containing only "present" values) seems reasonable
* The second overload of otherwise() seems fine to me. Not sure I like the name, but if we decide we like the two-overloads idea, that should help us narrow down the large field of names we have to consider.
* Other aspects were already discussed in this thread


Nat Pryce

unread,
Apr 27, 2011, 2:31:50 PM4/27/11
to guava-...@googlegroups.com
I wrote Maybe<T> to represent a known or unknown value, rather than a
present or not-present value. I implemented equality to have similar
semantics as SQL's NULL or IEEE floating point NaN -- you cannot say
that two unknown values are equal.

Ideally, equals for Maybe<T> would return Maybe<Boolean> but it's not
possible to do that in Java,

For Optional<T>, it makes sense for equals to return false when
applied to two "nothing" values.

As for the rest of the class, feel free to adopt any parts you feel
like. Assume the same license as Guava (Apache 2.0?).

--Nat.

> --
> guava-...@googlegroups.com
> Project site: http://guava-libraries.googlecode.com
> This group: http://groups.google.com/group/guava-discuss
>
> This list is for general discussion.
> To report an issue: http://code.google.com/p/guava-libraries/issues/entry
> To get help: http://stackoverflow.com/questions/ask (use the tag "guava")
>

--
http://www.natpryce.com

Louis Wasserman

unread,
Apr 27, 2011, 2:54:17 PM4/27/11
to guava-...@googlegroups.com
While I'm a Haskell devotee, and I love Haskell's Maybe, I'm going to defend both Kevin's implementation and his management style.  Pardon my rant.
  1. There is a design pattern, common in Java, in which a "null" value for a variable exclusively represents "not here."  Optional, as it is written, is perfectly designed to stand in for this pattern, while being safer and more difficult to screw up.  This is a common pattern in Java, and a depressingly easy one to screw up.
  2. Null-accepting alternatives would not be able to replace this pattern, and it's one that could use replacing.
  3. "Maybe" concepts from other languages aren't quite like Optional, or risk confusion with Optional, in their handling of null values.  "Pain and ruin," as Kevin put it.  (In Haskell, the closest analog to null is undefined, but Just undefined is still "present.")
  4. While I'd like Optional to be all kinds of things -- a functor!  Even a monad!  A burrito! -- I recognize that Java isn't always the most natural world for those things.
  5. If we're going to shoehorn those things into Java, we need, above all else, to carefully put those things in the most elegant, natural place possible, where they fit into the language as neatly as possible.  Putting something in anywhere but the best place we can manage is a Bad Thing.
  6. In Haskell, there's a concept called "point-free" syntax, in which we express a function without ever referring to any variables -- just expressing it as a composition of other functions, or the result of more complicated function operators than composition.  This syntax is also called "pointless" syntax, for the reason that it obfuscates terrifically if you don't use it sparingly.  If a functional programming style obfuscates in Haskell, a language meant for such things, then in Java it can only be an atrocity.
  7. I am against writing libraries that make it easier to write atrocities, except where there have been very convincing arguments that the benefits outweigh the consequences.  Thus, debate, but err on the side of "no atrocities."
That said: -1 to !Options.absent().equals(Options.absent()), and I'm not clear on what signature or meaning this "otherwise" method would have, though I like the name.

On Wed, Apr 27, 2011 at 1:22 PM, Maaartin G <graj...@seznam.cz> wrote:
I like the name "otherwise" and the overload for otherwise(Maybe<T>), I like the integration with Predicate and Function. But the fact that unknown() creates always a new instance not equal to any other unknown() is strange and precludes the use as a null substitute in maps not allowing null. The public constructor may be a problem, too.

Nat Pryce

unread,
Apr 27, 2011, 3:14:34 PM4/27/11
to Louis Wasserman, guava-...@googlegroups.com
On 27 April 2011 19:54, Louis Wasserman <wasserm...@gmail.com> wrote:
> ... I'm not

> clear on what signature or meaning this "otherwise" method would have,
> though I like the name.

Otherwise is the name I used for getOrElse in my Maybe<T> class,


--
http://www.natpryce.com

Dimitris Andreou

unread,
Apr 27, 2011, 3:35:23 PM4/27/11
to Louis Wasserman, guava-...@googlegroups.com
On Wed, Apr 27, 2011 at 11:54 AM, Louis Wasserman <wasserm...@gmail.com> wrote:
While I'm a Haskell devotee, and I love Haskell's Maybe, I'm going to defend both Kevin's implementation and his management style.  Pardon my rant.
  1. There is a design pattern, common in Java, in which a "null" value for a variable exclusively represents "not here."  Optional, as it is written, is perfectly designed to stand in for this pattern, while being safer and more difficult to screw up.  This is a common pattern in Java, and a depressingly easy one to screw up.
  2. Null-accepting alternatives would not be able to replace this pattern, and it's one that could use replacing.
  3. "Maybe" concepts from other languages aren't quite like Optional, or risk confusion with Optional, in their handling of null values.  "Pain and ruin," as Kevin put it.  (In Haskell, the closest analog to null is undefined, but Just undefined is still "present.")
  4. While I'd like Optional to be all kinds of things -- a functor!  Even a monad!  A burrito! -- I recognize that Java isn't always the most natural world for those things.
  5. If we're going to shoehorn those things into Java, we need, above all else, to carefully put those things in the most elegant, natural place possible, where they fit into the language as neatly as possible.  Putting something in anywhere but the best place we can manage is a Bad Thing.
  6. In Haskell, there's a concept called "point-free" syntax, in which we express a function without ever referring to any variables -- just expressing it as a composition of other functions, or the result of more complicated function operators than composition.  This syntax is also called "pointless" syntax, for the reason that it obfuscates terrifically if you don't use it sparingly.  If a functional programming style obfuscates in Haskell, a language meant for such things, then in Java it can only be an atrocity.
  7. I am against writing libraries that make it easier to write atrocities, except where there have been very convincing arguments that the benefits outweigh the consequences.  Thus, debate, but err on the side of "no atrocities."
That said: -1 to !Options.absent().equals(Options.absent()), and I'm not clear on what signature or meaning this "otherwise" method would have, though I like the name.

Another -1 to that from me. There is only one empty set, anything else would be assigning "information" (in the form of object identity) to nothing, taking away its nothingness. :) Optional got it right. 

From my side, I like:
- the name! Yes, I feel adjectives are cool, when coupled with type parameters (hey, the other week I wrote things like Striped<Lock>, Striped<Semaphore> and so, couldn't name it better).
- the refreshing absence of Functions/Predicates in method arguments :)

I love scala, I would wish all of us wrote scala instead, BUT in Java I prefer people using plain old if/else than writing things like fold(functionForIf, functionForElse). 

A method to turn this into Iterable though would be nice. I don't care about the for-each syntax, but having Iterables#concat work with lots of optional values would be sweet. I think it's a perception problem, and people can be educated (stackoverflow and javadocs would help), to make the perceived "weirdness" in extending Iterable vanish eventually. I would +1 going that way (but lets not turn this into a democracy!)

And lets hope Kevin or someone comes up with a slightly better name for get(default) though, that's all.

Colin Decker

unread,
Apr 27, 2011, 3:50:36 PM4/27/11
to Dimitris Andreou, Louis Wasserman, guava-...@googlegroups.com
A method to turn this into Iterable though would be nice. I don't care about the for-each syntax, but having Iterables#concat work with lots of optional values would be sweet. I think it's a perception problem, and people can be educated (stackoverflow and javadocs would help), to make the perceived "weirdness" in extending Iterable vanish eventually. I would +1 going that way (but lets not turn this into a democracy!)

But why bother with making it work with Iterables.concat() and educating people to use this slightly odd and unnatural way of turning an Iterable<Optional<T>> into an Iterable<T> when you can create a method that's specifically for doing that like Kevin mentioned? I don't know where it'd go or what it'd be called, but something like

   Iterable<T> allPresent(Iterable<Optional<? extends T>>)

To me, that expresses the intent a whole lot better than concat does and it doesn't require anything funny like making Optional implement Iterable or be convertible to an Iterable.

Louis Wasserman

unread,
Apr 27, 2011, 3:58:06 PM4/27/11
to Colin Decker, Dimitris Andreou, guava-...@googlegroups.com
+1 for the type of allPresent, if not the name.

Dimitris Andreou

unread,
Apr 27, 2011, 4:16:58 PM4/27/11
to Colin Decker, Louis Wasserman, guava-...@googlegroups.com
And will you suggest more methods if I mention #transform, #filter, #etc? :) Anyway, I don't mean to contribute any more to the length of this thread, so I'll leave it here.

Dimitris Andreou

unread,
Apr 27, 2011, 5:00:33 PM4/27/11
to Colin Decker, Louis Wasserman, guava-...@googlegroups.com

Ok, I'll add one more message. I suspect that the most common way one is going to end up having an iterable of optionals is using a transform function on an iterable of objects that contain an optional. So it would be a small cost in changing such a function from x.getOptionalFoo() to getOptionalFoo().asSet(), as/if needed. So let's ignore the subtyping I mentioned.

(Oh, instead of asList() though, i'd prefer an asSet() returning ImmutableSet, if something like this is added at all)

Sorry for the noise!

Ricardo Redder

unread,
Apr 27, 2011, 6:44:20 PM4/27/11
to guava-discuss
<B> B fold(Function<T, B> n, Function<T, B> s)
This is really the essence of the Optional type.  With it, you can
implement everything else - get, getOrElse, isDefined, map/transform,
equals, hashCode, toString, everything else you can think of

This one seems to be pretty good... I would vote for that...
Maybe a few will remember from another topic from this list "avoiding if else", that would be one way... I know the if-else is just hidden from us, but it might be more readable in some cases...

Regards,

--
Redder

Blair Zajac

unread,
Apr 27, 2011, 6:52:28 PM4/27/11
to Colin Decker, Dimitris Andreou, Louis Wasserman, guava-...@googlegroups.com
On 04/27/2011 12:50 PM, Colin Decker wrote:
> A method to turn this into Iterable though would be nice. I don't
> care about the for-each syntax, but having Iterables#concat work
> with lots of optional values would be sweet. I think it's a
> perception problem, and people can be educated (stackoverflow and
> javadocs would help), to make the perceived "weirdness" in extending
> Iterable vanish eventually. I would +1 going that way (but lets not
> turn this into a democracy!)
>
>
> But why bother with making it work with Iterables.concat() and educating
> people to use this slightly odd and unnatural way of turning an
> Iterable<Optional<T>> into an Iterable<T> when you can create a method
> that's specifically for doing that like Kevin mentioned? I don't know
> where it'd go or what it'd be called, but something like
>
> Iterable<T> allPresent(Iterable<Optional<? extends T>>)

or filterPresent()? allPresent() sounds like it should return a Boolean.

Blair

Colin Decker

unread,
Apr 27, 2011, 6:52:49 PM4/27/11
to Dimitris Andreou, Louis Wasserman, guava-...@googlegroups.com
Maybe I'm missing something, but I don't see how being able to get an Iterable<Iterable<T>> or an Iterable<Set<T>> instead of an Iterable<Optional<T>> changes anything as far as filtering, transforming, etc. You still have to use concat() to get an Iterable<T> at which point you're at the same place you would be if you'd used a special Iterable<Optional<T>> to Iterable<T> method. In both cases you can then transform and filter as you please.

-- 
Colin

Colin Decker

unread,
Apr 27, 2011, 7:02:27 PM4/27/11
to Blair Zajac, Dimitris Andreou, Louis Wasserman, guava-...@googlegroups.com
Yeah it does sound like something that might return a boolean. The name was very much a placeholder. =)

-- 
Colin

Jed Wesley-Smith

unread,
Apr 28, 2011, 12:44:00 AM4/28/11
to Tim Peierls, Kevin Bourrillion, guava-discuss
(forgot to reply to all)

On 27 April 2011 23:53, Tim Peierls <t...@peierls.net> wrote:
On Wed, Apr 27, 2011 at 1:44 AM, Jed Wesley-Smith <jed.wes...@gmail.com> wrote:
Kevin, it is fantastic to finally have a somewhat standard Option class in a common library, but almost every implementation I have seen follows the scala/haskell idiom of Option/Some/None. Is there any chance of following this convention rather than inventing a new mostly similar one?


I am not expecting all of the functionality, just the basic naming, use Option<T> with Some and None concrete implementations.

I think it's better not to raise the expectations of Scala and Haskell devotees by using such suggestive names.
 
Well, it already does a basic subset of Option (without the catamorphism support). 

 
- please (please) add Option<S> transform(Function<T, S> f)
- or implement Iterable<T> so we can wire that up ourselves

Not sure what you're asking for here.
 
One of the really nice things an Option can do for you is to chain function application. Given an Option<A> and an F<A, B> I can get an Option<B> trivially. If the original option is undefined then so is the subsequent one. There is no need for condition checking.

There are a few similar methods such as 'boolean exists(Predicate<A>)' and 'Option<A> filter(Predicate<A>)' that are very handy as well for tying options together.
-- 
cheers,
- jed.

Ray Conner

unread,
Apr 29, 2011, 1:40:54 PM4/29/11
to guava-discuss
Very nice.

I like the Range and Ranges classes, far fewer methods than my old
attempts. Mine had one significant difference; I had allowed the lower
bound to be higher than the upper bound. It's been so long, I honestly
can't remember why, but there was a use case. It may have been because
my range was specifically double's, and used primarily for spatial
operations (potentially infinite bounding boxes, domain for a
parametrically defined curve, etc.). It's not uncommon to transform or
project in some way and end up with a reflection, but it's important
to keep the "lower" and "upper" ends correctly associated, so that the
math comes out right.

The one non-metric method I have which you don't (I'm not asking for
it, just presenting it), is the equivalent of this pseudo-code.
"bound" isn't a great name, but you get the idea.
public C bound( C value ) {
if( value < lower ) return lower;
else if( value > upper ) return upper;
else return value;
}

+1 on Range *not* implementing Predicate. Ranges.asPredicate( Range )
seems to be a better place for that functionality.

- Ray A. Conner

On Apr 25, 2:06 pm, Kevin Bourrillion <kev...@google.com> wrote:
> Here are some new things we're looking at including in release 10 of Guava,
> slated for June 30:
>
> Optional<T>:http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/co...
>
> Range<C>:http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/co...http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/co...
>
> Uninterruptibles:http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/co...
>
> New allAsList() and successfulAsList() methods in Futures:
> <http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/co...>http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/co...
>
> --
> Kevin Bourrillion @ Googlehttp://guava-libraries.googlecode.com

Colin Decker

unread,
Apr 29, 2011, 1:59:35 PM4/29/11
to Ray Conner, guava-discuss
+1 on Range *not* implementing Predicate. Ranges.asPredicate( Range )
seems to be a better place for that functionality.

Why not have it implement Predicate? Static methods for getting a Predicate are ok when either the type doesn't already implement Predicate and can't be changed or when the type doesn't naturally represent a predicate (or there might be various ways to use it as a predicate). Range is both new and a good example of a natural predicate.
 

- Ray A. Conner

On Apr 25, 2:06 pm, Kevin Bourrillion <kev...@google.com> wrote:
> Here are some new things we're looking at including in release 10 of Guava,
> slated for June 30:
>
> Optional<T>:http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/co...
>
> Range<C>:http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/co...http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/co...
>
> Uninterruptibles:http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/co...
>
> New allAsList() and successfulAsList() methods in Futures:
> <http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/co...>http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/co...
>
> --
> Kevin Bourrillion @ Googlehttp://guava-libraries.googlecode.com

Kevin Bourrillion

unread,
Apr 29, 2011, 2:06:20 PM4/29/11
to Colin Decker, Ray Conner, guava-discuss
I feel pretty certain that anyone who knows what a Range<C> is and knows what a Predicate<C> is will have no trouble inferring exactly what it means to use a Range as a Predicate (i.e., contains()).  That is, it's "natural."  If I worried there was any ambiguity there, then I would have avoided implementing it for sure.

Aside: I feel the same way about our forthcoming Cache type, with respect to Function.  If you use a Cache<K, V> as a Function<K, V>, it seems pretty darn clear to me what that means.

Kevin Bourrillion

unread,
Apr 29, 2011, 2:07:25 PM4/29/11
to Ray Conner, guava-discuss
On Fri, Apr 29, 2011 at 10:40 AM, Ray Conner <ray.a....@gmail.com> wrote:

 public C bound( C value ) {
   if( value < lower ) return lower;
   else if( value > upper ) return upper;
   else return value;
 }

Nice... but, since our ranges aren't always closed, this could return a value not contained in the range, which is weird; to work right it would require a DiscreteDomain, which makes it unwieldy.

Ray Conner

unread,
Apr 29, 2011, 3:25:49 PM4/29/11
to guava-discuss
On Apr 29, 2:07 pm, Kevin Bourrillion <kev...@google.com> wrote:
> On Fri, Apr 29, 2011 at 10:40 AM, Ray Conner <ray.a.con...@gmail.com> wrote:
>
>  public C bound( C value ) {
>
> >    if( value < lower ) return lower;
> >    else if( value > upper ) return upper;
> >    else return value;
> >  }
>
> Nice... but, since our ranges aren't always closed, this could return a
> value not contained in the range, which is weird; to work right it would
> require a DiscreteDomain, which makes it unwieldy.

Which is pretty much why I wasn't actually encouraging it. I though
that, perhaps, there might be a way to do this that made sense, and I
just wasn't seeing it.

>
> --
> Kevin Bourrillion @ Google
> Java Core Libraries Teamhttp://guava-libraries.googlecode.com

- Ray

Ray Conner

unread,
Apr 29, 2011, 3:47:16 PM4/29/11
to guava-discuss
I'm not saying that it would be ambiguous. Clearly, it wouldn't.

Abusing the technical jargon, a range is a connected subset of a
totally ordered set. The concept of a set does lead obviously to a
"contains" predicate, but I don't normally think of a Set as a kind of
Predicate. If Predicate had existed in the JDK prior to the
development of the Collections framework, I would have been surprised
if Collection had extended that interface.

Maybe it's my math background. Given a set S, you say "if x is an
element of S", not "if S(x)". Regardless, it's just one person's
opinion. Other opinions are equally valid :)

- Ray
> >>http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/co....
> >> ..
>
> >> > Uninterruptibles:
> >>http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/co...
>
> >> > New allAsList() and successfulAsList() methods in Futures:
> >> > <
> >>http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/co...>
> >>http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/co...
>
> >> > --
> >> > Kevin Bourrillion @ Googlehttp://guava-libraries.googlecode.com
>
> >> --
> >> guava-...@googlegroups.com
> >> Project site:http://guava-libraries.googlecode.com
> >> This group:http://groups.google.com/group/guava-discuss
>
> >> This list is for general discussion.
> >> To report an issue:http://code.google.com/p/guava-libraries/issues/entry
> >> To get help:http://stackoverflow.com/questions/ask(use the tag "guava")
>
> >  --
> > guava-...@googlegroups.com
> > Project site:http://guava-libraries.googlecode.com
> > This group:http://groups.google.com/group/guava-discuss
>
> > This list is for general discussion.
> > To report an issue:http://code.google.com/p/guava-libraries/issues/entry
> > To get help:http://stackoverflow.com/questions/ask(use the tag "guava")

Louis Wasserman

unread,
Apr 29, 2011, 4:06:41 PM4/29/11
to Ray Conner, guava-discuss
On that note, a suggestion: Range should have a closure() method.

Kevin Bourrillion

unread,
Apr 29, 2011, 4:08:42 PM4/29/11
to Ray Conner, guava-discuss
I hear you, but I'm swayed by the usability advantages.  I think being able to pass "Ranges.greaterThan(5)" directly into any predicate-accepting method makes for nicely readable code.


To get help: http://stackoverflow.com/questions/ask (use the tag "guava")

Kevin Bourrillion

unread,
Apr 29, 2011, 4:09:27 PM4/29/11
to Louis Wasserman, Ray Conner, guava-discuss
... taking what and returning what?  Is it similar to Ranges.encloseAll()?

Dimitris Andreou

unread,
Apr 29, 2011, 4:23:22 PM4/29/11
to Ray Conner, guava-discuss

Sets are predicates and predicates are sets; these are equivalent and completely interchangeable notions. java.util.Set is a mathematical set (contains) *plus* enumeration. Thus it would have made complete sense for java.util.Set to subtype Predicate. It would also make sense to rename Predicate to Set and Set to IterableSet. Eg filter(predicate) would become filter(Set), 'filter anything contained in that set'. Hypothetically speaking of course.

Kevin Bourrillion

unread,
Apr 29, 2011, 4:27:47 PM4/29/11
to Dimitris Andreou, Ray Conner, guava-discuss
On Fri, Apr 29, 2011 at 1:23 PM, Dimitris Andreou <jim.a...@gmail.com> wrote:

Sets are predicates and predicates are sets; these are equivalent and completely interchangeable notions.

Yeah, but you're talking like a mathematician.  In Java-land when we say set we mean java.util.Set.  Meaning "sets" and "predicates" are only interchangeable for a fixed universe.

Kevin Bourrillion

unread,
Apr 29, 2011, 4:27:59 PM4/29/11
to Louis Wasserman, Ray Conner, guava-discuss
Warning: pure speculation follows.

We hope to keep going and ponder RangeSet eventually; something like:

public interface RangeSet<C extends Comparable<?>> {
  boolean contains(C value);
  boolean containsAll(RangeSet<C> other);

  // unlike Range, RangeSets are actually closed over these operations; how nice
  RangeSet<C> intersection(RangeSet<C> other);
  RangeSet<C> union(RangeSet<C> other);
  RangeSet<C> difference(RangeSet<C> other);
  RangeSet<C> complement();

  boolean disjoint(RangeSet<C> other);
  Range<C> span();

  SortedSet<Range<C>> ranges();
  Range<C> rangeContaining(C value);
}

As far as I can guess, we would leave it implementation-specific whether empty constituent ranges are disregarded and "abutting" groups of ranges coalesced (you have to do both or neither, or complement() is no longer precisely invertible).

Of course, there could be a mutable subtype, but I expect to focus on the immutable case first.

I'm tempted to add overloads of every RangeSet-accepting method to take a Range instead, but we can just see how prevalent the "doThis(RangeSets.of(singleRange))" pattern turns out to be, and address it then.  It's somewhat possible that Range could end up implementing RangeSet, as strange as that seems.

Bonus... RangeSet paves the way for Histogram to built around a Multiset<Range>.

Ray Conner

unread,
May 2, 2011, 10:40:14 AM5/2/11
to guava-discuss
I can't argue with that. The code is definitely cleaner.
> > > >> To get help:http://stackoverflow.com/questions/ask(usethe tag
> > "guava")
>
> > > >  --
> > > > guava-...@googlegroups.com
> > > > Project site:http://guava-libraries.googlecode.com
> > > > This group:http://groups.google.com/group/guava-discuss
>
> > > > This list is for general discussion.
> > > > To report an issue:
> >http://code.google.com/p/guava-libraries/issues/entry
> > > > To get help:http://stackoverflow.com/questions/ask(usethe tag

finnw

unread,
May 10, 2011, 1:49:43 PM5/10/11
to guava-discuss
On Apr 27, 6:09 pm, Kevin Bourrillion <kev...@google.com> wrote:
> I agree.  get(T) is the one method that bears a TODO comment in the source
> code saying that we need to still rename it.  Trouble is there are just too
> many possibilities to choose from.  :-)
>
>   String callMeThis = optionalNickname.getWithDefault(firstName);
>   String callMeThis = optionalNickname.getOrElse(firstName);
>   String callMeThis = optionalNickname.getOr(firstName);
>   String callMeThis = optionalNickname.or(firstName);
>   String callMeThis = optionalNickname.orDefault(firstName);
>   String callMeThis = optionalNickname.getOrDefault(firstName);
>   String callMeThis = optionalNickname.getDefaultingTo(firstName);
>
> More nominations?  I may actually just make a darn *survey* out of it.

I think the "get" name is fine, but firstName should be @NonNull.
This method is likely to be called inside logical expressions a lot,
e.g.
optionalNickName1.get(default1).equals(optionalNickName2.get(default2)),
so the shorter the better.
But why allow a null default? Wouldn't a toNullable() method be more
intuitive?
I assume you guys have thought about this already. Why did you choose
to do it that way?

Kevin Bourrillion

unread,
May 10, 2011, 2:03:00 PM5/10/11
to finnw, guava-discuss
Actually, all this is definitely in flux.  I'm currently liking this getup:

T get()
T or(T defaultValue)
Optional<T> or(Optional<T> secondChoice)
@Nullable T orNull()

There will definitely be significant updates to Optional soon.


To get help: http://stackoverflow.com/questions/ask (use the tag "guava")

Tim Peierls

unread,
May 10, 2011, 2:13:30 PM5/10/11
to Kevin Bourrillion, finnw, guava-discuss
Ah, that's nice.

Willi Schönborn

unread,
May 10, 2011, 2:22:09 PM5/10/11
to guava-...@googlegroups.com
On 10.05.2011 20:13, Tim Peierls wrote:
Ah, that's nice.

On Tue, May 10, 2011 at 2:03 PM, Kevin Bourrillion <kev...@google.com> wrote:
Actually, all this is definitely in flux.  I'm currently liking this
getup

Pun intended?

Ben Hardy

unread,
May 10, 2011, 2:38:03 PM5/10/11
to guava-discuss
Hi Kevin et al,

I was curious to know if there'd be transform and filter methods on Optional instances, that would operate the same way as Scala's Option.map and filter.  This'd be nice for chaining operations together rather than having to call a static transform method elsewhere like we currently have to do with Lists. Though I can certainly understand that there may not be a desire to depart from existing conventions in Guava.

e.g., just thinking out loud here

Function<String,String> fixCapitalization = ...
Function<String,String> trim = ...

Optional<String> customerName = Optional.of("fred");

// proposed way of doing things - the flow reads rather easily.
Optional<String> changed = customerName.transform(fixCaptilization).transform(trim);

// a little nicer than
Optional<String> changed = Optional.transform(Optional.transform(customerName, fixCaptilization), trim);

// also nicer than
Optional<String> changed = Optional.transform(customerName, Functions.compose(fixCaptilization, trim));

cheers
b

Todd Vierling

unread,
May 10, 2011, 3:43:00 PM5/10/11
to guava-...@googlegroups.com, finnw
On Tuesday, May 10, 2011 2:03:00 PM UTC-4, Kevin Bourrillion wrote:
Actually, all this is definitely in flux.  I'm currently liking this getup:
Optional<T> or(Optional<T> secondChoice)

The signature for that method should be:

Optional<T> or(Optional<? extends T> secondChoice)

This will require an explicit unsafe cast under the hood, but as Optional is immutable, that shouldn't be a problem.

Kevin Bourrillion

unread,
May 10, 2011, 3:59:46 PM5/10/11
to guava-...@googlegroups.com, finnw
Yeah, I just elided that in the email.

In theory one would like to be able to "or" together an Optional<Integer> and Optional<Double> to get an Optional<Number>, but there's nothing we can really do on that; you'll just have to cast your first Optional to Optional<Number> yourself before calling or().


Kevin Bourrillion

unread,
May 10, 2011, 4:01:21 PM5/10/11
to guava-...@googlegroups.com, finnw
On Tue, May 10, 2011 at 12:43 PM, Todd Vierling <t...@duh.org> wrote:

This will require an explicit unsafe cast under the hood, but as Optional is immutable, that shouldn't be a problem.

In fact, I did something in Optional's javadoc I'd never done before:

 * @param <T> the type of instance that can be contained. {@code Optional} is naturally covariant on
 *     this type, so it is safe to cast an {@code Optional<T>} to {@code Optional<S>} for any
 *     supertype {@code S} of {@code T}.  

I'm on the fence as to whether we should repeat that kind of text on other safely covariant and contravariant types in our library.

Todd Vierling

unread,
May 10, 2011, 5:21:33 PM5/10/11
to guava-...@googlegroups.com, finnw
On Tuesday, May 10, 2011 4:01:21 PM UTC-4, Kevin Bourrillion wrote:
This will require an explicit unsafe cast under the hood, but as Optional is immutable, that shouldn't be a problem.

In fact, I did something in Optional's javadoc I'd never done before:

 * @param <T> the type of instance that can be contained. {@code Optional} is naturally covariant on
 *     this type, so it is safe to cast an {@code Optional<T>} to {@code Optional<S>} for any
 *     supertype {@code S} of {@code T}.  

I'm on the fence as to whether we should repeat that kind of text on other safely covariant and contravariant types in our library.

Why this wasn't allowed as legal in Java generics is still beyond me:

@SuppressWarnings("unchecked")
public <T2 super T> Optional<T2> cast() { return (Foo)this; }

That would save a lot of these hassles by allowing safe-cast methods for the type bounds known to be safe conversions. It works for contravariant ("extends") situations, though those tend to be more rare. :-/

Dimitris Andreou

unread,
May 10, 2011, 5:28:04 PM5/10/11
to guava-...@googlegroups.com, finnw
I assume it would take too much work to make the java compiler sufficiently smart to grok co-/contra-variant type parameters. If you do want such a smart compiler, use scala.

Todd Vierling

unread,
May 10, 2011, 5:29:55 PM5/10/11
to guava-...@googlegroups.com, finnw
On Tuesday, May 10, 2011 5:21:33 PM UTC-4, Todd Vierling wrote:
Why this wasn't allowed as legal in Java generics is still beyond me:

@SuppressWarnings("unchecked")
public <T2 super T> Optional<T2> cast() { return (Optional)this; }

Oh, I missed a point. The above does only work for "extends" cases, but the following alternative worked in my test class, rewritten for Optional:

@SuppressWarnings("unchecked")
public <O2 extends Optional<? super T>> O2 cast() {
    return (Optional)this;
}

I tried these (my test class was named Foo, as implied by my previous post and corrected in the quote above ;)...

public Foo<Number> trycasting(Foo<Integer> fi) {
    Foo<? extends Object> fqo = fi.cast();
    Foo<Number> fn = fi.<Foo<Number>>cast();
    // Foo<Integer> f2i = fn.cast(); ... correctly fails
    return fi.cast();
}

The only downside I can see of this approach is that (as you see in the second cast call) you can't do <parametertype>cast(); it has to be the fully qualified type. But, uses of that cast syntax are rare anyway.

Todd Vierling

unread,
May 10, 2011, 5:32:07 PM5/10/11
to guava-...@googlegroups.com, finnw
On Tuesday, May 10, 2011 5:28:04 PM UTC-4, Dimitris Andreou wrote:
I assume it would take too much work to make the java compiler sufficiently smart to grok co-/contra-variant type parameters. If you do want such a smart compiler, use scala.

I do write scala code (even have a small utility library on github), but GWT doesn't compile scala code, and sometimes it's not viable for a given environment. Besides, those discussion groups are this way... =>

Thomas Jung

unread,
May 11, 2011, 3:14:15 AM5/11/11
to Kevin Bourrillion, guava-...@googlegroups.com, finnw
You can express the type parameters of an or method as:

@SuppressWarnings("unchecked")
<T, Y extends T, X extends T> Option<T> or(Option<Y> left, Option<X> right){
return left.isDefined() ? (Option<T>) left : (Option<T>) right;
}

The following tests work:

@Test public void or(){
Option<Double> l = Option.some(.2);
Option<Integer> r = Option.some(1);
Option<Double> n = Option.none();
Option<Number> or = this.<Number, Double, Integer> or(l, r);
assertEquals(l, or);
Option<Number> or2 = this.<Number, Double, Integer> or(n, r);
assertEquals(r, or2);
}

The eclipse compiler can infer the type parameter from or(l, r) but
javac can't. So it's somewhat useless.

Thomas

Kevin Bourrillion

unread,
May 11, 2011, 4:50:15 PM5/11/11
to Tim Peierls, finnw, guava-discuss
Would anyone care to weigh in on whether the same approach toward nullability seems valuable for Holder<T> (the mutable version of this, which really is just about exactly the same as AtomicReference<T>)?

We're considering taking the same approach, which ends up with Holder having something like 11 methods, or just going with the much simpler, "it holds a nullable reference" approach (making it even more exactly like A.R.).

Todd Vierling

unread,
May 11, 2011, 4:55:46 PM5/11/11
to guava-...@googlegroups.com, Tim Peierls, finnw
On Wednesday, May 11, 2011 4:50:15 PM UTC-4, Kevin Bourrillion wrote:
Would anyone care to weigh in on whether the same approach toward nullability seems valuable for Holder<T> (the mutable version of this, which really is just about exactly the same as AtomicReference<T>)?

I think it would only really apply if Holder was intended to be a mutable implementing subclass of Optional. Something that is just an indirection to a reference variable seems more like... just an indirection to a (nullable) reference variable.

We're considering taking the same approach, which ends up with Holder having something like 11 methods, or just going with the much simpler, "it holds a nullable reference" approach (making it even more exactly like A.R.).

Well, without the atomic test-and-set operations, and the overhead of doing value swaps with thread primitives. I had such a class in one of my utility libraries way back when, all based on a very simple superinterface:

public interface Cell<T> {
    public T get();
}

which, obviously, could be simply 'mixed in' to a subclass of something like Reference<T> or AtomicReference<T> with null values allowed. (I actually had a CheckedCell superinterface of it that declared "throws Exception", but the need for that was a bit less.)

Louis Wasserman

unread,
May 11, 2011, 4:54:56 PM5/11/11
to Kevin Bourrillion, Tim Peierls, finnw, guava-discuss
I'm going to say +0.5 for "taking the same approach with Holder" to avoid overlap with AtomicReference and avoid gratuitous redundancy.

Ray

unread,
May 11, 2011, 7:49:01 PM5/11/11
to guava-discuss
Kevin and Team, I just want to thank you all for your work on this.
Your efforts help make our code more robust, better performing, and
easier to maintain. I've noticed some of the somewhat heated
discussions, and want you to know that Guava's users do not all feel
the same sense of entitlement for you to provide the solutions that
meet our individual needs. You guys really do a first-rate job.

On Apr 25, 2:06 pm, Kevin Bourrillion <kev...@google.com> wrote:
> Here are some new things we're looking at including in release 10 of Guava,
> slated for June 30:
>
> Optional<T>:http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/co...
>
> Range<C>:http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/co...http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/co...
>
> Uninterruptibles:http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/co...

Maaartin G

unread,
May 11, 2011, 8:17:40 PM5/11/11
to guava-...@googlegroups.com, Tim Peierls, finnw
On Wednesday, May 11, 2011 10:55:46 PM UTC+2, Todd Vierling wrote:
On Wednesday, May 11, 2011 4:50:15 PM UTC-4, Kevin Bourrillion wrote:
Would anyone care to weigh in on whether the same approach toward nullability seems valuable for Holder<T> (the mutable version of this, which really is just about exactly the same as AtomicReference<T>)?

I think it would only really apply if Holder was intended to be a mutable implementing subclass of Optional. Something that is just an indirection to a reference variable seems more like... just an indirection to a (nullable) reference variable.

I don't think an immutable class (Option) should have a mutable subclass (Holder).  I don't like the other way round either, when it can be avoided (unlike in case of Set and ImmutableSet). In case Holder should be that similar to Option, I'd propose a common superclass AbstractXyz with subclasses MutableXyz and ImmutableXyz  (where Xyz=Option or Holder, whatever name is more appropriate). There's hardly more work needed for such a hierarchy and using inheritance is clearer than learning two very similar classes. In addition to the four  methods listed above there could be toMutable() and toImmutable() conversion methods.

Kevin Bourrillion

unread,
May 11, 2011, 8:23:59 PM5/11/11
to Ray, guava-discuss
I really appreciate that, Ray.  Thanks!

For the record though, I think the Guava user community is fantastic, and I have no complaints!



Project site: http://guava-libraries.googlecode.com
This group: http://groups.google.com/group/guava-discuss

This list is for general discussion.
To report an issue: http://code.google.com/p/guava-libraries/issues/entry
To get help: http://stackoverflow.com/questions/ask (use the tag "guava")

Todd Vierling

unread,
May 11, 2011, 8:46:38 PM5/11/11
to guava-...@googlegroups.com, Tim Peierls, finnw
On Wednesday, May 11, 2011 8:17:40 PM UTC-4, Maaartin G wrote:
I don't think an immutable class (Option) should have a mutable subclass (Holder).  I don't like the other way round either, when it can be avoided (unlike in case of Set and ImmutableSet). In case Holder should be that similar to Option, I'd propose a common superclass

That's closer to what I meant: if Optional and Holder are intended to be workalikes, they should inherit from a common API of some sort.

Tim Peierls

unread,
May 12, 2011, 9:59:59 AM5/12/11
to guava-...@googlegroups.com, finnw
I haven't understood what Holder brings to the table that AtomicReference doesn't. Is it that you want to be able to s/Optional/Holder/g after you decide that some category of values is @Nullable after all? Or the other way around? Or something else?

--tim

Kevin Bourrillion

unread,
May 12, 2011, 10:18:56 AM5/12/11
to Tim Peierls, guava-...@googlegroups.com, finnw
Not a lot, really, except GWT compatibility, a much shorter name (which matters to some degree), and the possibility of sharing Optional's cute little null-sidestepping features.  And no use of Unsafe to scare some users away...

We had been telling people to use AtomicReference<MyType> for this purpose for years, but we finally discovered that some users really just can't stand that, and were continuing to use 'new MyType[1]' in their code anyway.  We figured we'd rather see Holder<MyType> in their code than that.  Also, I admit that we were just a little bit tired of the question coming up over and over again. :-/

Incidentally, I have so far refused to make Holder's field volatile, on the grounds that anyone who needs that reeaally should be using AtomicReference instead.


Todd Vierling

unread,
May 12, 2011, 10:26:19 AM5/12/11
to Kevin Bourrillion, Tim Peierls, guava-...@googlegroups.com, finnw
On Thu, May 12, 2011 at 10:18 AM, Kevin Bourrillion <kev...@google.com> wrote:
> Incidentally, I have so far refused to make Holder's field volatile, on the
> grounds that anyone who needs that reeaally should be using AtomicReference
> instead.

Right. This does incur some runtime overhead, which a Holder wouldn't have.

I'm waffling on my own opinion of which way it should go, but:

* if a mutable version of Optional, both classes should implement a
common interface for the get-related methods

* if a non-atomic version of AtomicReference, it should be nullable
just like AtomicReference.

Tim Peierls

unread,
May 12, 2011, 10:33:08 AM5/12/11
to Kevin Bourrillion, guava-...@googlegroups.com, finnw
On Thu, May 12, 2011 at 10:18 AM, Kevin Bourrillion <kev...@google.com> wrote:
Incidentally, I have so far refused to make Holder's field volatile, on the grounds that anyone who needs that reeaally should be using AtomicReference instead.

OK, but aren't you worried that it's all too easy for the "new MyType[1]" crowd to think that they're on safer ground?

final Holder<MyType> result = ...;
exec.execute(new Runnable() {
    public void run() { result.set(computeResult()); } // poor man's submit
});
// Subsequent poll for result won't work -- no h-b edge between result.set and poll attempts.

I guess a big bold warning in Holder could defend against that.

--tim

Todd Vierling

unread,
May 12, 2011, 10:45:02 AM5/12/11
to Tim Peierls, Kevin Bourrillion, guava-...@googlegroups.com, finnw
On Thu, May 12, 2011 at 10:33 AM, Tim Peierls <t...@peierls.net> wrote:
>> Incidentally, I have so far refused to make Holder's field volatile, on
>> the grounds that anyone who needs that reeaally should be using
>> AtomicReference instead.
>
> OK, but aren't you worried that it's all too easy for the "new MyType[1]"
> crowd to think that they're on safer ground?
>
> final Holder<MyType> result = ...;
> exec.execute(new Runnable() {
>     public void run() { result.set(computeResult()); } // poor man's submit
> });
> // Subsequent poll for result won't work -- no h-b edge between result.set
> and poll attempts.

Effectively, it's "volatile" enough for most users. Since everything
is accessed by method (not field), the pre-set() value is not cachable
by external code.

Tim Peierls

unread,
May 12, 2011, 11:04:07 AM5/12/11
to Todd Vierling, Kevin Bourrillion, guava-...@googlegroups.com, finnw
I don't know what you mean. Unless there's some form of synchronization or volatile, set() in one thread won't be visible to get() in another. 

I can't see the Holder code, though. I assumed Kevin was implying no synch at all when he said no volatile.

My concern is that naive users would incorrectly assume the existence of memory effects.

--tim

Todd Vierling

unread,
May 12, 2011, 11:11:00 AM5/12/11
to Tim Peierls, Kevin Bourrillion, guava-...@googlegroups.com, finnw
On Thu, May 12, 2011 at 11:04 AM, Tim Peierls <t...@peierls.net> wrote:
> I don't know what you mean. Unless there's some form of synchronization or
> volatile, set() in one thread won't be visible to get() in another.

Huh?

http://java.sun.com/docs/books/jvms/second_edition/html/Overview.doc.html#17257

The frame of local variables in the execution of get() is flushed when
the method returns. When get() is invoked again, it will access the
field again from scratch. The importance of the volatile qualifier
comes in basically when code is executing a longer-lived method (the
field is accessed multiple times in the *same* method):

http://java.sun.com/docs/books/jvms/second_edition/html/Threads.doc.html#22258

That says, effectively, that volatile variables in the source code
must be compiled differently (they cannot be cached in the local
variable pool of the current frame; a "getfield" opcode must be
invoked every time).

Tim Peierls

unread,
May 12, 2011, 11:20:12 AM5/12/11
to Todd Vierling, Kevin Bourrillion, guava-...@googlegroups.com, finnw
We must be talking about different things. I mean that the following situation is fine:

final AtomicReference<Foo> fooHolder = new AtomicReference<Foo>(null);

Thread 1                             Thread 2
--------                             --------
fooHolder.set(new Foo());            ...
...                                  Foo foo = fooHolder.get();

But if you s/AtomicReference/Holder/g, it is broken (assuming no synch or volatile in the impl of Holder).

--tim

Todd Vierling

unread,
May 12, 2011, 11:23:56 AM5/12/11
to Tim Peierls, Kevin Bourrillion, guava-...@googlegroups.com, finnw
On Thu, May 12, 2011 at 11:20 AM, Tim Peierls <t...@peierls.net> wrote:
> We must be talking about different things. I mean that the following
> situation is fine:
> final AtomicReference<Foo> fooHolder = new AtomicReference<Foo>(null);
> Thread 1                             Thread 2
> --------                             --------
> fooHolder.set(new Foo());            ...
> ...                                  Foo foo = fooHolder.get();
> But if you s/AtomicReference/Holder/g, it is broken (assuming no synch or
> volatile in the impl of Holder).

And I'm saying that is incorrect, according to the JVM spec to which I
linked. Since get() and set() are _method calls_ rather than simple
field accesses, nothing about the field hidden inside Holder will be
cached by Thread2. This means Thread2, when it calls get() again, will
re-access the field from scratch, and _will_ see the new value set by
Thread1... regardless of whether the field is internally declared
volatile.

Kevin Bourrillion

unread,
May 12, 2011, 12:18:19 PM5/12/11
to Tim Peierls, Todd Vierling, guava-...@googlegroups.com, finnw
On Thu, May 12, 2011 at 8:04 AM, Tim Peierls <t...@peierls.net> wrote:
I don't know what you mean. Unless there's some form of synchronization or volatile, set() in one thread won't be visible to get() in another. 

I can't see the Holder code, though.

Kevin Bourrillion

unread,
May 12, 2011, 12:20:50 PM5/12/11
to Todd Vierling, Tim Peierls, guava-...@googlegroups.com, finnw
On Thu, May 12, 2011 at 7:26 AM, Todd Vierling <t...@duh.org> wrote:

* if a mutable version of Optional, both classes should implement a
common interface for the get-related methods

That they should do this was sort of an axiomatic truth for me, but when asked to justify the real benefits of creating a type hierarchy, I couldn't quite do it.  Can anyone explain convincingly why we should need to interface with a Holder or an Optional polymorphically?

Todd Vierling

unread,
May 12, 2011, 12:27:25 PM5/12/11
to Kevin Bourrillion, Tim Peierls, guava-...@googlegroups.com, finnw
On Thu, May 12, 2011 at 12:20 PM, Kevin Bourrillion <kev...@google.com> wrote:
> That they should do this was sort of an axiomatic truth for me, but when
> asked to justify the real benefits of creating a type hierarchy, I couldn't
> quite do it.  Can anyone explain convincingly why we should need to
> interface with a Holder or an Optional polymorphically?

I've run into plenty of instances, with my simpler nullable-cell type
tree, where immutable and mutable instances were both desirable, but I
wanted methods not doing mutable operations to accept a single
(read-only) interface in parameters to work with either one. Of
course, in my case there was only a get() method, but this seems to
extend to the Optional/Holder case too IMO.

Tim Peierls

unread,
May 12, 2011, 12:33:54 PM5/12/11
to Kevin Bourrillion, Todd Vierling, guava-...@googlegroups.com, finnw
On Thu, May 12, 2011 at 12:18 PM, Kevin Bourrillion <kev...@google.com> wrote:
On Thu, May 12, 2011 at 8:04 AM, Tim Peierls <t...@peierls.net> wrote:
I don't know what you mean. Unless there's some form of synchronization or volatile, set() in one thread won't be visible to get() in another. 

I can't see the Holder code, though.

voila:


It is NOT certain to stay in this form.

Thanks. So my concern about naive users misusing this class stand, but I think they could be addressed by promoting the parenthetical "(without the atomic operations and thread-safety)" to a separate, prominent warning clause. 

Todd, I don't think the JVMS is saying what you think it's saying. At any rate, the relevant spec is the memory model section of the JLS:


Note that if what you claimed was really true, we'd have to retract Java Concurrency in Practice.  :-)

--tim

Maaartin G

unread,
May 12, 2011, 5:48:12 PM5/12/11
to guava-...@googlegroups.com, Todd Vierling, Tim Peierls, finnw
On Thursday, May 12, 2011 6:20:50 PM UTC+2, Kevin Bourrillion wrote:
On Thu, May 12, 2011 at 7:26 AM, Todd Vierling <t...@duh.org> wrote:

* if a mutable version of Optional, both classes should implement a
common interface for the get-related methods

That they should do this was sort of an axiomatic truth for me, but when asked to justify the real benefits of creating a type hierarchy, I couldn't quite do it.  Can anyone explain convincingly why we should need to interface with a Holder or an Optional polymorphically?

I'd rather ask, what are the benefits of not using a  type hierarchy. I think it gets neither any easier for you  not for the users, who have to learn that Holder is in fact a mutable Option. Moreover, although I haven't used Option yet, I'm quite sure, there are many places where both are acceptable as parameters. Actually, I can hardly imagine an input parameter (i.e., not mutating the content), where only one of them can be used.

I'd prefer the following hierarchy:
- Option
- - ImmutableOption
- - MutableOption
- - - AtomicOption
where the last class would use a volatile content (and possibly implement some or all of the the AtomicReference methods).

The existence of AtomicReference doesn't make AtomicOption superfluous, just like the existence of a reference (i.e. taking a variable directly) doesn't make  Option   superfluous.
 

Maaartin G

unread,
May 12, 2011, 5:56:08 PM5/12/11
to guava-...@googlegroups.com, Tim Peierls, Kevin Bourrillion, finnw
I'm quite sure you're wrong. Method boundaries (unless synchronized) are completely transparent to the compiler, it's free to fetch everything and reorder and inline statements at will, as long as it maintains the single threaded semantics. Otherwise, each method call would be extremely costly on multicore machines (due to missed optimization chances, memory barriers, cache synchronization/flushing, ...).

Ray Conner

unread,
May 16, 2011, 6:00:50 PM5/16/11
to guava-discuss
I think I see the source of the confusion. Todd is correct when he
states:
"The frame of local variables in the execution of get() is flushed
when the method returns."

The disconnect is that we're not talking about memory in the frame of
local variables. That memory is inherently local to the thread and
cannot be shared, even if you wanted to. The field within the Holder
instance is not on the stack, not in that "frame of local variables"
at all. In fact, the fields of an object instance can't be on the
stack, although a reference to an object could be.

- Ray

Todd Vierling

unread,
May 18, 2011, 12:06:16 PM5/18/11
to guava-...@googlegroups.com
On Monday, May 16, 2011 6:00:50 PM UTC-4, Ray Conner wrote:
I think I see the source of the confusion. Todd is correct when he
states:
  "The frame of local variables in the execution of get() is flushed
when the method returns."

The field within the Holder
instance is not on the stack, not in that "frame of local variables"
at all. In fact, the fields of an object instance can't be on the
stack, although a reference to an object could be.

You're partly correct about my confusion. I was primarily conflating bytecode compilation (which has specific rules on volatile, in that every read access requires a getfield as opposed to caching in the local variable pool) with JIT's behavior (which may elide the flush of the reference, and turn multiple getfields into multiple accesses to a cached value).

James Moore

unread,
May 18, 2011, 12:27:08 PM5/18/11
to Kevin Bourrillion, Louis Wasserman, Ray Conner, guava-discuss
On Fri, Apr 29, 2011 at 1:27 PM, Kevin Bourrillion <kev...@google.com> wrote:
Warning: pure speculation follows.

We hope to keep going and ponder RangeSet eventually; something like:


It'd get used on my current project.  I've got text with start and stop times on words (subtitles for multiple speakers), and I need to do things like find gaps where no one's speaking.  RangeSet would come in handy.

-- 
James Moore
ja...@restphone.com
http://jamesmoorecode.blogspot.com/

Jed Wesley-Smith

unread,
May 19, 2011, 3:06:28 AM5/19/11
to guava-...@googlegroups.com
Todd, do you have a reference for the JIT behaviour of eliding flushes and caching multiple accesses to a volatile? That's a bit of a worry.




--
cheers,
- jed.

Todd Vierling

unread,
May 19, 2011, 11:12:54 AM5/19/11
to Jed Wesley-Smith, guava-...@googlegroups.com
On Thu, May 19, 2011 at 3:06 AM, Jed Wesley-Smith
<jed.wes...@gmail.com> wrote:
> Todd, do you have a reference for the JIT behaviour of eliding flushes and
> caching multiple accesses to a volatile? That's a bit of a worry.

>> You're partly correct about my confusion. I was primarily


>> conflating bytecode compilation (which has specific rules on volatile, in
>> that every read access requires a getfield as opposed to caching in
>> the local variable pool) with JIT's behavior (which may elide the flush
>> of the reference, and turn multiple getfields into multiple accesses to
>> a cached value).

I meant that JIT may elide the flush or turn multiple getfields into
cache hits for members _not_ marked "volatile". That's the difference
noted in the JVM spec cited to me earlier, chapter 14, which deals
with memory (rather than bytecode) aspects of "volatile".

Jed Wesley-Smith

unread,
May 19, 2011, 10:04:02 PM5/19/11
to Todd Vierling, guava-...@googlegroups.com
phew! thanks for clearing that up ;-)
--
cheers,
- jed.
Reply all
Reply to author
Forward
0 new messages