104

I often heard the claim that dynamically typed languages are more productive than statically typed languages. What are the reasons for this claim? Isn't it just tooling with modern concepts like convention over configuration, the use of functional programming, advanced programming models and use of consistent abstractions - all of which could be used in statically typed languages as well? Admittedly there is less clutter because the (for instance in Java) often redundant type declarations are not needed, but you can also omit most type declarations in statically typed languages that use type inference, without losing the other advantages of static typing. And all of this is available for modern statically typed languages like Scala as well.

So: what is there to say for productivity with dynamic typing that really is an advantage of the type model itself?

Clarification: I'm more interested in big / medium sized projects than in quick hacks. :-)

9
  • 14
    Would you expect the "static duo" to be faster or more productive than the "dynamic duo"?
    – user8709
    Nov 29, 2011 at 11:17
  • What do you mean with duo? Anyway: I can think of a couple of reasons that static typing is more productive than dynamic typing: more compiler checks for errors, code completion, more information on the intent of the programmer in the code. That's why I am asking about the converse. Nov 29, 2011 at 13:26
  • 14
    It was a joke with a point. The "dynamic duo" is Batman and Robin. They wouldn't strike nearly as much fear into the Gotham City criminal underworld if they were called the "static duo". Since developers are people, superficial things can make a difference irrespective of what the terms mean.
    – user8709
    Nov 29, 2011 at 13:43
  • 2
    I totally agree with John Skeet msmvps.com/blogs/jon_skeet/archive/2009/11/17/…
    – user
    Feb 22, 2012 at 22:10
  • 1
    I think this question and the most upvoted response (mikera's) are both very much objective as possible. The 2nd-most upvoted response (Guillaume's) is more anecdotal and opinionated, yes, though there is great discussion here. And since the reason for the closing is flawed, the question should be reopened.
    – Jack A
    May 31, 2022 at 2:59

9 Answers 9

118

I actually think it's a pretty close call. Both dynamic typing and static typing have their advantages.

Reasons for dynamic typing being more productive:

  • It's more concise - A lot of extraneous boilerplate code can be removed if everything is dynamically typed - type declarations, typecasting logic etc. All other things being equal, shorter code is marginally quicker to write, but more importantly it can be quicker to read and maintain (since you don't need to wade through many pages of code to get a grip on what is happening)
  • Easier to "hack" techniques such as duck typing and monkey patching can get you results very quickly (although might confuse you later on...)
  • More interactive - dynamic typing is arguably more suitable for interactive, REPL-like programming for rapid prototyping, real-time debugging of running program instances or even live coding.
  • Test cases can catch the runtime errors - assuming you are using TDD or at the very least have a good test suite, this should pick up any typing issues in your code.
  • Better polymorphism - dynamic languages are potentially more likely to encourage the creation of polymorphic functions and abstractions, which can boost productivity and code re-use. Clojure for example makes great use of dynamic polymorphism in its many abstractions.
  • Prototypes - prototype based data / object models are in my view more powerful and flexible than statically typed inheritance heirarchies. Dynamic languages are more likely to allow or encourage a prototype-based approach, Javascript being a great example.

