Thanks for taking part in the book giveaway. I had looked briefly at Groovy before and was first pleased with the automatic import of java.util, java.net, and java.io in all Groovy files. I'm still surprised nothing similar was done for Java 7 or Java 8.
One arguable advantage of Java's type system is that it's relatively easy to create an auto-complete system for an IDE (and I believe similar plugins exist for Vim and Emacs, though I've never toyed with them). As far as I understand, using a language with duck typing makes it much harder to provide that feature. Then I think the question becomes whether the other advantages of duck typing and -at least in theory- more rapid development due to duck typing outweigh the drawbacks of the reduced assistance your IDE can provide you.
I've been working with Java for 8 years and with C++ before that, so I don't have an accurate view from the other side of the fence. My impulse is to say that yes, a more flexible type system is worth the trade off. But maybe I would feel differently if I spend a few years working on Groovy (or Python, Perl, Clojure, etc...)
So my two questions:
1. What do you think about that same trade off?
2. Assume you were going to write a large application from scratch and use Groovy. Obviously if you found existing Java libraries that did much of the work you would import them. But outside that, I'm just curious if you would write a mix of Java and Groovy or just go for Groovy everywhere unless performance requirements forced you back into Java. Or in other words, do you personally view Groovy as an excellent Java add-on, or basically the language that you would always prefer to use instead of Java?
The issue of static vs dynamic typing is important in the IDE and arguably important in general. Sometimes new Groovy developers are like kids leaving for college after growing up in a restrictive environment, using def everywhere just because they can. As they gain more experience, Groovy coders tend to use def less and less.
Dierk Koenig, lead author on _Groovy in Action_, had the best quote on that I've seen. He says, "if I'm coding and I think of a type, I type it (pun intended)." In other words, if he knows the reference is going to be a String, or a Date, or an Employee, he puts in the static type rather than saying def. In that sense, Groovy is said to be optionally typed.
The def keyword is useful for testing, because if I want to create a mock object and the resource I'm mocking uses a def reference, I can set it to anything I like and rely on duck typing to provide the correct methods. If the reference is a File, though, I can only substitute in Files (or subclasses of File).
You will often find def used as a return type on methods. For example, in Grails controllers, by default each action (which is what Grails calls its methods) uses def as a return type, because it may return something, or do a redirect, or do a forward. Using def keeps its options open.
Of course, using actual types makes IDEs happier, and the Groovy plugin for Eclipse has improved by leaps and bounds over the last couple of years. IntelliJ IDEA is usually better, though.
You raised two other issues:
1. The list of automatic imports in Groovy is java.lang, java.util, java.io, java.net, java.math.BigInteger, java.math.BigDecimal, groovy.lang, and groovy.util. I agree that Java ought to do that too, but so be it.
2. Java is good for tools, libraries, and basic infrastructure. Those tools prefer Java interfaces, too, so one easy integration technique is to use Java for interfaces but implement them in Groovy. That makes the Java tools happy, while also keeping the developers happy.
I think the analogy to kids leaving for college is probably pretty accurate. I must admit, as I'm learning dynamically typed languages that behavior is definitely my impulse. Luckily for me unit tests should catch most of the flaws in my frenzy of 'defs' or equivalents. Too bad college students don't have a corresponding safeguard they can put into place after a night of excess to insulate them from most of the results.
Thanks also for the explanation of def for a return type as a useful place to take advantage of dynamic typing. I'll keep that in mind.
On point 1, I'm sorry but I did know the full list of automatic Groovy imports. I only listed java.util, java.net, and java.io because those are the ones that I've had to type in by hand so many times. (I could make a macro or use some other automatic feature in Eclipse, but I just developed the muscle memory habit of putting at least one of those three at the top of most .java files immediately after I type the package declaration.) I guess I should have made that clear for anyone else.
One of the biggest changes in the industry over the past few years has been the rise of automated testing tools, like JUnit, and the understanding that just because something compiles doesn't mean it's right.
I had a friend that taught some of those early C++ classes back in the mid 90s. Once a student called him over and said that his code wasn't working. When my friend looked at the code, he noticed that the first line started with /* and the last line ended with */.
He said, "you commented out your entire program."
The student responded, "that's the only way I could get it to compile!"
You still need tests or you haven't proven anything.
Btw, I assumed you knew the full set of automatic imports. I just listed them here for everybody else.