The Artima Developer Community
Sponsored Link

Weblogs Forum
Generics

46 replies on 4 pages. Most recent reply: Jun 30, 2005 4:24 PM by Bruce Eckel

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 46 replies on 4 pages [ « | 1 2 3 4 | » ]
Todd Blanchard

Posts: 316
Nickname: tblanchard
Registered: May, 2003

Re: Generics "Considered Harmful" Posted: Jul 7, 2005 12:18 PM
Reply to this message Reply
Advertisement
I'll put the same thing here I put on Ken's blog.

I'd have to say that the complaint about generics is an nth order complaint about Java's design. It all comes down to "strict static typing doesn't really work all the time" and "type must not be confused with protocol" or "substitutability has nothing to do with type".

You only need generics in strictly typed function dispatch languages like C++ and Java. You don't need them in message passing dynamically typed languages like Smalltalk and Objective C.

To work around the first rule - "strict static typing doesn't really work all the time", we get hacks like templates and generics. Better to give up on the strict static typing idea and just accept that the world is messy.

To me, this is just more proof that Java the language was irredeemably broken at conception.

Bruce Eckel

Posts: 868
Nickname: beckel
Registered: Jun, 2003

Re: Generics "Considered Harmful" Posted: Jul 7, 2005 12:40 PM
Reply to this message Reply
> Luckily, most java developers will happily ignore
> Generics, but personally I will miss being able read the
> java core libraries source code and actually understand it.

Well, part of the point that I'm trying to make is that this is an illusion -- I don't think you can just "happily ignore Generics." It only seems that way, but eventually you are forced to deal with them beyond List<Cat>.

Michael Feathers

Posts: 448
Nickname: mfeathers
Registered: Jul, 2003

Re: Generics "Considered Harmful" Posted: Jul 7, 2005 12:47 PM
Reply to this message Reply
> > Luckily, most java developers will happily ignore
> > Generics, but personally I will miss being able read
> the
> > java core libraries source code and actually understand
> it.
>
> Well, part of the point that I'm trying to make is that
> this is an illusion -- I don't think you can just
> "happily ignore Generics." It only seems that way, but
> eventually you are forced to deal with them beyond
> List<Cat>.


That's sad. Do you have any examples? Is there anything about List<Cat> that forces you into odd covariance situations ? What if you never inherit from Cat? Is life fine then?

David Vydra

Posts: 60
Nickname: dvydra
Registered: Feb, 2004

Re: Generics "Considered Harmful" Posted: Jul 7, 2005 1:48 PM
Reply to this message Reply
Recently, I worked in a shop where we did not use anonymous inner classes. At the time I thought that was due to the fact that most of the developers were new to Java, but in retrospect that may have been a good strategy to keep the code readable and to reduce training time. Later, I moved to a shop where some people tried to write Smalltalkish java with lots of anonymous inner classes. When we had a retrospective, several developers complained that the code was difficult for them to read.

I agree that Java is not the best language out there, but it does have a plethora of tools and libraries that make it the right choice in many circumstances. Every team should decide which language features to use to balance code readability with code duplication.

Todd Blanchard

Posts: 316
Nickname: tblanchard
Registered: May, 2003

Re: Generics "Considered Harmful" Posted: Jul 7, 2005 3:20 PM
Reply to this message Reply
> Recently, I worked in a shop where we did not use
> anonymous inner classes. At the time I thought that was
> due to the fact that most of the developers were new to
> Java, but in retrospect that may have been a good strategy
> to keep the code readable and to reduce training time.
> Later, I moved to a shop where some people tried to write
> Smalltalkish java with lots of anonymous inner classes.
> When we had a retrospective, several developers complained
> that the code was difficult for them to read.

Yes, little wonder as Java's syntax is horrible. Pity they didn't bother to make blocks part of the language. Compare equivalent code:

button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Button b = (Button)e.getSource();
/*Do some stuff here */}});

vs

button onClickDo: [:button | "Do stuff here" ].

One of them is easy to read and understand - the other has the meaning buried in worthless boilerplate required to satisfy a cumbersome and unnecessary type system.

Syntax definitely matters.

Michael Lorton

Posts: 1
Nickname: malvolio
Registered: Jul, 2005

Re: Generics "Considered Harmful" Posted: Jul 9, 2005 12:54 AM
Reply to this message Reply
Look, you can have static typing or you can have dynamic typing. I've maintained very large systems in statically-typed languages and in dynamically-typed languages and it doesn't strike me as much of a contest.

Yes, you can write three lines of Python that would blow up to five (!) lines of code in Java, but when you've got 250,000 lines written by 50 programmers over five years, all of a sudden the wordiness of static typing just doesn't seem so bad.

To get back to generics, all the actual complaints come down to two:

