JEP 186: Collection Literals
Remi Forax
forax at univ-mlv.fr
Thu Jan 16 05:43:21 PST 2014
On 01/15/2014 11:56 PM, Samir Talwar wrote:
>
> On Wed, Jan 15, 2014 at 8:24 PM, Remi Forax <forax at univ-mlv.fr
> <mailto:forax at univ-mlv.fr>> wrote:
>
> On 01/15/2014 06:44 PM, Samir Talwar wrote:
> > I've wanted to chip in to this thread all day. Now I finally
> have time. :-D
> >
> > Remi: Overloads for `MyCollectionType.of(…)` are just pushing
> the work onto
> > the API designer. We should be able to do better than that. This
> sort of
> > thing is duplicated all over Guava too (I think in that case it
> was to
> > avoid unchecked warnings), and it's silly to expect everyone
> designing a
> > collection to do the same.
>
> It depends how you define silly.
> What I wanted to say is just that collection literal should not be
> more
> complex than adding several overloads. And I fear that this is not
> possible.
> And the warning is not an unchecked warning but a varargs warning, and
> for of() it can be disable by using @SafeVarargs.
>
>
> You're right. Sorry for the mix-up. I'm not sure what you mean by
> "more complex" though. Do you mean the code required in APIs to
> support collection literals? (If not, ignore the next bit.) I don't
> think there's really a comparison to be made here; one exists purely
> to fill a language hole, and one to hook into a language feature that
> would be otherwise unavailable.
If you prefer: when you weight a language feature, it's impact in term
of jdk code should not be neglected.
>
> >
> > Klaus: Agreed. Strings are fine in dynamically typed languages,
> but when we
> > have static typing, I'd much rather use something the compiler
> can check. I
> > imagine that, just like in most JavaScript applications, most
> cases will
> > expect a relatively small number of keys that are known ahead of
> time.
>
> The question was more, not to restrict keys to be String only but
> to acknowledge that most of the keys will be String.
>
>
> And I don't think this is true. When using string keys in JavaScript,
> Groovy, etc. this is done because strings are no less safe than, for
> example, enum values in a dynamically-typed language. In Java, etc.
> the rules are different. Enum values offer no real penalty and a whole
> load of compile-time benefits in most cases (i.e. where the keys are
> known ahead of time in options maps and the like). While I'm not sure
> that strings won't be more popular, I'd argue that's probably down to
> sloppiness and shouldn't be encouraged. Obviously, any type is a
> candidate for a map key, but I'd be upset if it was assumed to be a
> string and only processed as something else if there was some extra
> magic syntax (for example, `[(key): value]` in Groovy).
you use String to interact with end users, either at the beginning of a
program or at the end,
that's not fully true for an interactive program but that's basically
the idea.
If you use String in the middle, it's sloppiness.
If you use enum at the beggining of a program when you parse arguments
or config file by example,
it's sloppiness too because you will have to map the enum value to want
to do later in your program (and Java is stupid enough to let you do a
switch :( ) so doing the transformation String to what I want instead of
String to enum value to what I want is IMO better.
Now you can also use enums to decouple things, by example to cleanly
separate an application from a library code, in that case enums are fine.
>
> >
> > I am very much of the opinion that the concrete type of the object
> > shouldn't be dictated. I think it should maintain a similar style to
> > lambdas; that is that the type is determined by the context
> (left-hand
> > side, parameter type, etc.). I would like to see something
> better than a
> > cast (which is generally very long when generics get involved) for
> > occasions where the concrete type is ambiguous, as this is going
> to happen
> > much more often than with lambdas.
>
> you want to be able to do a diamond in a cast ?
>
>
> Not exactly. Often that's too late. For example, if I'm assigning to a
> variable of the type `List<Runnable<Integer>>`, then I can't just
> assign `[new DoThatThing(), new DoThatThing()]`. Nor can I cast it to
> `ArrayList<Runnable>` later, as it's already of the type
> `List<DoThatThing>`, and we can't vary the generic type. It needs to
> be done at construction time. Something like `new ArrayList<> [1, 2,
> 3]` would be more preferable, because then I can type `new
> ArrayList<Runnable> [x, y, z]`.
It's not too late if the cast is used as target type of the list you
want to create,
anyway it's ugly.
>
> >
> > I'd also like to avoid binding certain styles to specific
> interfaces; not
> > all of us use List, Set and Map every day. One notable exception
> is the
> > pcollections library, which defines persistent equivalents with
> interfaces
> > such as PVector, PSet, PMap, etc. and is a pretty good example
> of something
> > that others have hinted they'd like to see in the core Java
> library. To
> > that end, I'd like for every type to have the option of
> providing a builder
> > (could we re-use Collector, as Remi hints at?). I know there's the
> > possibility people will abuse this to make Java work like C++
> but honestly,
> > I don't think there's much danger. Most people are pretty good
> at following
> > conventions, even if they're terrible (Java beans spring to mind).
>
> I just say that we give up to try to find a common interface for
> injecting values for something more specific to stream.
>
>
> I don't know much about this. What would be the problems with using
> collectors?
wrong interface for what we want to do, too Stream specific.
>
>
> >
> > Finally, I think it's pretty clear that we need two distinct
> styles: one
> > for list-like collections and one for map-like ones. I'm a
> pretty big fan
> > of Groovy's `[a, b, c]` and `[a: 1, b: 2, c: 3]`. I don't think
> there's an
> > advantage to a specific syntax for sets because of the above.
> >
> > Cheers,
> >
> > — Samir.
>
> regards,
> Rémi
>
>
> And thanks again for humouring me. :-)
>
> — Samir.
Rémi
>
> >
> >
> >
> > On Wed, Jan 15, 2014 at 5:14 PM, Remi Forax <forax at univ-mlv.fr
> <mailto:forax at univ-mlv.fr>> wrote:
> >
> >> On 01/15/2014 06:04 PM, Per Bothner wrote:
> >>> On 01/15/2014 03:44 AM, Zhong Yu wrote:
> >>>> On Tue, Jan 14, 2014 at 7:17 PM, Per Bothner <per at bothner.com
> <mailto:per at bothner.com>> wrote:
> >>>>> For example, one could define:
> >>>>>
> >>>>> T v = { e1, ..., en}
> >>>>>
> >>>>> as syntactic sugar for:
> >>>>>
> >>>>> TB tmp = T.make_builder();
> >>>>> tmp.add(e1); ..; tmp.add(en);
> >>>>> T v = tmp.build();
> >>>> How is this any better than
> >>>>
> >>>> T.of(e1, ..., en);
> >>>>
> >>>> ? I don't see how the literal syntax helps code writers or code
> >>>> readers in this case.
> >>> I can think of two reasons:
> >>>
> >>> (1) Target-typing means you don't have to redundantly specify T:
> >>>
> >>> T v = { e1, ..., en};
> >>>
> >>> vs
> >>>
> >>> T v = T.of(e1, ..., en);
> >>>
> >>> (2) Using the T.of form requires allocating an array,
> >>> which is then thrown away.
> >>>
> >>> I don't think (2) is a major justification. (1) may not
> >>> be enough to justify a new language feature by itself,
> >>> though one could argue it's a natural extension of the
> >>> existing syntax for arrays.
> >> I disagree for (1), if you take a look to java.util.EnumSet by
> example,
> >> you will see that there are multiple overloads of 'of' to avoid
> to allocate
> >> an array in the common cases.
> >>
> >> Rémi
> >>
> >>
> >>
> >>
>
>
>
More information about the lambda-dev
mailing list