Runtime vs Compile time, Static vs Dynamic
I misspelled a method call, but it sill compiled. What gives?
Take this simple script as an example:
Note that running
groovyc Greet.groovy does not produce any errors. Instead, a
MissingMethodException is thrown at runtime.
This is because Groovy is a dynamic language. Several other things could be happening to make this code valid at runtime. Using the MetaClass, you could add a
salude() method to the Greet class at runtime. You could also add a
state property to
Number, which would make the
welcome(..) call valid. See ExpandoMetaClass and TMPGroovy Categories.
Will I get a performance boost if I statically type all of my fields and methods?
Actually, no. The way Groovy method selection is done, it actually takes longer if you provide lots of static type information. This could possibly change in the future, but as of Groovy 1.1 this is not the case. See this thread for more info.
But can't you add warnings so I can see missing methods at compile time?
In theory, we could. It would only work for methods available at compile time, and only for fields and parameters that you have strongly typed. But as we mentioned above, that hurts performance! Plus, there are a number of frameworks that rely heavily on dynamic methods (i.e. GORM ). In this case, you would get gobs of warnings, and likely just start ignoring them because it is just noise.
It might be scary to do away with all of your static typing and compile time checking at first. But many Groovy veterans will attest that it makes the code cleaner, easier to refactor, and, well, more dynamic. You should make all efforts to use unit tests to verify your intended behavior. Also keep in mind that Groovy also offers a slew of features to make unit testing easier as well.
Can't we provide some sort of "NotDynamic" flag to speed up method invocation?
This has been discussed on the mailing list many times before. Although it has not been ruled out entirely, there are many implications to such a 'feature'. The primary focus right now is to improve the performance of normal, dynamic Groovy. Groovy is already performant enough for "most" use cases. If you see a performance bottleneck in your code, the typical optimization path is to factor out those pieces to Java code, and call them from Groovy. See this thread and this one.