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.
Type checking to the rescue
If all you need is a scripting language and that you don't rely on the dynamic behaviour, since Groovy 2.0.0, you can add an annotation that will activate type checking:
The compiler will report errors at compile time instead of runtime. See GEP 8 - Static type checking for details.
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?
Since Groovy 2.0.0, you can annotate your code with @CompileStatic. Be warned that while this will improve performance, it changes the semantics of your code. See GEP 10 - Static compilation for details.