Reasons for static typing being more productive:

  • Better design - being forced to think about the types of values in your software up front can push you towards cleaner, more logical solutions. (I say can - it's still possible to design really bad code...)
  • Better compile time checking - static typing can enable more errors to be caught at compile time. This is a huge advantage, and is arguably the best thing about statically typed languages overall.
  • Auto-completion - static typing can also give more information to the IDE so that auto-completion of code or documentation lookup is more effective.
  • Discourages hacks - you have to keep type discipline in your code, which is likely to be an advantage for long term maintainability.
  • Type inference - in some languages (e.g. Scala) this can get you many of the conciseness benefits of dynamic languages will still maintaining type discipline.

On average my conclusion (after many years of experience on both sides of the fence) is that dynamic typing can be more productive in the short term, but it ultimately becomes difficult to maintain unless you have very good test suites and testing discipline.

On the other hand, I actually prefer statically typed approaches overall, because I think the correctness benefits and tool support give you better productivity in the long term.

21
  • 19
    +1, very detailed answer. The value of the point "Better compile time checking" can't be stressed enough.
    – NoChance
    Nov 29, 2011 at 8:57
  • 8
    Along with Type Inference, there's also Haskell-style overloading, C++ templates, generics and maybe some other language features which provide some of the advantages of Duck-typing within a static-typing framework - as long as the object provides the needed interface (it "quacks like a duck") you can use it, almost irrespective of that objects nominal type. The "almost" is because some approaches require some kind of "this type quacks like the relevant kind of duck" declaration - e.g. the "class" declaration in Haskell.
    – user8709
    Nov 29, 2011 at 11:25
  • 57
    I have to disagree strongly with your assertion that "shorter code... is quicker to read and maintain." There's an intermediate step, understanding the code. I've had to maintain other people's code in both Delphi and JavaScript, and the Delphi code is far easier to understand because it is more verbose. And most especially because the Delphi code has type declarations and the JavaScript does not. When dealing with anything more complex than primitives, type declarations make it trivial to see what your variables are and what they can do, which is essential knowledge for maintenance work. Nov 29, 2011 at 17:24
  • 27
    I beg to disagree with most of the reasons given here. Take Haskell, which has probably there strictest type system out there. It has a REPL (actually at least two), it features very powerful polymorphism by doing pattern-matching on constructors and it is as concise as one can hope for - much more than Javascript or Python. So I guess some of the reason you mention are accidental rather than inherent to loosely typed languages.
    – Andrea
    Feb 17, 2012 at 11:09
  • 23
    I would not put too much trust in "test cases". You can't compare them with a good type system. A type system provides a proof that your function will already be called with at least type correct parameters, while test cases can only provide empirical evidence. Yet even this evidence is gathered from an artificial setting.
    – Ingo
    Feb 17, 2012 at 11:36
71

With dynamic languages you can write crappy code faster than when using a typed language.

Once you have quickly created your huge pile of dynamic stuff, you can safely move to another project without having to care about long term maintenance.

This is productivity gain :)

I'm joking, but after having being involved in a project using 'dynamic language', I have been frightened by the amount of unnecessary tests, documentations and conventions you have to deal with if you want to have a working product.
And with the joy of lots of runtime errors that could have been caught at compilation.
Oh, I also forgot to rant about all those hacks and voodoos that meta-programming let you introduce in your code !

So the productivity gain might be a myth for medium/big project over its lifetime.

2
  • 16
    Yes, my experience is the same. A 100 lines perl script is ok, and without such great tools we'd been lost. But a 100k line perl project will most probably be a nightmare.
    – Ingo
    Feb 17, 2012 at 11:41
  • 6
    ...and then you have JavaScript (not just dynamic but also weakly typed).
    – Den
    Jun 20, 2014 at 11:22
17

There is a theoretical view to this problem too: A static type system is essentially a specialized theorem prover which only accepts the program when it can prove the type-correctness of it. All static type systems reject some valid programs because no decidable static type system is powerful enough to prove all possible type-correct programs.

One could argue that those programs that are not provable by a static typechecker are hacks and/or bad style, but if you already got a valid program and the typechecker doesn't accept it, it certainly is impairing your productivity in the short run.

Some cases where you might notice the type-checker getting in the way is with generic containers and co-/contravariance in arguments and return types.

5
  • 26
    Conversely if you have erroneously entered an incorrect program the compiler tells you immediately and highlights the bad line. this improves your productivity, when compared to noticing a failed test run and debugging to find the error.
    – MarkJ
    Nov 29, 2011 at 19:04
  • 8
    generic containers and explicit co-/contravariance are meant to "get in your way" if you do it wrong. what's the benefit of compiling code which will fail at runtime?
    – M.Stramm
    Aug 31, 2012 at 7:49
  • Usually job is considered 0 % done until it runs all the tests successfully. Only then your progress can be considered more than nothing. With that in mind, I don't think it's worth measuring your productivity on something that hasn't been finished yet.
    – Pijusn
    Mar 26, 2013 at 15:25
  • 1
    -1 Doesn't address the actual question ("productivity gains", remember?) Also, you probably don't even want to write those "valid programs the type system rejects". Just because you can doesn't mean you should. And why would you even have a "valid program" which the typechecker rejects? What, were you coding a Javascript program and suddenly tried to make it compile in Java?
    – Andres F.
    Nov 19, 2015 at 21:11
  • Those valid programs that the type system rejects can help shorten your code thus leading to fewer errors that the type system can't figure out (less code = less errors). The compiler / IDE highlighting the line can be done in dynamic languages with test values (i.e REPL driven development) so you can see the intermediate values, and they can pick up errors that your type system can't as well as type errors. You can also use static type inference to give you type warnings.
    – aoeu256
    Oct 3, 2019 at 19:43
