Search code examples
javagroovydynamic-languagesparadigms

Can you have too much of “dynamic” in dynamic languages?


In last few months I have been making a transition from Java to Groovy and I can appreciate many of the benefits it brings: less code, closures, builders, MOP that in the end makes framework like Grails possible, ease with mocking when writing tests etc.

However, I have been “accused” by my coworkers that my code is not groovy enough. Namely, I still declare types for my parameters and fields, tend to use inheritance and polymorphism instead of duck typing etc. It seems to me that in these situations it is not only dynamic vs. static, but also dynamic vs. object-oriented paradigm kind of dilemma. In those cases I still tend to prefer OO. I feel that OO paradigm has great value in its basic premise in allowing you to abstract and relate your code constructs to particular real-world concepts.

So, here are particular questions I need help with:

  1. Should I declare types for my parameters, fields, etc?

  2. Should I declare block of code as closure when simple method will do?

  3. When should I use duck typing instead of polymorphic dynamic dispatch. For example, in groovy I can do animal."$action"() or def animal; animal.action() , instead of Animal animal = new Dog(); animal.action(). I can see the problem with first in the context of Open-Closed principle, but any other reasons to prefer OO style polymorphism?

  4. When should I use interfaces in groovy (if ever)?

I am sure that there are some other similar dilemmas I failed to write down. I also think that these questions are valid not just for groovy, but for any other dynamic language. What is your opinion?


Solution

  • .1. Should I declare types for my parameters, fields, etc?

    I tend declare types on classes that are used as part of a public API, things that other developers will be consuming a lot, or where I'd like some additional autocomplete help from IntelliJ. Otherwise I 'def' things.

    .2. Should I declare block of code as closure when simple method will do?

    I use methods unless it's something I plan on passing around as a variable. Even though there is the "foo.&bar" method dereference operator, most devs don't know about this and are confused by it when they run across it. I also use closures when it's a small piece of code that is clear to remain in a larger method rather than put in it's own method for descriptive purposes.

    .3. When should I use duck typing instead of polymorphic dynamic dispatch. For example, in groovy I can do animal."$action"() or def animal; animal.action() , instead of Animal animal = new Dog(); animal.action(). I can see the problem with first in the context of Open-Closed principle, but any other reasons to prefer OO style polymorphism?

    I only use the animal."$action"() form when I need that level of indirection because the method name varies based on the code execution path (most often during heavy metaprogramming). I use Animal animal = new Dog(); animal.action() when I want the IDE's help with autocompletion, or that level of documentation is helpful for code clarity (and not hurt by the extra verboseness that might be obvious or constraining).

    .4. When should I use interfaces in groovy (if ever)?

    I very rarely use them. I could see using them mostly as documentation of the expected fields for a public API call, or possibly as a marker interface to help distinguish one set of classes from another from a metaprogramming perspective. They're much less useful in groovy than they are in java.