1. I can't access the type-argument at run-time.
2. generics places weird restrictions of what I can do.

(1) Yes. There's compile-time and there's run-time. Some things, like scope, local variable names, and type-arguments are compile-time concepts and go away before run-time. In those (rare) cases you need to know type-information, it is the programmer's (and not the language's) responsibility.


(2) No. Java generics are a reification of generic static type-safety means. If you cannot do something, it isn't because of some fluke of the Java language -- it's because it's unsafe. Let me give you an example: one engineer complained that he couldn't assign a variable of type List<List<String>> to another of type List<List<?>>. To him, it was perfectly obvious that you should be able to, because you could assign a List<String> to a List<?>. Well, you can't. It's isn't Java's fault, it is inherent is the meanings of the symbols. A language that did allow you to assign a List<List<String>> to a List<List<?>> would not be statically type-safe.


Which brings me back to my original point. Some people don't like static type-safety because they find it restrictive. Okay, matter of taste.

Other people don't like static type-safety because they find it unnecessary. Those people, well, they're just mistaken.

Bruce Eckel

Posts: 868
Nickname: beckel
Registered: Jun, 2003

Re: Generics "Considered Harmful" Posted: Jul 9, 2005 1:13 PM
Reply to this message Reply
It's not quite as simple as that. The part you have right, I think, is that there are two camps of people, but I would classify them as "those who think it is as simple as that" and "those who don't." Or, from Gerald Weinberg's analysis, "Linear thinkers" and "Systems thinkers." Weinberg makes, in "Becoming a Technical Leader" (and other places, I'm sure), the very important observation that both approaches work at different times, which is why we can't simply make the decision that one approach is right and move on. I think the most difficult thing for someone schooled in linear thinking (as I was) is to acquire systems thinking in addition to linear thinking, because linear thinking doesn't want to allow any competitors -- it says "you can always control variables and change a single factor and deterministically establish the results." Systems thinking says that, in reality you can't ever just change one thing. Everything affects everything else.

An example often comes up in discussions about Java. There's a significant camp that says that "Java is a statically typed language." But if you really look at it, while Java has static typing, it also has a very significant dynamic aspect. Some kinds of type checking simply don't happen until runtime. And you can go further and use reflection to do some very dynamic things. For people who are convinced that Java should only be considered a statically typed language, anything that isn't checked until runtime is simply branded "bad" and "you should never do this." But that closes a great many doors on the possibilities of the language, and delegates it to be, in effect, "A better C++."

This is a very difficult discussion, and although I've been thinking about it for years, it's only been in the past couple of weeks (primarily from reading Weinberg) that I began to realize why it is so complex: it's not "either or," it's "sometimes one, sometimes the other." In more concrete terms, you can't simply say that static type checking is good or bad. You have to look at the context, which includes the system you're trying to build and the people that are building it. When I was working with college interns, Java's static type checking was grossly lacking -- the interns needed to be put into an iron maiden of type checking in order to be productive. With mature programmers working on certain types of projects, static checking is an impediment, and they can be vastly more productive with a language like Python. (On the other hand, I think the teaching of statically typed languages warps the minds of young programmers into thinking that all they have to do is argue with the compiler until they reach agreement, then the program is done. In effect, all they have to do is "pass the test," then they deserve an 'A').

This comment needs to become an essay on its own, but these are some of the starting ideas.

Bruce Eckel

Posts: 868
Nickname: beckel
Registered: Jun, 2003

Re: Generics "Considered Harmful" Posted: Jul 10, 2005 2:59 PM
Reply to this message Reply
To address these points (Although I think there are actually more than two complaints):

> To get back to generics, all the actual complaints come
> down to two:
>
> 1. I can't access the type-argument at run-time.
> (1) Yes. There's compile-time and there's run-time. Some
> things, like scope, local variable names, and
> type-arguments are compile-time concepts and go away
> before run-time. In those (rare) cases you need to know
> type-information, it is the programmer's (and not the
> language's) responsibility.

This does not address the complaint, it simply describes the way that Java happens to work. A type argument is not necessarily a compile-time concept, but the erasure implementation in Java happens to implement it that way. But describing it like this makes it sound like it's intuitively obvious that type arguments should go away at runtime. Type information about objects doesn't go away at runtime, why should type arguments? You can't explain it without explaining erasure and migration compatibility.

The real problem, I think, is that the type information looks like it's there. You can say 'T', and sometimes it's meaningful and sometimes it isn't, and you have to figure it out, usually every time.

When you need information about a type argument at runtime, you have to pass in an extra Class<T> argument. But this is counterintuitive since you already have a T. It's doable, but it's something extra to learn and remember -- and if generics were implemented in the language from the beginning this would not be the case. You would have type argument information available at runtime.


