The Artima Developer Community
Sponsored Link

Weblogs Forum
Have Generics Killed Java?

62 replies on 5 pages. Most recent reply: Aug 8, 2010 3:43 PM by Eric Armstrong

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 62 replies on 5 pages [ « | 1 2 3 4 5 | » ]
Eric Armstrong

Posts: 207
Nickname: cooltools
Registered: Apr, 2003

Re: Have Generics Killed Java? Posted: Jul 22, 2010 10:53 AM
Reply to this message Reply
Advertisement
James wrote:
>
> ...when I want something
> like a table with a dynamically generated number of
> columns, the structure of these models and their
> interactions becomes much more complicated. I would
> regularly become confused about which type of object to
> expect at which level. This could only be checked at
> runtime. It wasn't even the run-test cycle that was the
> problem: I would waste much more of time just trying to
> make sense of the multi-layered structures...Generics
> exposed the
> hidden structure and makes the code much more transparent
> and readable.
>
Interesting use case! Thanks for pointing to it. Thanks to everyone else who has posted interesting comments, as well. I nervously expected to be thrashed about the head and shoulders for that particular post.

To reply to some of the other comments...

1. Java is still #1, I know. But I wonder if it is being taught in schools these days because it so readable (the original motivation) or because it represents so many jobs. (Nothing wrong with that. I just wonder how the academic community regards it for didactic purposes, compared to earlier versions.)

2. Judging by the comments here, Scala appears to be gaining traction. It's particularly heartening to know that fellow Ruby fan Eric Pederson likes it. (And Bill Venners, and Scott Kilpatrick...)

3. Fire Mage gave me a good description of my internal state: "Every time I have to type in type parameters while coding it seems to put the brakes on my chain of thought..." Yes. That is indeed an issue. I like it when the computer is waiting on me, not vice versa, so I can operate as fast as I can think and type.

4. Morel Xavier pointed to Haskell. Would love to see some equivalent examples in that language. I know of it, but have never studied it.

5. Morel also asks if it makes sense to write tests that do the same verifications. The answer is yes. Because with tests, you can asymptotically approach 100% quality. Static type checking catches some things. Generics adds a few more things. But "quality" is not a strong enough argument, to me. ("Understanding", on the other hand, is pretty big. See point #10)

6. Generics are optional? Not really. They're viral. I don't like warnings in my code. If I use a generified library, generics begin migrating through my code to get rid of them. (Ronald suggests using the @SuppressWarnings("unchecked") annotation. Probably a good idea. But it's more syntactic sugar the programmer has to feed the compiler, to keep it quiet.

7. Roland Miura also wrote, "I'm doing a lot of Groovy code nowadays, and it's really frustrating not being able to refactor and navigate through code like I can do with Java." I have to admit, that is a major strength of Java. Tor did a great job with Ruby in NetBeans. That's as close as I've ever come to the same kind of refactoring and navigational capabilities.

8. Scott Kilpatrick mentioned the downcasts in 1.4. Yeah. I never liked those, either.

9. Something I neglected to mention in the article, is that Ruby is also type safe. Once you assign a value, it has a type. It's never autoconverted, after that. Of course, it's checked at runtime, so safety still depends on testing.

10. The general consensus I see so far is that people are finding generics helpful when when working with code written by others, especially when it's complex. The point I particularly like is that it helps them *understand* what they're dealing with. Aids to understanding are pretty darn valuable, in my book.

11. Howard Lovatt gave a nice heads up on upcoming stuff in 1.7. Thanks!

Eric Armstrong

Posts: 207
Nickname: cooltools
Registered: Apr, 2003

Re: Have Generics Killed Java? Posted: Jul 22, 2010 11:04 AM
Reply to this message Reply
James Watson wrote:
>
> In Wicket you have (your own) model objects behind all of
> your interface components. For simple things like labels,
> this is fairly straightforward. But when I want something
> like a table with a dynamically generated number of
> columns, I the structure of these models and their
> interactions becomes much more complicated. I would
> regularly become confused about which type of object to
> expect at which level. This could only be checked at
> runtime. It wasn't even the run-test cycle that was the
> problem: I would waste much more of time just trying to
> make sense of the multi-layered structures (something I've
> also experienced using Python.) Generics exposed this
> hidden structure and makes the code much more transparent
> and readable.
>
Thanks, James. That was a thoughtful comment. As Benjamin James so wisely wrote a few posts later, "For people who (need) to continue using Java, generics are welcome."

And as Tim Jansen wrote: "The problem is that I don't know the types of the key and values in the 'map' returned by getInfo()." Defining the contract and understanding it continue to be highly relevant issues, especially when interacting with code written by others.

Cedric Beust

Posts: 140
Nickname: cbeust
Registered: Feb, 2004

Re: Have Generics Killed Java? Posted: Jul 22, 2010 11:20 AM
Reply to this message Reply
> 3. Fire Mage gave me a good description of my internal
> state: "Every time I have to type in type parameters while
> coding it seems to put the brakes on my chain of
> thought..." Yes. That is indeed an issue. I like it when
> the computer is waiting on me, not vice versa, so I can
> operate as fast as I can think and type.

Agreed, but the solution is not to remove types, it's to make it easier to specify them in the source. Whenever I find myself defining a method signature in Ruby, my fingers are begging me to let me enter the type of the parameter I just added. I know it, it's just a few extra characters, it provides extra safety, yet Ruby won't let me.

The solution in Java:

Today: let the IDE do this for you. I hardly enter any type these days, I type the name of the variable, press Ctrl-1 and I let the IDE add the type for me.

Tomorrow: type inference. Hopefully, at some point I can just say that the type of my variables is "var" and the compiler will know what it is without losing any type safety.

> 5. Morel also asks if it makes sense to write tests that
> do the same verifications. The answer is yes. Because with
> tests, you can asymptotically approach 100% quality.

That's delusional. First, you can never reach 100% coverage (not that it would even be useful) and two, static code coverage is still missing plenty of code paths.

> Static type checking catches some things. Generics adds a
> few more things. But "quality" is not a strong enough
> argument, to me. ("Understanding", on the other hand, is
> pretty big. See point #10)

The main point of static type checking is *not* to catch errors at compile time but to 1) provide contracts that the compiler can check, 2) enable automatic refactorings and 3) improve maintenance because future developers can more easily make sense of what the code does.

