I can't take credit for this statement, since I am only drawing the logical conclusion from a statement said by a man far smarter than I.
Donald Knuth wrote in his famous paper Structured Programming with go to Statements (PDF):
We should forget about small efficiencies, say about 97% of the time: pre-mature optimization is the root of all evil
Since compilation is premature optimization, it is therefore, the root of all evil. Simple!
Static typing, weak typing, dynamic typing, strong typing, WTF?
There are a number of misconceptions concerning typing.
The meaning of weak and strong typing, is not clearly defined but is mostly interpreted like this.
In a weakly typed language, such as C, the types of the variables can be automatically converted from one representation to another, while in a strongly typed language an explict conversion is required.
This is not what I am writing about here. I am referring to static vs. dynamic typing and the definition I am using is:
- Static typing, the type checking is performed at compile-time.
- Dynamic typing, the type ckecking is performed at run-time.
Development Mode
Every time I build my code, my entire code base is type-checked. EVERY TIME! When I am working in development mode, I only care about the method and class that I am currently working on. As long as my tests pass I am happy, type-safe or not.
In development mode it is actually more accurate to call static typing pre-mature de-optimization than pre-mature optimization.
Production Mode
The only reason, to ever use static typing, is because the code may be optimized better, to give better performance.
So, the strategy should be:
- Use a dynamically typed language during development. It gives you faster feedback, turn-around time, and development speed.
- If you ever get lucky enough to have performance problems, which cannot be solved with caching or algorithmic optimization, rewrite the problematic code in a statically typed language.
This is what Twitter did, and it has worked well for them.
Other Misconceptions
Proponents of Java often have the misconception that dynamically typed languages are unsafe, yet they use frameworks, like Spring, and Qi4J, that are littered with reflective code, and without the so-called safety net that static typing is believed to give. The reason these frameworks are popular is because they allow us to be more productive. The reason they are more productive is because they use dynamic programming techniques.
Anyone, who has worked seriously with a modern dynamically typed language like Ruby or Smalltalk, know that they are more productive. Working with waterfall languages after working with agile languages is just painful. (Thanks to Andreas Ronge for coining the term Waterfall Language.)
Anders Janmyr
Consultant at Jayway

