The Artima Developer Community
Sponsored Link

Weblogs Forum
Simplyfing Java Generics by Eliminating Wildcards

33 replies on 3 pages. Most recent reply: Jul 19, 2008 7:16 PM by Howard Lovatt

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 33 replies on 3 pages [ « | 1 2 3 | » ]
Rob Bygrave

Posts: 1
Nickname: xrob
Registered: Nov, 2006

Re: Simplyfing Java Generics by Eliminating Wildcards Posted: Jan 24, 2008 2:24 AM
Reply to this message Reply
Advertisement
In removing wildcards... is this the same as saying every generic type would be co variant?

In which case, another way of looking at it is ... when (if ever) do you NOT want covariance? AKA What are we giving up by losing wildcards?

I'm thinking that reading behaviours (your sum function etc) typically benefit from covariance. What about modifying behaviours? I guess your point is that typically you have to be careful when writing modifying behaviours (your point being ArrayStoreException is rare).

My gut instinct says you are right...

Howard Lovatt

Posts: 321
Nickname: hlovatt
Registered: Mar, 2003

Re: Simplyfing Java Generics by Eliminating Wildcards Posted: Jan 24, 2008 4:00 PM
Reply to this message Reply
@Rob,

Your reading is what I was trying to convey

Neal Gafter

Posts: 12
Nickname: gafter
Registered: Oct, 2003

Re: Simplyfing Java Generics by Eliminating Wildcards Posted: Feb 6, 2008 3:32 PM
Reply to this message Reply
The first quote was from someone using Generics without wildcards. Both Josh Bloch and you somehow conclude that the removal of a feature that has nothing to do with the author's problems would somehow resolve his issues. That's a leap of logic I simply cannot understand. I just can't.

Howard Lovatt

Posts: 321
Nickname: hlovatt
Registered: Mar, 2003

Re: Simplyfing Java Generics by Eliminating Wildcards Posted: Feb 7, 2008 12:47 PM
Reply to this message Reply
@Neal,

My comments in the background section were the quote is used, and I assume Joshua Bloch's in his presentation, were about the general complexity of generics. Just below the quote I said "The examples that Joshua chose mainly involved wildcards ...". I added the emphasis to mainly for this post it wasn't in the original blog. This sentence is meant to link the general background to the specific topic of the blog. Sorry if that wasn't clear.

With regard to the original quotation; it is about generic complexity in general, but the specific example is about recursive definitions. Recursive definitions are something else it would be nice to eliminate, but I don't know how - any suggestions? Also I would like to see erasure erased.

I have to say that I was originally much keener on Generics than I am now; having used them for a number of years. The gain I get from increased type safety is heavily offset by the complexity.

Fred Garvin

Posts: 52
Nickname: fredgarvin
Registered: Jan, 2008

Re: Simplyfing Java Generics by Eliminating Wildcards Posted: Feb 8, 2008 2:41 PM
Reply to this message Reply
The bottom line is we like a static type system when it *helps* us write code. We tend not to like it so much when it impedes progress by confusing us, as Josh points out in his talk.

Indeed, variance and generics make a complex mixture no matter how you approach it. The approach adopted in Java incorporates what is called use-site variance via wildcards. Use-site variance, essentially, places the burden on the user of generic types (user = you and me) to specify variance constraints. Thus, it is quite surprising Sun went with this approach given generics exist primarily to improve our ability to read and write code using, not writing, libraries of generic types. The wildcard approach also leaves us with some very peculiar "features". For instance, take a peek at java.util.List.indexOf( Object o ). Ask yourself why the argument is of type Object and not E as it should be in a perfect world. I'll leave the answer as an exercise to the reader.

Another approach involves definition-site variance where more of the burden is placed on the generic class author where it belongs. Still, though, there's an awful lot of complexity involved that leaks out into our code.

Alas, at the end of the day variance and generics leaves us with complexity we probably would be better off without -- it's not helping us.

What would help us is trading off a little type-safety for a lot of usability, which IMO is exactly what is proposed here. Parametric covariance a la arrays = bliss.

Fwiw, the best alternative I've seen aside from the superior array aproach is here http://research.microsoft.com/~akenn/generics/ECOOP06.pdf
It's still too complex for my taste, however; I hope it never sees the light of day.

Dale Gerdemann