> 9. Something I neglected to mention in the article, is
> that Ruby is also type safe. Once you assign a value, it
> has a type. It's never autoconverted, after that. Of
> course, it's checked at runtime, so safety still depends
> on testing.

This is a very limited version of type safety. It's better than nothing but it still makes most automatic refactorings impossible.

Morel Xavier

Posts: 73
Nickname: masklinn
Registered: Sep, 2005

Re: Have Generics Killed Java? Posted: Jul 22, 2010 11:35 AM
Reply to this message Reply
> The main point of static type checking is *not* to catch
> errors at compile time but to 1) provide contracts that
> the compiler can check, 2) enable automatic refactorings
> and 3) improve maintenance because future developers can
> more easily make sense of what the code does.
>

I disagree with the former assertion. Static type checking does indeed serve to catch errors at compile time, and if your type system is expressive enough and you use it you can catch logic errors. Hell, that's exactly what "provide contracts the compiler can check" means.

That's what users of H-M based type systems (MLs, Haskell) mean when they say that if a program type checks it's correct, or that sigfpe declares (half in jest)

> Haskell is so strict about type safety that randomly generated snippets of code that successfully typecheck are likely to do something useful, even if you've no idea what that useful thing is.

Cedric Beust

Posts: 140
Nickname: cbeust
Registered: Feb, 2004

Re: Have Generics Killed Java? Posted: Jul 22, 2010 11:39 AM
Reply to this message Reply
> > The main point of static type checking is *not* to
> catch
> > errors at compile time but to 1) provide contracts that
> > the compiler can check, 2) enable automatic
> refactorings
> > and 3) improve maintenance because future developers
> can
> > more easily make sense of what the code does.
> >
>
> I disagree with the former assertion. Static type checking
> does indeed serve to catch errors at compile time

Yes, I should have been more specific: catching errors at compile time is not the main advantage that statically typed languages have over dynamically typed ones. These advantages are the three items I described in my article above.

Morel Xavier

Posts: 73
Nickname: masklinn
Registered: Sep, 2005

Re: Have Generics Killed Java? Posted: Jul 22, 2010 11:39 AM
Reply to this message Reply
> 4. Morel Xavier pointed to Haskell. Would love to see some
> equivalent examples in that language. I know of it, but
> have never studied it.
>

The examples you give don't map too nicely to Haskell, because they're impure (side-effecting), and in Haskell side-effects themselves are type-encoded.

For instance,

[fixed]list.each { |item|
...
}[/fixed]

Would translate to something along the lines of

[fixed]mapM_ (\item -> ...) list[/fixed]
Where `mapM_ :: Monad m => (a -> m b) -> [a] -> m ()`

Morel Xavier

Posts: 73
Nickname: masklinn
Registered: Sep, 2005

Re: Have Generics Killed Java? Posted: Jul 22, 2010 12:02 PM
Reply to this message Reply
Crap. Wrong button and I don't find how to edit... oh well

Please note that my examples are not tested, I have yet to reinstall ghc on my machine

> 4. Morel Xavier pointed to Haskell. Would love to see some
> equivalent examples in that language. I know of it, but
> have never studied it.
>

The examples you give don't map too nicely to Haskell, because they're impure (side-effecting), and in Haskell side-effects themselves are type-encoded.