17

One advantage I've found with most dynamic languages is that they make it easier to write more generic code. It's much easier to write at a higher level of abstraction when you don't have to fight the type system to do so.

You don't have to think about it as much--writing code that does something nontrivial with any object in Java is difficult and probably requires reflection which is basically dynamically typed; with something like JavaScript, writing a function that does something interesting to all objects is second nature. A perfect example would be a function I recently wrote that takes an object and replaces all of its methods with ones that do the same thing but also fire off an event. I have no idea how to approach something like this in Java. However, I'm not sure how much of this is due to the type systems and how much is due to other language differences.

However, I've recently started using Haskell. Haskell lets me write abstract, generic code as easily as any dynamically typed language I've used. My Java/JavaScript example above makes no sense in Haskell because it doesn't have objects, methods, events or even much mutation, but other sorts of generic code are really easy to write.

In fact, Haskell can write some generic code that dynamically typed languages can't; a perfect example is the read function which is basically the opposite of toString. You can get an Int or a Double or whatever type you want (as long as it's in a certain type class). You can even have polymorphic constants, so maxBound can be the maximum Int, Double, Char...etc., all depending on what type it's supposed to be.

My theory now is that the productivity gain from using a dynamic language is always in comparison to languages like Java with less capable, more verbose and less flexible type systems.

However even Haskell's type system has some annoying issues that you would not have in a dynamically typed language. The biggest one I've been annoyed about is the way numbers are handled; for example, you have to mess around with the type system to use length (of a list) as a double, something you would have no issues with without a type system. Another annoying thing I've run into is working with Word8 (an unsigned int type) and functions which expect Int.

So, ultimately, having no type system makes it easier to write generic code without thinking too much and also avoids annoying pitfalls of type systems. You never have to fight the type system in a dynamic language, but you can't rely on it either.

6
  • 2
    Yes, for some reason number systems are hard to get right. In scala it is also a mess. I think dynamic type systems win hands down over simple static typesystems in terms of ease of working with it, but lose from the more advanced ones (like Scala, Haskell, ML etc, which all uses variants of system-F). Sep 19, 2014 at 18:30
  • 6
    Your answer is well-meant, but has mistakes. First, it's not true that dynamic languages "have no type system", so that cannot be the reason they "make it easier to write generic code". They don't make it easier, as your own counterexample with Haskell shows (you debunk your own assertion!). "You never have to fight the type system" is false: you fight it every time you must fix a bug which was caused by not enough static typechecking. Finally, explicitly coercing the Int returned by a list is trivial; example: 1.0 + fromIntegral (length myList), i.e. just use fromIntegral.
    – Andres F.
    Nov 19, 2015 at 21:20
  • 3
    Finally, "writing code fast" != "being more productive". Your code has to work! If you write buggy software which you must later spend time debugging and fixing, you are not being productive.
    – Andres F.
    Nov 19, 2015 at 21:22
  • 3
    "without thinking too much" red flag for what most people mean when they talk about dynamically typed languages being "more productive" Nov 7, 2018 at 23:26
  • 1
    If type systems really improved productivity where are all of the useful applications in Haskell or Idris? I think things like how easy it is to understand the type error, "patchability" (ability to edit your application in unpredictable ways) and 90% error checking of doctests & type inference may be more important.
    – aoeu256
    Oct 3, 2019 at 19:54
15

Q: I often heard the claim that dynamically typed languages are more productive than statically typed languages. What are the reasons for this claim?"

This has historical reasons. If you go back a few decades, dynamic languages were indisputably vastly more productive than static languages (while also significantly slower). Perl is clearly much more productive than C if you know both and the task at hand allows either. But over time languages have borrowed a lot from each other, and newer languages are narrowing the gap (both in productivity and performance).

Here are some points to consider:

Garbage collection: Garbage collection is a huge productivity boost. I believe Java was the first mainstream static language with GC. Before this, static basically meant manual memory management. (Note: Here and in the following I'm only considering mainstream languages. Lots of experimental and niche languages exists which will provide counterexamples to any point I make.)

Memory safety: It is a productivity improvement that you don't have to worry about shooting yourself in the foot. Before "managed" static languages like Java, static typically meant direct memory access. Debugging is also a part of productivity, and unsafe memory access can lead to really obscure bugs.

Cumbersome type systems. Before the introduction of parameterized types (like templates or generics) in static languages, the limitations of the static types systems were often a burden. For example in Java you had to explicitly downcast every time you picked an item from a collection. So you got the syntactic overhead of a cast and no type safety. Considering how ubiquitous collections are in programming, this was a major drawback.
Having to declare the type of everything is a lot of redundant typing, but with modern type inference, this can be reduced significantly.

Big standard library. Python was famously advertised as "batteries included" because of the large standard library. This in comparison with C which have a very minimalist standard library. But with platforms like Java and .net, a vast standard library is becoming standard, and newer languages like Scala and F# are inheriting this "for free".

First class data structures. Dynamic languages like Perl and Python have built-in first-class data structures like lists and maps with convenient syntactic shortcuts for common operations. Compared to this, C have no built-in collections except fixed-size arrays.

Closures and lambda syntax - dynamic languages typically have had this from the beginning, but static languages have adopted this, most recently Java.

REPL the ability to quickly test code snippets interactively is a huge boon. But though IDE tools, like the "immediate" window in Visual Studio, static languages can emulated this to some extent.

Advanced tooling - in addition to the above points where static languages are getting closer to the convenience of dynamic languages, modern editors are taking advantage of static analysis in a way that dynamic languages have a hard time matching. For example editors can provide safe automatic refactorings, something that is strictly speaking impossible in a dynamic language.

Bottom line: Historically it was true, but today the answer is less clear cut.


Q: So: what is there to say for productivity with dynamic typing that really is an advantage of the type model itself?

It is somewhat hard to separate the dynamic typing model from dynamic languages, but as an example C# have adopted more an more dynamic features over time, even though it as its core is a static language. This is really a proof of benefit of the dynamic type model. Examples:

Reflection Reflection is fundamentally a dynamic typing feature. You inspect object types at runtime rater than compile time. When it was introduced it was kind of frowned upon, but in C# the use of reflection gets more and more ubiquitous, for example ASP.Net MVC uses reflection heavily.

Attributes Attributes are an example of dynamic typing. You can add arbitrary attributes to a class at compile time, and then you inspect at runtime (through reflection) and manipulate objects based on it. Something like MEP is basically an extension framework based on a dynamic type model.

Linq to SQL, EF mv. The various Linq transformers inspect queries as runtime objects and generate sql on the fly. It doesn't get more dynamic than inspecting code at runtime. CodeDom is the other side of the coin, where code can be generated at runtime

Roslyn Roslyn basically implements eval, which was once considered the defining feature of a truly dynamic language.

Dynamic The dynamic-type is the most explicitly dynamic feature in C#, and is advertised at making interaction with external objects and languages simpler and more productive. But it is also used in Asp.net MVC for convenience.

The benefit of all the above features shows that the dynamic model have definite advantages even in a static language with parameterized types, structural types and type inference.

11
  • I really don't like this answer, because nearly all the points don't address the core question, "What is the supposed productivity gain of dynamic typing?" not dynamic languages.
    – nanny
    Nov 19, 2015 at 21:17
  • 1
    @nanny could you elaborate on your perceived difference between dynamic typed languages and dynamic languages? (its one of those fuzzy things). Could you give an example of a dynamic typed language that isn't a dynamic language, along with clear definitions of each?
    – user40980
    Nov 19, 2015 at 21:21
  • @nanny: The question actually asks about "dynamically typed languages", not just "dynamic typing".
    – JacquesB
    Nov 19, 2015 at 21:25
  • @MichaelT Sorry I wasn't clear. Dynamic typing is one aspect of all dynamic languages. This answer is talking about others aspect that, historically, dynamic languages tend to come with, without actually addressing the dynamic typing part.
    – nanny
    Nov 19, 2015 at 21:31
  • 1
    @nanny: I'm basically answering this: "I often heard the claim that dynamically typed languages are more productive than statically typed languages. What are the reasons for this claim?" - I believe the reasons for this claim are historical and related not only to dynamic typing but also to other productivity improving features of dynamic languages.
    – JacquesB
    Nov 19, 2015 at 21:41
6

The whole of all modern language features is so big, that static vs. dynamic typing alone doesn't carry much weight.

The rule is, the better your language features, the shorter your code. That's quite simple. Java shows how static typing can go awfully wrong, which gives its opponents much to feed on. Poorly designed language features generally come with a cost, and static typing in Java is firstly a mandatory feature (otherwise most people probably wouldn't even use it) and secondly poorly executed.
This is why in comparison most dynamic languages shine, even though I would argue that PHP doesn't really make your life better in the grand total (at least until recently), because of many other quirks unrelated to type systems.

