If generics had been used to restrict types in collections, fine but
people were using the <? extends Blah> and <? super Blah> too much
making things more complicated. Add to this the reification issue
mentioned previously.
Personally I think a language change should only be introduced if it
reduces the complexity (sometimes boiler plate isnt the end of the
world as long as you know what it does). I suspect closures will end
up being the next generics debacle.
R
However, the ability of whatever proposal makes it to be expanded
later to support of course isn't, and this is in fact a (minor) aspect
of the closure debates - how much do we paint ourselves into a corner
if we adapt closure proposal X?
On May 25, 4:27 pm, Viktor Klang <viktor.kl...@gmail.com> wrote:
> I also want to add the debate regarding non-local returns.
>
> > javaposse+...@googlegroups.com<javaposse%2Bunsubscribe@googlegroups .com>
Rakesh, as I already said, closures itself are in. Folks like you that
think generics sucked and closures are too complicated lost.
Fortunately.
There's *some* merit in objecting based on complexity
Why must it always be the case (in Java at least) that new functionality so often seems to come with a whole bucketload of new boilerplate as well? Other languages have already shown us that this needn't be the case, and that features can be combined to offer even more elegance then either one by itself.
The enhanced-for loop was a step in the right direction, allowing me to write smaller and more elegant code.Generics, on the other hand...
co- and contravariance are inherently complex. You can't make them non-
complex. See scala, haskell, and any other language with them. You
could go without it altogether, but then we have a dynamic typing
system - a system where by you do not know at write time what the
types of things are, and you are instead forced to re-assert the type,
over and over again. In python, a type assertion is trivial, by
writing something like:
foo[0].bar()
you are asserting that the first entry in the 'foo' list is currently
referencing an object which has a 'bar' entry, and that this 'bar'
entry is an executable function.
java does not work that way. Scala does not work that way. Haskell
does not work that way. Java DID work that way, at least in situation
where generics are now used. This is what you used to have to do:
((Foo)foo.get(0)).bar()
unwieldy and ugly, but that's a syntax issue. More to the point is
that, in a strongly and statically typed language, you are
nevertheless forced into making runtime type assertions. This does not
smack of a consistent language (the very consistency Kevin, Rakesh,
and Viktor seem to want!). Generics gets us back to:
foo.get(0).bar()
which is as it ought to be. If you want this to work correctly, then
you need generics. Show me a language that's statically typed which
nevertheless avoids generics. It'll be about as complex as generics is
(though reification _CAN_ help; lack of reification is a separate
issue, to wit: Java has raised backwards compatibility above all other
concerns. Hem and haw about other languages doing it better all you
want, but when you are the world's most popular programming language,
especially in large teams, you can't break old code. It would have
been great if java had more support to evolve the language, but it
doesn't, and more to the point, few other languages do. That's a hard
nut to crack).
On May 26, 5:29 pm, Kevin Wright <kev.lee.wri...@googlemail.com>
wrote:
> There's *some* merit in objecting based on complexity
>
> Why must it always be the case (in Java at least) that new functionality so
> often seems to come with a whole bucketload of new boilerplate as well?
> Other languages have already shown us that this needn't be the case, and
> that features can be combined to offer even more elegance then either one by
> itself.
>
> The enhanced-for loop was a step in the right direction, allowing me to
> write smaller and more elegant code.
> Generics, on the other hand...
>
> On 26 May 2010 15:41, Viktor Klang <viktor.kl...@gmail.com> wrote:
> >> javaposse+...@googlegroups.com<javaposse%2Bunsubscribe@googlegroups .com>
> >> .
> >> > >> For more options, visit this group athttp://
> >> groups.google.com/group/javaposse?hl=en.
>
> >> > > --
> >> > > You received this message because you are subscribed to the Google
> >> Groups "The Java Posse" group.
> >> > > To post to this group, send email to java...@googlegroups.com.
> >> > > To unsubscribe from this group, send email to
> >> javaposse+...@googlegroups.com<javaposse%2Bunsubscribe@googlegroups .com>
> >> .
> >> > > For more options, visit this group athttp://
> >> groups.google.com/group/javaposse?hl=en.
>
> >> --
> >> You received this message because you are subscribed to the Google Groups
> >> "The Java Posse" group.
> >> To post to this group, send email to java...@googlegroups.com.
> >> To unsubscribe from this group, send email to
> >> javaposse+...@googlegroups.com<javaposse%2Bunsubscribe@googlegroups .com>
> >> .
> >> For more options, visit this group at
> >>http://groups.google.com/group/javaposse?hl=en.
>
> > --
> > Viktor Klang
> > | "A complex system that works is invariably
> > | found to have evolved from a simple system
> > | that worked." - John Gall
>
> > Akka - the Actor Kernel: Akkasource.org
> > Twttr: twitter.com/viktorklang
>
> > --
> > You received this message because you are subscribed to the Google Groups
> > "The Java Posse" group.
> > To post to this group, send email to java...@googlegroups.com.
> > To unsubscribe from this group, send email to
> > javaposse+...@googlegroups.com<javaposse%2Bunsubscribe@googlegroups .com>
> > .
> > For more options, visit this group at
> >http://groups.google.com/group/javaposse?hl=en.
>
> --
> Kevin Wright
>
> mail/google talk: kev.lee.wri...@googlemail.com
> wave: kev.lee.wri...@googlewave.com
> skype: kev.lee.wright
> twitter: @thecoda
List<String> list = new ArrayList<>();
(Backwards compatibility again rears its head here: new ArrayList()
wasn't possible because in current java that means: "raw type", and
backwards compatibility means semantic means cannot change. If I were
the dictator I'd drop it here, but I'm not, and while I don't agree I
can see why its done this way).
Co/Contravariance is how the world works. You can't just wave your
hand and make it go away. It is entirely possible to say: I take a
list and I add integers to it. You can supply such a method with a
List containing anything from Integer on down to Object and nothing
will break, hence you need a way to say: List<? super Integer>. If you
couldn't say that, you lose the ability to create a method that says:
I take any list that will let me add integers to it. What do you
propose, exactly? Drop 'extends' and 'super' altogether? There are
massive amounts of things you can then no longer do. For example, you
then can't run someNumberList.addAll(someIntegerList). Alternatively
you make generics a glorified comment and don't do any compile-time
checking at all, instead relying entirely on runtime exceptions.
That's one way to design a language. I suggest you use jython instead
of living in the fantasy that java is somehow dynamic, or should be.
It's true the error messages could use some more support, but compared
to other languages, javac's messages are stellar, so evidently that's
a hard thing to get right. I am of half a mind to dive into javac
itself and send some patches; javac is now open source, so, anyone can
contribute!
Interop: Yup. It's a pain, isn't it?
On May 26, 5:54 pm, Kevin Wright <kev.lee.wri...@googlemail.com>
wrote:
> Generics have 3 big issues (from memory)
>
> - Having specified the type parameters on declaring a variable, they must
> then be repeated when instantiating it.
>
> - Co/Contravariance (i.e. ArrayList<X extends ParentType>). Not so bad on
> collections, but a nightmare for more advanced structures where USERS have
> to get the right balance of <X extends T> vs <X super T>. Error messages
> here if you get it wrong are often less than helpful.
>
> - Interop with non-genericised legacy code - 'nuff said!
>
> Full kudos to Google Collections though. They do manage to take away much
> of the pain from the first two points, though some people would consider the
> API to be non-idiomatic Java.
>
> On 26 May 2010 16:41, Alexey Zinger <inline_f...@yahoo.com> wrote:
>
>
>
> > Generics are complex (more to produce API than consume), but I don't think
> > it's fair to say that all it did was add boilerplate. As a consumer of
> > generified API, I hardly ever see casts anymore (which should count as a
> > reduction in boilerplate as well as an improvement in type safety -- one of
> > Java's cornerstones), I don't have to express in comments what is now both a
> > concrete expression in the code and is picked up by javadoc. It has made
> > light structural typing convenient (rolling your own Pair-like constructs).
>
> > Alexey
> > 2001 Honda CBR600F4i (CCS)
> > 2002 Suzuki Bandit 1200S
> > 1992 Kawasaki EX500
> >http://azinger.blogspot.com
> >http://bsheet.sourceforge.net
> >http://wcollage.sourceforge.net
>
> > ------------------------------
> > *From:* Kevin Wright <kev.lee.wri...@googlemail.com>
> > *To:* java...@googlegroups.com
> > *Sent:* Wed, May 26, 2010 11:29:52 AM
> > *Subject:* Re: [The Java Posse] Re: "The closure debate is pants" - No, no
> > it isn't.
>
> > There's *some* merit in objecting based on complexity
>
> > Why must it always be the case (in Java at least) that new functionality so
> > often seems to come with a whole bucketload of new boilerplate as well?
> > Other languages have already shown us that this needn't be the case, and
> > that features can be combined to offer even more elegance then either one by
> > itself.
>
> > The enhanced-for loop was a step in the right direction, allowing me to
> > write smaller and more elegant code.
> > Generics, on the other hand...
>
> > On 26 May 2010 15:41, Viktor Klang <viktor.kl...@gmail.com> wrote:
> >>> javaposse+...@googlegroups.com<javaposse%2Bunsubscribe@googlegroups .com>
> >>> .
> >>> > >> For more options, visit this group athttp://
> >>> groups.google.com/group/javaposse?hl=en.
>
> >>> > > --
> >>> > > You received this message because you are subscribed to the Google
> >>> Groups "The Java Posse" group.
> >>> > > To post to this group, send email to java...@googlegroups.com.
> >>> > > To unsubscribe from this group, send email to
> >>> javaposse+...@googlegroups.com<javaposse%2Bunsubscribe@googlegroups .com>
> >>> .
> >>> > > For more options, visit this group athttp://
>
> ...
>
> read more »
Repetition of generics in type declaration and object instantiation go
away in java 7. This is already in the java 7 nightlies:
List<String> list = new ArrayList<>();
(Backwards compatibility again rears its head here: new ArrayList()
wasn't possible because in current java that means: "raw type", and
backwards compatibility means semantic means cannot change. If I were
the dictator I'd drop it here, but I'm not, and while I don't agree I
can see why its done this way).
Co/Contravariance is how the world works. You can't just wave your
hand and make it go away. It is entirely possible to say: I take a
list and I add integers to it. You can supply such a method with a
List containing anything from Integer on down to Object and nothing
will break, hence you need a way to say: List<? super Integer>. If you
couldn't say that, you lose the ability to create a method that says:
I take any list that will let me add integers to it. What do you
propose, exactly? Drop 'extends' and 'super' altogether? There are
massive amounts of things you can then no longer do. For example, you
then can't run someNumberList.addAll(someIntegerList). Alternatively
you make generics a glorified comment and don't do any compile-time
checking at all, instead relying entirely on runtime exceptions.
That's one way to design a language. I suggest you use jython instead
of living in the fantasy that java is somehow dynamic, or should be.
To unsubscribe from this group, send email to javaposse+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/javaposse?hl=en.
I don't think I understand what you're asking / pointing out.
On May 27, 7:32 am, Viktor Klang <viktor.kl...@gmail.com> wrote:
> ...
>
> read more »
I don't think the closure debates include anything on verbosity of
generics, that's project coin's bailiwick.
> ...
>
> read more »
--
You received this message because you are subscribed to the Google Groups "The Java Posse" group.
To post to this group, send email to java...@googlegroups.com.
To unsubscribe from this group, send email to javaposse+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/javaposse?hl=en.
On May 27, 2:15 pm, Viktor Klang <viktor.kl...@gmail.com> wrote:
> ...
>
> read more »
The obvious answer here is: Java uses call-site variance
On 27 May 2010 19:16, "Reinier Zwitserloot" <rein...@gmail.com> wrote:
I haven't seen any proposals back then or now or know of any languages
that use "call site variance". Can you elaborate a bit on what this
means?
On May 27, 2:15 pm, Viktor Klang <viktor.kl...@gmail.com> wrote:
> On Thu, May 27, 2010 at 2:03 PM, Reinier Zwitserloot <reini...@gmail.com>wrote:
>
> > I don't think the closure debates include anything on verbosity of
> > generics, that's projec...
> ...
>
> read more »
--
You received this message because you are subscribed to the Google Groups...
On May 27, 2:39 pm, Kevin Wright <kev.lee.wri...@googlemail.com>
wrote:
> The obvious answer here is: Java uses call-site variance
>
> ...
>
> read more »
--
You received this message because you are subscribed to the Google Groups "The Java Posse" group.
To post to this group, send email to java...@googlegroups.com.
To unsubscribe from this group, send email to javaposse+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/javaposse?hl=en.
Ah, that helps.
There remain things you cannot do with that which are perfectly
possible with java's generics. For example:
someNumberList.addAll(someIntegerList);
For that to work, a List<Integer> has to be some sort of List<Number>,
so List would need to be declared as List[+A]. However, if you do
that, you break things:
List<Number> n = new ArrayList<Number>();
List<Integer> i = n; //legal if List is declared as List[+T].
n.add(someDouble);
i.get(0); //invisible ClassCastException because we caused heap
pollution!
It would have been fine if List was immutable. But it isn't. Further
complicating matters, if we lived in a perfect world and the list
hierarchy was split into:
interface List //Contains only the 'read' methods and implies neither
immutability nor mutability
interface ImmutableList extends List //Does not add any methods, but
implies immutability
interface MutableList extends List //Adds set, clear, add, addAll,
retain, etc methods, implies mutability
Then if List was declared as List[+T] you'd still run into trouble
because there's a mutable subtype of it. Therefore, List would have to
remain List[T], but then ImmutableList overrides this with List[+T].
That would get very hairy very fast, and be a not-fun source of
puzzlers. Instead you'd have to get rid of List altogether and have
two completely separate trees: ImmutableList and MutableList.
Possible, but a gigantic departure from how java works today, and also
a cost.
--
You received this message because you are subscribed to the Google Groups "The Java Posse" group.
To post to this group, send email to java...@googlegroups.com.
To unsubscribe from this group, send email to javaposse+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/javaposse?hl=en.