For instance,
list.each { |item|
...
}

Would translate to something along the lines of
mapM_ (\item -> ...) list

Where `mapM_ :: Monad m => (a -> m b) -> [a] -> m ()`,

What does that type signature tells us? That mapM_ takes `(a -> m b)` a function from a type `a` to a type `something b`, `[a]` a list of `a`s and it returns `m ()` which is "something nothing" (`()` is the unit type, it's basically equivalent to Java's `void`). A monad is a generalized container type, akin to a generic container but which can also contain side effects or mutations.

And from the name (map) we can infer it performs a mapping.

So basically, it applies the provided function and ignores its result, which is perfect for side-effects such as printing to the screen.

So
list.each { |item|
puts item
}

becomes
mapM_ putStrLn list

and because putStrLn is of type `String -> IO ()`, the compiler can infer that `list :: [String]` and that our whole expression lives in the IO monad (think of it as a special context where it is possible to perform input/output operations) because the whole expression has type `IO ()`.

As for
map.sort.each { |key, value|
...
}

it would go roughly
mapM_ (\(key, value) ->  ...) (sort $ assocs m)

m is the map, `assocs` outputs the (key, value) pairs (http://hackage.haskell.org/packages/archive/containers/0.2.0.1/doc/html/Data-Map.html#v%3Aassocs), sort sorts it by natural order (http://haskell.org/ghc/docs/6.12.1/html/libraries/base-4.2.0.0/Data-List.html#v:sort) which results in a list being provided to mapM_ which we've already seen.

Eric Armstrong

Posts: 207
Nickname: cooltools
Registered: Apr, 2003

Re: Have Generics Killed Java? Posted: Jul 22, 2010 12:53 PM
Reply to this message Reply
Morel's Haskell examples:
>
> ...
>
Thanks, Morel. That's the first intro I've had to Haskell. I don't follow it all, exactly. But you gotta love a language that maps so well to mathematics! (I was a quasi-mathematician/philosopher before becoming a programmer.)
:__)

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: Have Generics Killed Java? Posted: Jul 22, 2010 1:46 PM
Reply to this message Reply
> Whenever I
> find myself defining a method signature in Ruby, my
> fingers are begging me to let me enter the type of the
> parameter I just added.

One of the things I find that I miss when using Python is when I want to use duck-typing for something non-trivial, the compiler won't just tell me what methods I need to implement. There may be IDE support for this kind of thing but I think it highlights the 'real' advantage of static typing, in my mind at least. In my experience with dynamic languages, they lack a centralized place to declare a set of related operations. I can't just click on a variable and ask for it's type definition.

This is just my personal opinion, of course. I'm not saying this applies to everyone else.

Morel Xavier

Posts: 73
Nickname: masklinn
Registered: Sep, 2005

Re: Have Generics Killed Java? Posted: Jul 22, 2010 2:59 PM
Reply to this message Reply
> > Whenever I
> > find myself defining a method signature in Ruby, my
> > fingers are begging me to let me enter the type of the
> > parameter I just added.
>
> One of the things I find that I miss when using Python is
> when I want to use duck-typing for something non-trivial,
> the compiler won't just tell me what methods I need to
> implement. There may be IDE support for this kind of
> thing but I think it highlights the 'real' advantage of
> static typing, in my mind at least.

FWIW, duck typing and nominative typing are pretty different, and most IDEs built these days have nominative typing in mind, because that's the baseline. The most mainstream language implementing an equivalent of duck typing statically would be OCaml and its structurally typed objects.

A nominative typing base is a pretty bad match for duck typing.

> In my experience with
> dynamic languages, they lack a centralized place to
> declare a set of related operations. I can't just click
> on a variable and ask for it's type definition.

It's not entirely correct in that it's highly language-dependent. Smalltalk had Protocols. Python also had informal protocols (defined out of band), but in 2.6 it introduced the concept of abstract base classes, which are kind of a cross between duck-typing, interfaces and typeclasses. They probably aren't yet well supported by IDEs though.

Ronald Tetsuo Miura

Posts: 22
Nickname: ronaldtm
Registered: Jan, 2004