On the other hand you have a lot of languages with expressive type systems that don't get in your way and that even aren't mandatory. And some of them even allow embedding untyped code, whenever you need to escape the type system.

Personally, I use haXe, which is a language with type inference, both nominal and structural subtyping, optional untyped code, first class function types, algebraic datatypes and (not quite mature but extremely powerful) lexical macros, all the while avoiding arcane syntax. After using haXe for about 3 years now, I have come to a simple conclusion:

Programming becomes far easier, when your language doesn't lock you into religious choices about paradigms but tries to just be a good tool. There's a number of static and dynamic languages and mixed languages, that succeed at that. Some of them are easy to learn, most hard to master.
Their power comes from the way their individual features can be composed to easily create simple solutions to complex problems. This precludes a certain orthogonality that can only be achieved through a delicate balance of inclusion or omission of all language features explored so far. If you tried to add static typing to Ruby, you would cripple it, if you tried to take it away from Haskell, you would crush it. In contrast to that: if you took it away from C, people would hardly notice and if you took it away from Java, some might thank you.

From my personal experience, I can tell you this: I like Ruby. It broadened my horizons and the way I design systems. IMHO it should be used to teach people programming in the first place. It is unobtrusive, powerful, concise, fun. I understand why somebody coming from an orthodox language will enjoy it.
On the long run however, static typing permits to defer work to the static analyzer and with type inference this comes basically at no cost. The result is code that is easier to maintain and often runs faster.

But again, static typing alone can't do a thing. It's a matter of combination. I think somewhere between F#, Scala, Nemerle, OCaml or haXe you can find your very own optimum. But that ultimately depends on you, because the language should allow you to embed your thoughts without effort, instead of forcing you to bend them around it. And after all, nothing yields more productivity gain, than if programming is fun.

2
  • "The rule is, the better your language features, the shorter your code." This might be down to opinion on some level, but I don't think this statement is accurate. Shorter code doesn't offer too many advantages on its own, other than involving less typing at write time, and maybe taking up less disk space (which is a non factor in compiled languages anyways). I think the mark of a good language is conveying as much information about what it's doing in the most concise manner possible. Dynamic typing isn't very self-documenting and loses maintainability as a result imo Nov 8, 2018 at 0:05
  • You can supplement dynamic typed code with information like default values / keyword arguments, types gotten from type inference, dynamic type inference from a JIT compiler, or just logging all functions [go through every function or class in a running program and replace them with a version of the function that logs its arguments/results). Then you can see the log of the previous runs of a function. Another idea is to reject code that neither has type annotations, run-time contracts, or sample REPL session tests but give the developer the option of choosing any of the three.
    – aoeu256
    Oct 3, 2019 at 20:04
4