> 2. generics places weird restrictions of what I can do.
> (2) No. Java generics are a reification of generic static
> type-safety means. If you cannot do something, it isn't
> because of some fluke of the Java language -- it's because
> it's unsafe. Let me give you an example: one engineer
> complained that he couldn't assign a variable of type
> List<List<String>> to another of type List<List<?>>. To
> him, it was perfectly obvious that you should be able to,
> because you could assign a List<String> to a List<?>.
> Well, you can't. It's isn't Java's fault, it is inherent
> t is the meanings of the symbols. A language that did
> allow you to assign a List<List<String>> to a
> List<List<?>> would not be statically type-safe.

Here you're talking about covariance and contravariance, which do indeed describe accurate mathematical relationships between types. But those features are in addition to generics. Although covariance and contravariance add complexity to the process of writing code with generics, I think most of the "weird restrictions" that people complain about come down to the erasure implementation, and what that prevents.

> Which brings me back to my original point. Some people
> don't like static type-safety because they find it
> restrictive. Okay, matter of taste.

I think it's much more important that that -- I think that it's a matter of productivity. This isn't a lifestyle choice, it's real dollars. However, see my previous response about the applicability of both approaches.

> Other people don't like static type-safety because they
> find it unnecessary. Those people, well, they're just
> mistaken.

And this is glib and dismissive. Also, note that "restrictive" and "unnecessary" are effectively the same description.

Perhaps you could describe the very large systems in both static and dynamically typed languages that you have maintained, and the issues that you found with each one. I suspect that could be more helpful and illuminating.

Bruce Eckel

Posts: 868
Nickname: beckel
Registered: Jun, 2003

Re: Generics "Considered Harmful" Posted: Jul 10, 2005 7:16 PM
Reply to this message Reply
> Recently, I worked in a shop where we did not use
> anonymous inner classes. At the time I thought that was
> due to the fact that most of the developers were new to
> Java, but in retrospect that may have been a good strategy
> to keep the code readable and to reduce training time.
> Later, I moved to a shop where some people tried to write
> Smalltalkish java with lots of anonymous inner classes.
> When we had a retrospective, several developers complained
> that the code was difficult for them to read.

Although I can understand it, I have a problem with the school of thinking that says "lets ignore a language feature, or decide it is bad, and pretend it doesn't exist. Otherwise it will be misused." I know that a common desire in Java is to be protected from doing anything wrong (even if it impedes your ability to do something right). But anonymous inner classes can be very effective at times, so to decide not to use them because they might be poorly used seems to me to be a doomed decision. If they might be misused, why won't the same programmer misuse other features in the language? Isn't a better answer to teach people how to properly use all the features in a language?

I also observe that even if particularly language features are ignored in your own code, people will encounter that feature when reading other code.

That said, of all the features in Java, anonymous inner classes are probably the easiest to avoid, since I can think of no case where you couldn't write a named class.

Todd Blanchard

Posts: 316
Nickname: tblanchard
Registered: May, 2003

Re: Generics "Considered Harmful" Posted: Jul 11, 2005 3:26 PM
Reply to this message Reply
> Look, you can have static typing or you can have dynamic
> typing.

You can have both. Objective C gives you some of each. You choose how much help you want by typing (or not typing) your variables.

NSString* string = @"Hello ";
id otherString = @"world!";

[string foo]; // compiler generates "warning - NSString does not respond to "foo"

[otherString foo]; // dynamic typing assumed - no warning


> I've maintained very large systems in
> statically-typed languages and in dynamically-typed
> languages and it doesn't strike me as much of a contest.

Me neither, but I suspect we disagree.

> Java generics are a reification of generic static
> type-safety means. If you cannot do something, it isn't
> because of some fluke of the Java language -- it's because
> it's unsafe.

Bull. First, I object to the term "type safety". The Java type system is inherently unsafe as it is incomplete. The fact that downcasting exists and is allowed (and often *required*) makes it inherently unsafe at compile time.

Please tell me, what is the difference between the following failure modes when the list does not contain a Window:

Java:
((Window)list.get(0)).show();
aWindow.show();

Smalltalk:
(list at: 0) show.

In both cases you will end up with a runtime failure of your program. Both will generate runtime exceptions.

In the first case, the error will be thrown back at the client code with no opportunity to handle it on a per class basis. Fixing this involves touching every call site.

In the second case, the error will be provided to the object that does not implement the show method where it can be handled and possibly adapted to a more appropriate method. The default behavior is to throw the error back at the client as an exception, however you could attach a delegate to the class to handle the message and fix it in one place instead of dozens.

You can argue that you might be able to work around this with stricter collection typing.

I will argue that you will never eliminate all casts in your code and every cast is runtime exception waiting to happen and you are no better off than programmer who relies on dynamic typing.

You need to be able to mix styles in one language. You already do this but you are in denial about it.