Posts: 1
Nickname: dalger
Registered: Feb, 2008

Re: Simplyfing Java Generics by Eliminating Wildcards Posted: Feb 12, 2008 7:25 AM
Reply to this message Reply
I was very glad to discover this blog, since the running example was based on a post I made about a year ago at bugs.sun.com/bugdatabase/view_bug.do?bug_id=4617197. I'm actually more concerned about the interaction of immutables with the Liskov Substitution Principle than I am in wildcards. We know that Java doesn't allow List<Integer> to be a subtype of List<Number>. But to what extent can one work around this implementation. Suppose you make a non-generic class for List<Integer>:

class ImmutableListInteger extends ImmutableList<Number> {
...
}

It appears that most everything will work okay, but how can you implement iterable and ensure that the Iterator returns Integer's?

And, as for wildcards: My opinion is that if you read Naftalin and Wadler's book and practice a bit, you will get the idea. But Naftalin and Wadler don't know everything. I wrote to them about the Liskov<=>Immutable interaction before I posted to the Sun page, and they were surprised. They clearly had not thought about the issue.

Dale Gerdemann

Howard Lovatt

Posts: 321
Nickname: hlovatt
Registered: Mar, 2003

Re: Simplyfing Java Generics by Eliminating Wildcards Posted: Feb 12, 2008 5:45 PM
Reply to this message Reply
@Dale,

I am also (as well as the author of this blog) the author of the immutable proposal and as I said on that page below your post, you are right. I also mentioned in my reply on the immutable blog my misgivings about the generic typing. This blog represents my further thoughts on that subject.

Howard Lovatt

Posts: 321
Nickname: hlovatt
Registered: Mar, 2003

Re: Simplyfing Java Generics by Eliminating Wildcards Posted: Feb 12, 2008 6:14 PM
Reply to this message Reply
@Fred,

Thanks for the C# reference, this system is similar to Scala which they mention and very similar to Fortress (I am not sure if the C# proposal comes before or after the Fortress system).

Like you I think the C#/Fortress system is not worth the trouble. Some people are in the camp that the compiler should catch all type errors. Personally I am happy for some to be caught at runtime (so long as they are caught).

Fred Garvin

Posts: 52
Nickname: fredgarvin
Registered: Jan, 2008

Re: Simplyfing Java Generics by Eliminating Wildcards Posted: Feb 12, 2008 10:12 PM
Reply to this message Reply
@Howard,

Re: "Some people are in the camp that the compiler should catch all type errors."

Those people tend to be idealogues; they don't quite grasp the impact of such a requirement. Somehow the bigger picture escapes them. I'll say it again, the objective of a static type system is to *help* people read and write code. Wildcard-style variance is not helping; it has limited usefulness and it is in fact a major source of confusion. Conversely, Array-style variance is a very *useful* tool; it's both easy to understand and quite powerful.

Of course Java generics can't have Array-style variance without removing type erasure, yet another Java generics blunder. Sigh.

Gili T.

Posts: 6
Nickname: cowwoc
Registered: Jul, 2007

Re: Simplyfing Java Generics by Eliminating Wildcards Posted: Feb 25, 2008 9:16 PM
Reply to this message Reply
Fred nailed it on the head! We should be adding static typing so long as it helps us write code, not when it gets in our way.

I am not advocating dynamic typing here but rather I'm saying that the costs of some aspects of Generics outweigh their advantages. In such a case we are likely better off going one step back. A while back I tried retrofitting my API using Generics and got myself into an awful mess (some classes had five type parameters). I emailed Gilad Bracha and he basically told me that Generics are meant to be used when they simplify code, not when they make it worse. He said that in my particular case I was probably better off with it.

I personally think simplifying Generics is one of the most important goals we should have for Java7. I love static typing but the existing Generics design makes the resulting code unreadable and that's simply not an option.

Howard Lovatt

Posts: 321
Nickname: hlovatt
Registered: Mar, 2003

Re: Simplyfing Java Generics by Eliminating Wildcards Posted: Feb 25, 2008 11:23 PM
Reply to this message Reply
@Fred & Gill,

I am obviously with you guys in feeling that static typing should help not hinder. Another aspect of generics that I would like to see removed is recursive definitions like:

abstract class Currency<T extends Currency<T>> {
  final int amount;
  Currency(int amount) { this.amount = amount; }
  T add(T other) { return instance(amount + other.amount); }
  abstract T instance(int amount);
}


But I can't think how without loosing a lot of functionality - any thoughts?

Gregor Zeitlinger

Posts: 108
Nickname: gregor
Registered: Aug, 2005

Re: Simplyfing Java Generics by Eliminating Wildcards Posted: Feb 26, 2008 12:32 AM
Reply to this message Reply
> abstract class Currency<T extends Currency<T>> {
> final int amount;
> Currency(int amount) { this.amount = amount; }
> T add(T other) { return instance(amount + other.amount);}
> abstract T instance(int amount);
> }
>
> But I can't think how without loosing a lot of
> functionality - any thoughts?
What you are trying to accomplish here (I think) is to have the type of the derived class in the abstract class, i.e. this.getClass()

So why not do it like that

abstract class Currency {
  final int amount;
  Currency(int amount) { this.amount = amount; }
  this add(this other) {  
    return instance(amount + other.amount);
  }
  abstract this instance(int amount);
}

Howard Lovatt

Posts: 321
Nickname: hlovatt
Registered: Mar, 2003

Re: Simplyfing Java Generics by Eliminating Wildcards Posted: Feb 26, 2008 8:16 PM
Reply to this message Reply
@Gregor,

Yes self types are some help but they introduce other problems. In the Meyer Eiffel book (I think it is version 3 that has self types) there is a ski trip example with boy and girl skiers that you don't want to share the same room. I.E.

interface Skier { 
  this getRoomMate(); 
  void setRommMate(this roomMate);
}
class Girl implements Skier { ... }
class Boy implements Skier { ... }


All well and good, Boys can't share with Girls. Next Meyer introduced ranked skiers.

interface Ranking { int getRanking(); }
class RankedGirl extends Girl implements Ranking { ... }
class RankedBoy extends Boy implements Ranking { ... }


The problem is now that RankedBoys can only share with other RankedBoys and not Boys. The self type, as denoted by this, is too restrictive. This is a bug that actually made it into print, showing how subtle and hard to find the problems are (you could hardly say that Meyer is anything but an Eiffel language expert!)

The other problem with self types is that you are introducing another typing system in addition to generics, you are not replacing or eliminating generics. Therefore overall complexity goes up.

Fred Garvin

Posts: 52
Nickname: fredgarvin
Registered: Jan, 2008

Re: Simplyfing Java Generics by Eliminating Wildcards Posted: Mar 2, 2008 2:00 AM
Reply to this message Reply
Howard,

You make a good point regarding self types v. recursive type vars. Although seldom used, recursive type vars are quite powerful. But I wonder why you would want to see the feature removed? I'll admit it's a confusing and often misunderstood concept. For instance, it's not exactly obvious that a recursively defined generic class is designed to serve as an abstract class. A parameterized instance of one is always a super class; it is never constructed directly. Perhaps it's the complexity of the subject you don't care for?

My opinion, fwiw, is that, although the concept is deep and confusing at times, recursive type vars don't introduce more complexity to generics. In other words there is zero impact on the grammar to support the feature, therefore no additional complexity is introduced. You pretty much made that point in your response to Gregor. And the reality is that not many people are affected by this feature -- it's there for you if you need it, otherwise it's not seen or heard.

Which brings me back to your original message. Wildcard-style variance, unlike recursive type vars, is an anti-pattern wrt good language design. It's utterly confusing, it introduces a heap of complexity in the language, and it grows like kudzu in source code.

Howard Lovatt

Posts: 321
Nickname: hlovatt
Registered: Mar, 2003

Re: Simplyfing Java Generics by Eliminating Wildcards Posted: Mar 2, 2008 8:00 PM
Reply to this message Reply
@Fred,

All good points that you make. I am against recursive types because they confuse people, even people who are very strong programmers. EG:

http://weblogs.java.net/blog/arnold/archive/2005/06/generics_consid_1.html

My dilemma; is that I can't think of a better solution, unlike wildcards were an obvious solution is to simply get rid of them.

Flat View: This topic has 33 replies on 3 pages [ « | 1  2  3 | » ]
Topic: Simplyfing Java Generics by Eliminating Wildcards Previous Topic   Next Topic Topic: Tim O'Reilly in China

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use