Personally, the only reason dynamic typing would help is if you are a really slow typist or you build giant functions/methods/whatevers that are hard to navigate. You also have to get into the whole unit testing issue. Dynamic types require (unless you like writing broken code) vigorous unit tests (To ensure that your dynamic types don't blow up unexpectedly (ie variable is duck mostly, but dcuk accidentally sometimes)). Statics will try much harder to prevent this (And yes, you can make the argument for vigorous unit tests)

1
  • Well the Preschelt study suggest that static typing people are overconfident in their types, and so they test their application less often and so they are more likely to get bugs that aren't type errors. However, it was a small application*.
    – aoeu256
    Apr 28, 2021 at 20:35
0

I think first of all you need to define "productivity". What does "productivity" mean and include?

If by "more productive" you mean writing less lines of code to implement the same feature, then yes, dynamic-typing programming languages are more "productive" than static-typing languages.

However, if you also consider the time spent on debugging and bug fixing, then dynamic-typing languages may not be that productive, because dynamic-typing languages tend to push the error checking to run-time while, in contrast, static-typing languages can perform some error checking in compile time. As it is commonly accepted that, usually, the later a bug is found, the more expensive to fix that bug. Therefore, dynamic-typing code may result in the generally equal or perhaps even less than the productivity than static-typing code.

4
  • In general, it's not true that you can write a feature in fewer lines using a dynamic language. Which languages are you comparing, anyway?
    – Andres F.
    Nov 19, 2015 at 21:25
  • @AndresF. Oh, I mainly use Python and C++.
    – yaobin
    Nov 20, 2015 at 22:17
  • 1
    Ok, but you cannot generalize dynamic vs static when you're actually comparing Python and C++. C++ is not a particularly representative example of a language with static typing. There are extremely concise statically-typed languages, which more or less allow you to write programs as brief as with Python. So, in general, your assertion is false.
    – Andres F.
    Nov 21, 2015 at 19:59
  • Yeah, but what if you edit your program while its still running? Any run time issues will simply occur and you can fix them right there. In Lisp, whenever you get an error you can just fix your program and then continue running it... Yeah for more complex paths type annotations would be good [maybe you can use gradual typing like mypy & lisp], but those more complex paths also have the possibility of non-type errors so avoiding complex paths in any language may be a good idea.
    – aoeu256
    Oct 3, 2019 at 20:17
-1

The big advantage of dynamic typing is productivity.

Python, Ruby etc. have lots of other productivity boosters besides dynamic typing (default parameters, dictionaries as built in types etc.etc.) the cumulative effect on programmer productivity is impressive.

The penalties in terms of speed (or lack of!) and resource consumption are not as bad as you would expect and in most cases are more than compensated for by development speed and flexibility.

There is a (very old!) paper on the subject here. It is one the the few properly conducted studies on programmer productivity and many of the conclusions are still valid.

What would (probably) be different were the study to be conducted today:-

  1. Java JVMs have improved beyond recognition.
  2. Modern IDEs would have improved the C++, and Java coders productivity, but, made very little difference to the scripting languages.
  3. C# would be included and probably be in the same ball park as Java but slightly better.

So the message is unless performance is a really serious issue dynamic languages will boost your productivity.

12
  • 2
    My unclarity is what exactly it is that dynamic typing does to boost your productivity. The paper is interesting, however it is about a very small program, and I'm not sure how this carries over to the many thousands lines of code in most programs. Nov 29, 2011 at 17:06
  • 5
    That study only uses C, C++ and Java as examples of static languages, and then attempts to apply the conclusions found to traditional programming languages in general. All three languages share the same basic syntax, with the same inherent, prductivity-decreasing flaws, making the comparison invalid. It's not that static languages are unproductive, it's that the C family is unproductive. Had they included a Pascal dialect in their tests, they'd most likely have reached some different conclusions. Nov 29, 2011 at 18:16
  • @mason -- there are very few actual objective studies in this field. This is one of the few real studies with actual numbers etc. The "sample" program is not trivial! It combines elements of dictionary handling, complex algorithms and large data volumes. The high percentage of failed and crashing attempts confirm the non-trivial nature of the task. Nov 30, 2011 at 1:32
  • 2
    -1 You are not saying much about what makes dynamic typed languages more productive. Default parameters and dictionaries can be found in static typed languages like e.g. Scala.
    – Jonas
    Nov 30, 2011 at 16:57
  • 1
    @JamesAnderson Even worse, the paper you linked to doesn't even support your point. It compares "scripting languages" (often dynamic) with "conventional languages" (often static). Now, tell me, what exactly are "conventional" languages? Do you think it's the same as the set of languages with static typing? Even worse, the paper is not that old. By the year 2000, lots of great languages with static typing which were arguably more productive than dynamic languages already existed.
    – Andres F.
    Nov 20, 2015 at 13:33

Not the answer you're looking for? Browse other questions tagged or ask your own question.