Bruce Eckel

Posts: 868
Nickname: beckel
Registered: Jun, 2003

Re: Generics "Considered Harmful" Posted: Jul 11, 2005 4:01 PM
Reply to this message Reply
I would go further than this and say that Java already has a foot planted firmly in both the static and dynamic type checking camps.

But I will also assert that without Java's dynamic nature, there are a lot of things you simply can't do. If you refuse to accept or use reflection, for example (and some do), you are that much closer to just using C++. Indeed, if all you want Java to be is a statically typed language, then you may be better off with C++.

I think it's also important to realize that reflection provides a different kind of genericity, and I think it may at least partially compensate for the limitations of erasure-based generics. Of course, it's more complex to use, but at least its possible.

David Vydra

Posts: 60
Nickname: dvydra
Registered: Feb, 2004

Re: Generics "Considered Harmful" Posted: Jul 11, 2005 4:16 PM
Reply to this message Reply
Bruce,

We use English in different ways, for example, the language used in my local newspaper is different from the one used in the Foreign Affairs magazine -- it is much simpler. Why should java be different?

Getting back to the specifics - lets say that I only use List<Foo> and the new 'for' loop. No wildcards, no generic methods, no covariance. What is the problem? I am just getting a marginal improvement in the clarity of my code and there is almost no learning curve? This must be possible because 1.5 is 100% backwards compatible with 1.5 syntax. Am I missing something?

Isaac Gouy

Posts: 527
Nickname: igouy
Registered: Jul, 2003

Re: Generics "Considered Harmful" Posted: Jul 11, 2005 9:36 PM
Reply to this message Reply
Todd Blanchard wrote:
> First, I object to the term "type safety"

See Richard Gabriel's comment at the bottom of
ParcPlace Type-Safety Discussion
http://wiki.cs.uiuc.edu/VisualWorks/ParcPlace+Type-Safety+Discussion


> You can argue that you might be able to work around this
> with stricter collection typing.
>
> I will argue that you will never eliminate all casts in
> your code and every cast is runtime exception waiting to
> happen and you are no better off than programmer who
> relies on dynamic typing.

Seems like you're arguing that we shouldn't bother eliminating 97 casts from the code because there are 3 casts that we can't eliminate - and those 3 casts are potential runtime errors.

Seems like we just removed 97 potential runtime errors - so now we can focus testing on 3 potential runtime errors.

Todd Blanchard

Posts: 316
Nickname: tblanchard
Registered: May, 2003

Re: Generics "Considered Harmful" Posted: Jul 12, 2005 12:24 AM
Reply to this message Reply
>>ParcPlace Type-Safety Discussion

I know what real type safety is (I basically agree with Wirfs-Brock), and I'm quite aware that the context in which it was initially raised is the other definition - the dogma that arose from the C++ community which is overly fond of words like "correct, robust, safe, efficient" etc.

>>Seems like you're arguing that we shouldn't bother eliminating 97 casts from the code.

If you read it again, I'm in favor of allowing the programmer to chose whether he wants to statically type something and have the compiler check it for him, or whether he wants to rely on the runtime to help him catch and recover from errors. I'd actually like to see optional type annotations added to Smalltalk ala Strongtalk.

I don't believe in penalizing the programmer for one or the other approaches.

Java heavily penalizes the dynamic typer by forcing pointless casts (if the cast is wrong you get a runtime exception - if there is no cast and you send a message the object doesn't understand you get a runtime exception - why require casts?) and a terribly clumsy syntax for dynamic method invocation (the "reflection" api).

To me the generics look like a bandaid on an already poorly conceived type system/philosophy.

Isaac Gouy

Posts: 527
Nickname: igouy
Registered: Jul, 2003

Re: Generics "Considered Harmful" Posted: Jul 12, 2005 1:11 AM
Reply to this message Reply
> >>ParcPlace Type-Safety Discussion
>
> I know what real type safety is (I basically agree with
> Wirfs-Brock)

He doesn't say what (real or fake) type safety is!

"Type safety is the property that no primitive operation is ever applied to values of the wrong type"
p205 Programming Languages: Application and Interpretation
http://www.cs.brown.edu/~sk/Publications/Books/ProgLangs/

Java provides static-checking and is type-safe;
Smalltalk provides dynamic-checking and is type-safe;
C++ is not type-safe.


-snip-
> I don't believe in penalizing the programmer for one or
> the other approaches.

That programmer could always choose Dylan
http://www.gwydiondylan.org/gdref/tutorial/ch01.html#dynamic-vs-static

Flat View: This topic has 46 replies on 4 pages [ « | 1  2  3  4 | » ]
Topic: The Tortoise and the Hare Previous Topic   Next Topic Topic: Open Source Licenses versus Public Domain


Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2014 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use - Advertise with Us