Re: Have Generics Killed Java? Posted: Jul 22, 2010 3:37 PM
Reply to this message Reply
> 6. Generics are optional? Not really. They're viral. I don't like warnings in my code. If I use a generified
> library, generics begin migrating through my code to get rid of them. (Ronald suggests using the
> @SuppressWarnings("unchecked") annotation. Probably a good idea. But it's more syntactic sugar the programmer has to
> feed the compiler, to keep it quiet.

No, they are optional. It is by design, since they had the backwards compatibility requirement.

If you don't want the compiler to warn you, you can disable this specific warning altogether (since you don't like generics, you probably won't miss it):

Window -> Preferences -> Java -> Compiler -> Errors/Warnings -> Generic Types


> 7. Roland Miura also wrote, "I'm doing a lot of Groovy code nowadays, and it's really frustrating not being able
> to refactor and navigate through code like I can do with Java." I have to admit, that is a major strength of Java.
> Tor did a great job with Ruby in NetBeans. That's as close as I've ever come to the same kind of refactoring and
> navigational capabilities.

It's Ronald.

"As close as ever" is probably about 30% of the functionality, with 20% accuracy, which is pretty impressive support for a dynamic language.

Dick Ford

Posts: 149
Nickname: roybatty
Registered: Sep, 2003

Re: Have Generics Killed Java? Posted: Jul 22, 2010 4:31 PM
Reply to this message Reply
The guy that heads up the JRuby project has been working on a statically-typed language with a Ruby syntax.

http://www.mirah.org/wiki/MirahFeatures

And some samples: http://www.mirah.org/wiki/MirahSamples

Besides being a statically-typed language with a very dynamic, rubyesque feel to it, it doesn't have any big runtime.

Chad Stansbury

Posts: 2
Nickname: cstansbury
Registered: Jul, 2010

Re: Have Generics Killed Java? Posted: Jul 22, 2010 7:53 PM
Reply to this message Reply
Maybe I'm just getting old... but when I read articles like this I've started to wonder if the person who wrote it has too much time on their hands or are more interested in improving their "cred" in their newly adopted language by writing articles that compare said newer language's strengths against the established language's weaknesses.

Ultimately what matters to 99% of the people in the world is what you've created, not the tools you used to create it with...

Howard Lovatt

Posts: 321
Nickname: hlovatt
Registered: Mar, 2003

Re: Have Generics Killed Java? Posted: Jul 22, 2010 11:15 PM
Reply to this message Reply
@Fire Madge,

-- snip --

> > strings.sort().each( { s -> out.println( s ); } );
>
> How do I know what s is? What is "->"? A new operator?
> Like autoboxing, this line of code looks like Java doing
> g magic behind your back again for "convenience". What is
> wrong with using a for loop?
>
> for (String s : strings.sort()){
> out.println(s);
> }
>
> It even has the same number of characters!
> Do we have to keep adding ever more ways of doing the same
> thing just so that it looks more snappy? To me, this is
> Java catering to the dynamic community.

There is a difference that is significant, the for loop is strictly serial, one string after another. It is likely that they will also introduce something along the lines of:

strings.sort().parEach( { s -> out.println( s ); } );

Which processes each of the strings in parallel, not much an advantage for something like print but great for a computationally expensive operation on a multi-core machine. This, parallel operations, is one of the main drivers for introducing lambdas (as the "{ ... -> .... }" syntax is called).

-- snip --

> That's a subjective opinion. I understand the need for
> primitive types, which is mainly a performance
> consideration. Thanks to primitive types Java can be
> compared in performance to C++, something dynamic
> languages will probably never achieve. Also it makes it a
> lot easier and faster to work with native libraries, such
> as OpenGL and I/O operations. I don't think that
> everything has to be an object. But if there are primitive
> types, the distinction should be clear and they shouldn't
> start softening it up with "magic" such as autoboxing.

Scala does a nice Job of integrating Integer and int, unfortunately it is hard to see how Scala's type system could be retrofitted to Java.

Max Lybbert

Posts: 314
Nickname: mlybbert
Registered: Apr, 2005

Re: Have Generics Killed Java? Posted: Jul 23, 2010 2:06 AM
Reply to this message Reply
As others have said, the problem with

for (Map.Entry<K, V> e : map.entrySet())


isn't the generics; it's the lack of type inference. In C# it's

foreach (var e in map)


I would also mention that automatically inserting semicolons (i.e., having the compiler decide when statements end instead of the programmer) works in 99% of the cases and causes subtle bugs in the other 1%; often without a good safety hatch for that 1%.

But since the discussion has moved on to static typing vs dynamic typing, I will only add that I agree with Alexander Stepanov that "Everybody realizes that strong typing helps in catching errors. I discovered that strong typing ... was also an instrument of capturing designs. It was not just a tool to catch bugs. It was also a tool to think." ( http://www.sgi.com/tech/stl/drdobbs-interview.html ).

Once upon a time, static typing was used largely for efficiency concerns. Later it was sold as a way of avoiding trivial errors. But I honestly do find that static types make it easier to reason about a program. And I'm willing to put up with the drawbacks -- especially when type inference is available -- to get that advantage.

Flat View: This topic has 62 replies on 5 pages [ « | 1  2  3  4  5 | » ]
Topic: How Much Unit Test Coverage Do You Need? - The Testivus Answer Previous Topic   Next Topic Topic: Adding Optional Static Typing to Python

Sponsored Links



Google
  Web Artima.com   

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