4 Examples of a Dynamic Language Beating a Static Language
There has been a lot of discussions about the superiority of static languages vs. dynamic languages in recent years. Many great minds have contributed arguments for both sides of the discussion/argument. I’m not a programming language designer myself, so I won’t go over the finer points and benefits of a powerful type system. Be sure to check out the links in the additional resources section at the bottom of the page, though, as they are a really interesting read.
I also won’t try to convince you that a type system catches more bugs than some tests. Nor that tests are inevitable anyway, making a type system is kinda obsolete. Almost all developers share strong opinions on these topics, so let your steam out in the comments or throw 140 chars to @shelajev.
Dynamic Language vs. Static Language for Coding
Dynamic coding languages are designed to increase programmer output, using dynamically generated code to quickly implement functionality to an application. Static coding languages, on the other hand, are slower to work with, but because developers (typically) write only the code they need, the resulting code is more performant.
For an application that needs to run at scale, for instance, dynamically-written code may cause performance issues that statically-written code may not.
Why Use a Dynamic Language vs. a Static Language?
It is believed that a static type system will help you more than it will get in your way. While my favourite JVM language is Clojure, I feel to be at my most productive in Java. Mostly because of the experience I have in writing it. I really want to show you some of the situations where a dynamic language is preferable over a static one and try to make you actually think about the choice more carefully, the next time you encounter a problem that requires whipping up some code quickly.
Here’s a lemma to start us off: a compiler is an entity that has an opinion on your code’s correctness. It can reject your efforts by specifying whether a program is valid or not. A runtime is also an entity that might have an opinion on the topic. The major difference is when the type checking happens.
4 Situations Where You Should Use a Dynamic Language
In type theory, types are logical propositions. The programs that work with those types are proofs of those propositions. That’s the main takeaway I learnt from a type theory course. Without going into detail about what that actually means, I just want to look at a certain aspect of this fact. Programs are equivalent to theorem proofs. Proving things tends to be difficult and time consuming. There’s a simpler way of having no type information and not having to prove to a computer that your program works.
So here are 4 situations where you prefer a dynamic language or runtime.
1. You’re Writing Glue Code
This one is straightforward, right? When you create a library, or some component of the system that will be consumed on a higher level, you want a strong static type system, you want all the help the compiler can offer you and your consumer to make things right. If you’re not investing time into proving how things are transformed with the type system, you’re going to document it in much more detail or handhold every consumer until they understand what they are dealing with and how to use your creation well.
Now, imagine a typical web application. The main parts are specified a long time ago: clients will connect, pass HTTP parameters, there’ll be a URL, behind everything will be a database with the data that your code has to crunch and render. Everything is taken care of by the libraries, you just need to specify the business logic.
Here’s the minimal example of a Spring Boot application with Groovy. It is trivial, but so are the more complex web systems too: they just pass the data through. If your code is passing the data to and from components and is not consumed itself through the language level API by anyone else then it doesn’t have to have the extensive type information. There’s no one to benefit from this meta data. Dynamic languages rock for such code. You don’t work with, against or around the compiler, the runtime understands you perfectly.
2. You Like REPL
Imagine you have a REPL in a running application, sounds wonderful, doesn’t it? You can create snippets of code and execute them on the fly inside a running system, you debug like the old gods and have the the most fun you’re allowed to with a computer.
The thing is, your code is in the runtime already, the structures are loaded into memory and whatever you do you do at runtime. So the runtime gives you more detail about whatever it infers about the code: does it return anything, does the universe blow up if it is run.
Here’s an example from an article about Java 9 Shell:
Since the runtime knows the val is a double, do we really want to specify the type for that variable at the time of punching the text in? It’s a minor inconvenience, and it might save us if the Math.sqrt call returns something else instead of a double. But we’re at runtime and the type system that checks at runtime is dynamic. There’s no point in paying anything for the compile time type checks when you’re patching your code on the fly.
3. You Want to be Productive
This one might be a stretch, as you can be a productive developer in any language without any thoughts to type systems. However, you do want to make sure you have the easiest time iterating on the code level.
Here’s a blogpost on Google Developers medium that emphasises this issue. If your code stack allows quicker iteration of: “think about a change to make--implement the change--verify that it is useful” cycle you’d be able to change the code quicker and in the long run be more productive than in other technologies.
Naturally, at ZeroTurnaround we’ve been saying the same thing for ages. You want to apply the code changes to a running process without any delays, instantly — that’s how you become productive.
If you want to do that on the JVM, here you go: JRebel - a javaagent that reloads your code changes instantly in the running JVM process. You don’t need to restart anything and the latest version of the code magically gets loaded into the correct place, ready to be executed.
In order to do so, JRebel enhances the way the JVM loads classes, calls methods and refers to the fields in the objects. It adds a level of indirection to increase the flexibility.
Do you want another example? Look at sbt compilation times. It doesn’t come from the fact that Scala is dynamically typed, on the contrary, Scala’s type system is comprehensive and complex, and to verify all the claims in the typed code the compiler has to work harder. Next time you wait for your project to compile think how cool it would be not to waste that time.
Well, if you also happen to work in Java, check out JRebel, I cannot imagine you being disappointed with that.
4. You Want to be Semi-Dynamic
Surely I realise that whatever is written in the internets, you won’t be persuaded to change your opinion on such a fundamental topic. And it certainly won't convince you to change your habits, but it might make you aware that there's always the right tool for the job.
So, if you’re on the dynamic typing side of the things: here are some arguments for your next discussion. If you’re not - then remember that sometimes you do want to have a dynamic system even if you’re less comfortable with it in the beginning of your journey.
A lot has changed since this article has published, but the articles below help to frame it into the ongoing debate.
Want to be more productive during your Java development?
See a demo of our Java productivity tools, JRebel and XRebel.