22 comments ↓
It appears however, that Twitter has replaced parts of its back-end with Scala nowadays, which is a statically typed dynamic language.
You can read about the reasons for it in this article:
http://www.artima.com/scalazine/articles/twitter_on_scala.html
Yes, I know Twitter is on Scala, that was one of my points. Twitter was developed in Ruby and after a long time they got the pleasure of having performance problems due to too much traffic. Then, they ported some of their code to Scala, which is not in any way a dynamic language according to my definition above. Scala is, however, a lot more elegant than Java.
Fair enough, but the argument that Ruby on Rails is good for developing web applications is vastly different from the discussion whether dynamic typing is overall preferable to static typing.
I don’t have an opinion about that, since the more I learn about it, the more it seems to be a matter of context, and personal taste.
I believe the biggest win with a dynamic language is when calling methods on object. In C++, and also in the Java programming language (not the JVM) classes are really just structs with functions pointers, constant set of functions pointers at that. Good for speed, but terrible for adjusting classes to the needs of your application context.
In a dynamic language such as Ruby, Smalltalk or Objective-C a class can have methods added and/or replaced at runtime, which leads to much cleaner code. Where should I put a utility method for a vector, if not onto the vector class itself?
That and allowing methods to be treaded as a primitive type, for far cleaner dynamic method dispatching. The method name
onClick()is ALWAYS a worse name than your ownonWhatIActuallyIntend(). Most Java interface are cubes in a world of round holes. Closures is a step closer, but not quite as nice to have.Fredrik: Note that the post is regarding statically typed vs dynamically typed languages and not static vs dynamic languages. It is this that makes a language like scala, which is statically typed, while still keeping most of the advantages of a dynamic language, to end up within “the root of all evil” according to the author.
I have to dissagree with the statement that “The only reason, to ever use static typing, is because the code may be optimized better”.
One of the reasons for using a static typing language is to detect the type related problems at compile time, and not have them popup randomly after deployment.
Actually, the title needs to be corrected. It should read “Ignorance is the root of all evil”, and your post is a good example. It’s “not even wrong”, to use another popular saying.
First of all, when I compile in Java, only the changed class gets compiled, not the whole codebase. If, I’m in debug mode (as I often am during developent) I can then dynamically replace the old class with the new, and try it out instantly.
Second, one of the primary reasons I prefer static typing, as in Java, is because the types allow me to communicate intent. I can tell other developers what I expect from them, and I can see by looking at the types of methods what they expect from me. It saves me, and others, a whole lot of trouble. If you don’t have to communicate with other people, meaning, you’re in your own reality bubble, then this has no value, obviously. YMMV.
Third, for users of Qi4j the reflection is an internal implementation detail. In fact, we go to GREAT lengths to ensure that users deal with statically typed interfaces so as to avoid the typical problems that arise when you can’t communicate intent using types (and there’s LOTS of such examples in invoke-style AOP frameworks). If you had spent five minutes checking this it would be clear to you, but sadly, you obviously didn’t do this. It is always much easier to make up an opinion out of thin air and post it, rather than finding out what-is.
This does not mean that I don’t like dynamic typing at all. In SiteVision, a CMS that I architected, we allowed customers to tweak and customize quite a lot by using JavaScript/Velocity. This was an essential tool, and to use Java for that would have been a bad choice. However, when we made changes to the internal API and made upgrades to the base software it was a NIGHTMARE to check whether any scripts using the old API still worked, since, well, we couldn’t just compile to find out. And no, we do not suggest that customers write tests for scripted tweaks. That would just be plain dumb. If I were to do that feature again I would probably opt for using a language which was statically typed, but which allowed eval-style compilation, so that I could go through all customizations and easily find out which ones had broken with the new API.
Lastly, as I wrote in my article “Quicker frameworks” on the DDD site, what all these so-called “productive” languages are doing is focusing on being “more efficient”, whereas it is more interesting to be “more effective”, as Qi4j allows you to be. It is less interesting to write code fast than to not have to write code at all. Which is the aim of Qi4j, due to the high focus on composability and reusability. Given your conclusion I assume you have not read that either.
As I said, “ignorance is the root of all evil”. And that holds in all walks of life, not just software development.
In a perfect world where applications have a test coverage of 100% there would probably be no need for statically typed languages. But in the real world 100% coverage is unattainable and you can (and therefore will) cheat your way around tests. So, as it is, static typing IMHO certainly adds to the robustness of the application as it is much harder to circumvent than tests and lets you see many errors right there where you write them.
I’m confused. What is the problem with your code being type-checked every time you build it, anway? Takes very little time with modern hardware and compilers, so I don’t have a problem with it.
As for runtime flexibility – well, how often do you actually, really need to add methods to a type while the software is running? I can think of very rare examples, all of which were achieved by other means (e.g., rewriting bytecode, V-tables etc) for that tiny handful of occasions in nearly 3 decades of programming experience.
I guess I have to defend my position
@Andreas:
> One of the reasons for using a static typing language is to detect the type related problems at compile time, and not have them popup randomly after deployment.
When did you actually have a type-related problem pop up after deployment?
@Rickard:
>”Ignorance is the root of all evil”, and your post is a good example.
Ouch!
>If, I’m in debug mode (as I often am during developent) I can then dynamically replace the old class with the new, and try it out instantly.
Last time I tried to do something like “extract method”, I got the helpful error message that reloading the class was not possible since adding new methods to a class is not supported. Please correct me if I’m wrong.
>It is always much easier to make up an opinion out of thin air and post it, rather than finding out what-is.
Aren’t all opinions made up out of thin air? An opinion is an opinion and even if others have a different experience, why should I change my opinion based on what other people think?
I’m sorry I haven’t read all the articles you mention, but thanks for pointing them out to me.
@Georg:
> So, as it is, static typing IMHO certainly adds to the robustness of the application
I disagree, I don’t think a statically typed application is more robust than a dynamically typed. It is also a lot easier to get good test coverage in a dynamically typed application where you do not need special mock-frameworks to be able to test the code at all.
@Jason:
> I’m confused. What is the problem with your code being type-checked every time you build it, anyway? Takes very little time with modern hardware and compilers, so I don’t have a problem with it.
I don’t think it takes very little time. In many projects where I have been involved the build times quickly take more than 1 minute.
Ruby is VBScript in trendier clothes and an oversize goatee, imho. The speed and Behind the propaganda the simple truth remains: proper typing is a Good Thing. With a half decent refactoring tool such as ReSharper there are no limitations during development and if you can accept that extension methods obviously only has access to public properties on the ‘this’ object, c# actually gets the job done.
One of my primary reasons I prefer Ruby over Java is that it communicate intent better.
When I work in Ruby I often look at the source code in third party libraries and maybe even modify them. In Java this is
very unusual since it’s so much harder to understand code that some one else has written.
You can also see this behaviour for Ruby projects on GitHub, for example Rails which has nearly 1000 forks of the source code.
Having read Ruby code and then going back reading Java code again is a pain.
I believe a type is often just unnecessarily ceremony which cause problems (you need a compiler, harder to test, tight coupling between components since you declare a dependency using types).
http://blog.thinkrelevance.com/2008/4/23/refactoring-from-ceremony-to-essence
Maybe it is a bit like the checked vs. unchecked exception debate.
One mistake I did when I started writing code in a Ruby was creating types for everything. Instead, it’s common to use arrays and hash (key value) data structures
which you can let your objects mimic when you need a type (e.g. by using Mixins).
I also believe based on own experience that big refactoring in dynamically typed languages is easier to do because
1. Some times it’s not even needed to do a refactoring because of duck typing.
2. You don’t have to do a big bang fix of all compilation errors before running your tests. A soon as you changed everything you can run your tests again
3. Your test code is more likely to survive a big refactoring. I think this is because it is not so tightly coupled with the producation code by a type system.
A common belief is that static typing is better for building large systems. That belief is out of thin air us much as any thing else.
What we want is \strong testing, not strong typing\ as Bruce Eckel writes http://mindview.net/WebLog/log-0025
and readable code that communicate intent. The only way to get convinced is to use a language like Python/Ruby in a real project.
There are also other advantages which is not directly related to the language.
In a language like Ruby there is less need (or no need at all) for complex tools and frameworks like IDE, IoC/AoP frameworks, utility libraries, etc.
Even if a tool or library is needed it is usually much less complex and easier to configure (configuration is code – DSL)
In bigger Java project is not unusual to use 100-1000 external jar libraries, complex application servers.
A lot of problem in big Java projects is related to configuring IDE, build tools, over use of XML (spring/WEB-XML, etc..)
Having used Ruby tools/frameworks and going back using Java tools is also a big pain.
Anders, thanks for your feedback. Based on your input I got new information, which helps me to change my opinion, since I now understand that it was not accurate. It is this type of exchange that enables us both to grow and learn new things, so that we are not stuck in opinions that don’t match reality. So, given this I’ll have to rephrase myself: “Persistent ignorance is the root of all evil”.
@RickardOttosson
>Ruby is VBScript in trendier clothes and an oversize goatee, imho.
I have no experience with VBScript, but I know that Joel Spolsky are using Wasabi, their own dialect of VBScript to develop their flagship product.
>The speed and Behind the propaganda the simple truth remains: proper typing is a Good Thing.
In your opinion.
@RickardÖberg
> “Persistent ignorance is the root of all evil”.
Actually, I think the saying goes “Ignorance is Bliss”
I’m basing my opinion on personal experience, many years with statically typed, and a few years of dynamically typed languages.
@Andreas
Hear, hear!
I have full respect for a lot of reasons that Twitter could have had for switching parts of their stack from Ruby to Scala, but those are not the reasons they give. Instead, the argument they use for moving to Scala indicates that they never understood the language they used, and to some extend even miss important facets of Scala, which of course is a pity.
I wrote some thoughts on the “Twitter moves to Scala” interview a year ago here: http://niclasnilsson.se/articles/2009/04/06/comments%2Don%2Dtwitter%2Don%2Dscala/
Rickard’s arguments about using static typing to communicate intent is an argument I like. From an API and/or framework perspective, it becomes even more important, and static typing also makes some tooling easier to create. This is one of the weakest things with a dynamic language, both when it comes to expressing a certain kind of intent and certain kind of tooling.
(Side note: I still think static typing is a very small piece here. Intent for the order methods must be called and such is still a big problem only solved by documentation in the mainstream. One approach that at least helps a bit that I myself prefer as developer documentation is to expresses it executable BDD-style specs with nice declarative output, with the possibility to open the spec/example to see the details, but it would be nice to have a declarative, machine interpretable way to document these things too).
However, I do not see the point in comparing a framework, like Qi4J, and a general purpose programming language? To me, Qi4J is very nice implementation of a kind of style (mixing / weaving / Composite Oriented Programming), but that’s a style that can be implemented in more or less any language. Some languages fight the style and makes it hard to create a framework like Qi4J, other languages makes it easier, and if the language helps or resists actually has very little connection to the axis dynamic vs. static typing. Composability can be easy or hard in both kinds of languages. I fully agree with the points on efficient vs. effective, but I fail to see why the use of a dynamic language can not be as effective (even though the approach differs a bit)?
In the best of all worlds, I’d like to pick and choose when I want to have static typing and when I want dynamic typing. I’d like to turn it on and off in different phases of my development, and I’d like to have some interfaces more statically typed, or at least checked that they correspond to an interface, but I’d be happy if it’s duck typed, kind of like the approach Go took (if I understood it correctly). Also, (since this seems to turn into a nice collection of links as well), I think Ola Bini has an interesting point here: http://ola-bini.blogspot.com/2008/01/language-explorations.html
Kind regards
Niclas Nilsson
—
http://niclasnilsson.se
http://twitter.com/niclasnilsson
After 15+ years of experience developing systems in statically typed languages (C++ and Java) and ~3 years with dynamic languages such as Ruby and Javascript, for me the main difference comes down to basic joy of use.
Developing in Ruby feels much more elastic, kind of like using modeling clay to build something. You change it a bit, get immediate feedback, change it some more, and before you know it you’re done.
With languages like Java, the modeling clay has a scaffolding around it that you need to move and alter before you’re allowed to touch the actual clay. So much of your day goes by tinkering with the scaffolding that you think it’s normal and necessary.
Or perhaps it’s more analogous to a bike with training wheels. They give you a sense of safety and comfort, but in reality they are what’s keeping you from going faster. Don’t be the kid who builds larger and fancier training wheels in order to go a little bit faster (would this be Scala in this analogy?
, try losing the wheels for a while and see what happens.
This is how it feels to me, your mileage will vary, of course.
Hi
Thanks for a fun discussion. I’m developing Android demo application (Eclipse + Java) and I don’t really have ‘walked over’ this problem, yet. Although I have some own opinions about the ‘root of evil’ in traditional embedded realtime system, the app monolith and the lack of a real DB. When will DLL appear in this world?
“modern dynamic language….like Smalltalk” – now that’s funny
It seems that your main argument is that you are willing to give up correctness, or spend a good amount more time developing tests, in order to feel less constrained by the type system.
I believe argument is based on some false assumptions. The first would be that static type systems must constrain you more than a dynamic type system. This indicates to me you have not tried a language such as Haskell where very little such constraints apply. You are probably basing these opinions on our mainstream statically typed OO languages such as C#, Java, etc…
Second, that unit tests adequately make up for the loss of static typing. Again, in Haskell for example it is very rare that your program does not work the first time it compiles (often the only errors you will find are bugs in the FFI and imperative libraries). There are a lot of \unit tests\ that you essentially get for free without being constrained hardly whatsoever by the type system.
Third, I find I am quite productive and can produce good software with just about any language, paradigm, type system, whatever. The problem starts when you have to work on a team with other people and/or the code base grows to a certain size. You can’t always rely on everyone to write comprehensive unit tests. You can’t always predict how code is going to be used in the future. You are not always going to be working on a team with 100% l33t developers who don’t go home at night unless everything is perfect. I can’t imagine how difficult it would be to create a large multi-team solution in a dynamic language with developers picked from all skill ranges.
So in the end I would say I strongly disagree. I believe you can have the benefits of both static typing and whatever freedom you might feel from dynamic languages. Haskell’s type system is a prime example of this.
@Niclas:
>Rickard’s arguments about using static typing to communicate intent is an argument I like
Yes, I agree with that too. Intent is a good argument.
>I do not see the point in comparing a framework, like Qi4J, and a general purpose programming language.
I wasn’t trying to compare languages and frameworks. I was just trying to show that the frameworks, that everyone sees the need for in Java, are based on dynamic programming techniques.
>I think Ola Bini has an interesting point
I read Ola’s article and one thing I think is interesting is that the programming stack Ola is writing about is reversed from, for example, Spring. Ola is talking about the bottom layer being static and the top layers being dynamic, while in Spring the bottom layer is dynamic, and the top layers are static.
@Rick:
> “modern dynamic language….like Smalltalk” – now that’s funny
I wasn’t trying to be funny. It just shows how much before it’s time Smalltalk was, and how a dynamically typed language can evolve, since you are able to change the language itself without releasing new versions of the langugage.
@Nathan:
Haskell is actually my favorite statically typed language. I have, however, never written any major application in it. Moreover when I tried to use HAppS (http://happs.org/), the Haskell Application Server , the types really got in my way. So much so, that I never actually finished the task that I had set out to do.
I know that unit tests, won’t give me the same security as a static type checking will, and I think that QuickCheck is beautiful. But I’m willing to forego that for the ease of development, the flow, that I get when programming in dynamically typed languages.
It’s quite alright for you to strongly disagree
Here’s a quote that I like.
I’m not against types, but I don’t know of any type systems that aren’t a complete pain, so I still like dynamic typing.
- Alan Kay
> I wasn’t trying to compare languages and frameworks
No, but I think Rickard was?
Kind regards
Niclas
—
http://niclasnilsson.se
http://twitter.com/niclasnilsson
I appreciate your response. I did not mean to make it sound like I think Haskell is perfect, as it has many other lofty goals such as purity and laziness that can be painful. But strictly in the context of static typing, I don’t feel that it is responsible for the pain and often gets a bad rap just because of poor implementations.
I once heard of a solution where a dynamic language would provide static type checking as a form of an \IDE \tool\, and not necessarily as part of the compiler (like refactoring, etc…)
I mean when it comes down to it, languages such as Ruby/Python are strongly typed. So if the type doesn’t get in your way during compile time it is possible that it will at run time
If not, then that is an artificial limitation of that particular implementation. Hence, my disagreement that static typing is the root of all evil. I think there is a more fundamental cause of this evil you speak of.
[...] Anders Janmyr wrote recently an interesting article why he hates static typing: [...]
Leave a Comment