Summary
One of the things I've loved about Python is that it was built as a community from the beginning. Language design decisions are genuinely discussed and struggled with as a community. But with Java, I've always felt like the adults were telling me what to think.
Advertisement
I just saw Joe Darcy's JDK 7 in a Nutshell talk (9.5 minutes) from O'Reilly OSCON Java 2011. The new features he talked about were a bit of type inference so that you no longer have to repeat yourself in some of the most egregious ways the language formerly forced us to, and switching on String.
If this had happened 12 years ago, I would have felt like the language was on the right track, trying to make things easier and cleaner for the programmer. Instead, I feel like we got over a decade of being told why all the choices made in Java were the best way and that we should just accept and love them (and many did).
Only now, after years of dissatisfaction that led to more succinct and powerful languages on the JVM, do we finally start seeing some of these fundamental improvements. But it seems like they only happened under extreme duress after a lot of resistance. And perhaps these features might be helpful, but I can't see them stemming the flow away from Java towards other JVM languages for those that no longer want to struggle with the limitations of Java.
For example, in Scala the decision to use type inference is at the core of the language, not an afterthought. So defining an object is about as clean a process as you could hope for. Adding a little inferencing in Java 7 doesn't make a dent by comparison.
With Scala's pattern matching, you can switch on pretty much anything. Someone who is frustrated by the limitations of switching on integral values is not going to see enough of an improvement via string switching.
It's nice that Java is making these improvements. Java made some fundamental shifts in the programming world -- before Java everyone believed that virtual machines and garbage collectors would never be practical, for example. But it seems to me that the world started moving on awhile ago. The productivity and financial benefits of languages like Scala, Groovy, JRuby, Jython and numerous other JVM languages are getting harder and harder to resist.
I have also been skeptical of the benefits of closures, at least the "easy, quick" ones everybody gives in demos. For example, in his OSCON video, Odersky partitions people by age
val (minors, adults) = people partition (_.age < 18)
Such code is extremely sloppy and fragile, (yes, it's just a demo!) and, since it's so "easy", we encourage coders to do it this way. The real rules for the age of majority are complex (http://en.wikipedia.org/wiki/Age_of_majority#Countries_and_subdivisions) and you'd really want to call a method. At that point, the conciseness "advantage" of Scala over Java greatly diminishes.
But Scala's parallel implementation of partition is really cool and strikes me as a major advantage. WHich is starting to make a believer of me.
> Scala type inferencing is nice. But I don't understand > your concern about the limitations of switch statements in > pre-7 Java. > > Switch statements are, in general, something to avoid. > (e.g. http://c2.com/cgi/wiki?SwitchStatementsSmell) > > Making switch statements easier to use just makes them > more likely to be used, which is not progress. Use > polymorphism instead.
> I have also been skeptical of the benefits of closures, at > least the "easy, quick" ones everybody gives in demos. > For example, in his OSCON video, Odersky partitions > s people by age > >
> val (minors, adults) = people partition (_.age < 18)
>
> > Such code is extremely sloppy and fragile, (yes, it's just > a demo!) and, since it's so "easy", we encourage coders to > do it this way. The real rules for the age of majority > are complex > (http://en.wikipedia.org/wiki/Age_of_majority#Countries_and > _subdivisions) and you'd really want to call a method. > At > that point, the conciseness "advantage" of Scala over Java > greatly diminishes.
So, because this particular example of "age" is complex, you dismiss the entire idea? This is bizarre reasoning.
I can tell you from actual practice, that there are loads and loads of cases where inline lambdas are way more concise and readable than explicit methods/functions. Being able to avoid naming every little ad-hoc data manipulation you do is a big deal. Just compare inline lambdas with e.g. use of Function<F,T> from Google's Guava library.
If your decision procedure and/or function is complex, you can (and probably should) still define an explicit method... but unless you're using it more than once, there's often no need.
Java the language is pretty much done changing. The Java 7 changes were just for pain points that happened to be relatively easy to patch over. Closures are the only major new feature we'll see added, mainly to make Fork/Join more usable. A few years ago, closures in Java would have been a big deal, but I'm not sure they'll make that big an impact once they finally arrive in Java 8. By then we'll likely have two or three viable statically-typed JVM languages with closures and a whole lot more (Scala, Ceylon, Kotlin), none of which will require switching to the latest JVM in production.
I'm looking forward to using Java 7 and 8, but for the platform improvements only. The platform matters more than the language now.
> I have also been skeptical of the benefits of closures, at > least the "easy, quick" ones everybody gives in demos. > For example, in his OSCON video, Odersky partitions > s people by age > > val (minors, adults) = people partition (_.age < 18) > > Such code is extremely sloppy and fragile, (yes, it's just > a demo!) and, since it's so "easy", we encourage coders to > do it this way. The real rules for the age of majority > are complex > (http://en.wikipedia.org/wiki/Age_of_majority#Countries_and > _subdivisions) and you'd really want to call a method.
I have countless examples in real code where the predicate really is simple. Is there any Java programmer who hasn't found the regular need to lookup objects in a collection by name?
val startingWithA = people filter (_.name.startsWith("A"))
Or extract just one field:
val names = people map (_.name)
> At that point, the conciseness "advantage" of Scala over Java > greatly diminishes.
You are joking, right? Let's assume the predicate is very complex and is moved to its own method. Scala:
def isMinor(age: Int): Boolean = {
// oh so complex majority rules
}
val (minors, adults) = people partition (p => isMinor(p.age))
In Java:
publicboolean isMinor(int age) {
// oh so complex majority rules
}
List<Person> minors = new LinkedList<Person>();
List<Person> adults = new LinkedList<Person>();
for (p : people) {
if (isMinor(p.age))
minors.add(p);
else
adults.add(p);
}
> val startingWithA = people filter(_.name.startsWith("A"))
To answer your question, I've never written code to collect names starting with "A". :-) I'm mainly into mathematical algorithms.
Many of the closure examples use name sorting. And I always ask, what if the person is Chinese and the order of their names is reversed??? IMO, inline closures encourage coders to write code that is harder to enhance and maintain. I avoid Java's anonymous inner classes for similar reasons, and they don't even have the advantage of succinctness.
> > At that point, the conciseness "advantage" of Scala over > > Java greatly diminishes. > > You are joking, right?
Your code (I'm not sure how to quote formatted code so I don't show it) shows that Java is 7 lines longer. If the complex isMinor() code is 70 lines long, the Scala advantage drops from 700% to 10%. I call that greatly diminished.
If that partitioning code appears once in the entire program, that's 7 LOC in tens of thousands. If the code is used more than once, it should be encapsulated in a single method. With some support structures (cause Java can't do multiple returns) and an interface definition, that's maybe 30 lines of code? I believe there are third party libraries too.
In the past, I have not used partitioning into 2 collections, but I have used filtering into a single smaller collection, and that's how I did it.
IMO, the real advantage of Scala closures is not the in-line closures. It's the natural use of closures, in-line or not, in parallel collections. This is a huge advantage, and something that will definitely get me to look deeper into Scala.
BTW, with a last name of "O'Dea" I would think you'd be sensitive to handling slightly unusual names. For example, what if you wanted to process all names by their first three letters. Eventually, your loop get to "Ode".
val startingWith = people filter (_.name.startsWith("Ode"))
That would pick up Martin Odersky. It would not pick up your name. But should it? Or do you have to special case iterate over every "O'A", "O'B", etc... Not to mention all the Mcs and Macs out there, the de Las and Vons and Vans etc...
That's a good link. It's a shame that, like you, it's both anonymous and a one-off posting. Still, it's nice to see someone posting with a bit of passion and vitriol and who can tell the difference between new and interesting.
Flat View: This topic has 64 replies
on 5 pages
[
12345
|
»
]