The Dynamic Languages Renaissance
- Clash of the Type Models
- The Question of Speed
- Availability
- Dynamic Languages Are Fun!
Most of the code I write these days is in one of a small set of dynamic languages: Objective-C, Smalltalk, or JavaScript. JavaScript is probably the most widespread language available. Almost every web browser includes an implementation of it and it's the de facto standard for the client-side component of web applications.
Objective-C languished for a long time under NeXT. Some poor marketing decisions lead to C++ becoming the accepted extension to C in most of the industry, and for a long time Objective-C was regarded as being slow. The fact that it was fast enough to write device drivers for NeXT systems running on a 25 MHz 68040 was largely ignored.
Smalltalk suffered a similar fate. It's used in a few financial companies, which value the ability to modify their code massively on short notice. The best web application framework is still Smalltalk-only, but apart from a few niches it has been ignored. Part of the reason was the whole-environment approach taken by Smalltalk, where you had a choice between using Smalltalk for everything—or nothing. I hope that this situation will change soon. A few months ago, I committed the initial version of a Smalltalk compiler to the Étoilé repository, which is toll-free bridged with Objective-C. (Objective-C objects are Smalltalk objects and vice versa.)
Recent years have seen a gradual shift toward more dynamic languages. Although many of these languages are over 20 years old, they have begun to experience a rebirth, in terms of both use and development. This article takes a look at why this change is happening.
Clash of the Type Models
Dynamic languages are often regarded as "loosely typed" or even "untyped." But dynamic languages can have strong typing. Strongtalk was a dialect of Smalltalk that supported an optional strong type system, and Objective-C has a similar type model. (Actually, Objective-C has two orthogonal type systems, but I won't get into that discussion here.)
Throughout the 1980s, there was a familiar refrain from the type theory community: "Strong static typing can make code faster!" Then the Strongtalk team produced the fastest-ever Smalltalk implementation—but they did it without using the static type information. They discovered something quite interesting, which is that runtime-type feedback gives more accurate type information than static type tagging. If you define a method that takes an object as a parameter, as a programmer you try to specify the tightest type constraint that still allows any object you might want to use. In most cases, you end up specifying a much wider set of potential types than you ever actually receive. Type feedback, a mechanism that simply tracks all of the types you actually do receive, gives much more accurate information.
Then, in the 1990s, people started saying, "Well, maybe strong static typing doesn't make languages faster...but it does make them safer!" Java is often used as an example. Java was designed as a derivative of Objective-C, with syntax like that of C++. The type system in Java is very similar to that in Objective-C, complete with easy mechanisms for completely circumventing it—and yet Java code is generally safer. The reason has less to do with the type system than with a few minor tweaks such as automatic bounds-checking on arrays, and not allowing pointer arithmetic. Smalltalk has the same features and the same benefits.
A few bugs are found by strong typing, but very few. Of course, the result depends on the expressiveness of the type system. Something like SPARKAda allows arbitrary constraints to be annotated to various bits of code and incorporates design-by-contract at a very fine granularity, which actually works better than a strong type system. This kind of thing is also possible with dynamic typing, and both are possible with a dynamic language.
Dynamic languages are often dismissed by people who expect their type system to find their bugs, and similarly loved by those who spend more time fighting their type system than writing code. This debate is misleading, however, since a dynamic language can have a strong type system. The only requirement is that a static type system shouldn't affect the runtime semantics. A type system in a dynamic language can indicate whether a program is valid, but it can't alter the behavior of the program. This fact allows a dynamic language to have several different pluggable type systems, rather than a single one supplied by the language designers.
Whether a static type system is a good idea is an argument on which programmers will never agree. With a dynamic language, agreement isn't necessary. In Objective-C or Smalltalk, you can treat every object pointer as untyped, or you can specify a class for every object pointer. Which style you choose is up to you. Adobe's ActionScript allows a similar model, and a few Smalltalk dialects allow more complex type systems to be added to perform both runtime checking and static analysis when a program is loaded.
The idea of a pluggable type system is quite new. A few dynamic languages have had optional type systems, but it wasn't until 2003 that Gilad Bracha proposed the idea of having more than one optional type system in a language. In retrospect, this is a logical development from the idea of a dynamic language. In a dynamic language, the programmer can replace any undesirable element of the language—why not the type system?