Tuesday, February 26, 2008

Static vs "dynamic typing" (part 1)

Yes, I admit, it's an old, often reiterated discussion - but nonetheless it's still a quite frequent topic. So I decided to write a bit about it - in fact it's not only a bit so I've split it into multiple parts. In this first part, I want to talk about some of the basics, in the next one or two I will discuss the various pros and cons.

Lets start by talking a bit about nomenclature.

First: The opposite of static typing is not dynamic typing! It's also neither weak typing nor latent typing. Many languages with static typing also have runtime type checking (For example Java). Static typing is an additional layer on top of an otherwise (strong, weak etc) typed language. Because of this the opposite to static typing is simply no static typing!

Second: The existence of static typing can have effects on the semantics of the language. While this is not true in typed lambda calculus (the common textbook stuff) certain existing languages mix the boundaries between typing and language semantics. A quite common example for this is static function overloading in languages like Java or C++ which can't be implemented with a dynamic typing alone (because it requires a "static type"). But there are also languages where static typing is an totally isolated layer which can be removed without changing the semantics of the language.

Third: Latent typing and static typing aren't mutually exclusive. "Latent" only means that we don't have to explicitly write out the types of variables etc. But this can also be archived by doing type inference in a static typed language. So "Latent typing" is in fact only the opposite of "nominal typing".

The above may sound a bit nitpicky - but it's so often mixed up in articles and discussion about the topic! I think its important to know the differences before we delve into details.

But what is "dynamic typing" now? It's simply "type checking at runtime". In other words: Object can have a "dynamic type" which allows to choose the right operation not only by the name of the operation but also by the types of the operand(s).

For example Java and Ruby are both dynamically typed languages. But Java has also static and nominal typing while Ruby has no static typing and is also latently typed. Both languages are also strongly typed.

Now certain languages are "dynamic beyond types". The notion "dynamic language" has been established for those languages in the last years. A dynamic languages simply allows the program to change itself. This can be self modifying assembler code, the dreaded "eval"-function or the addition or removal of fields and methods at runtime. Most languages are "dynamic" to a certain degree. So called "dynamic languages" languages (like Ruby for example) are simply much more dynamic compared to a less dynamic language (like Java for example). But it's a continuum, not a have or have-not. "Dynamic languages" don't even need to omit static typing, if they have a compiler which does type-checking after every code-modification (which is a bit hard to do, so it's rather uncommon). But I don't want to talk about the pros and cons of "dynamic languages" here, the term is just often used in discussions and I think it's important not to mix it up with the typing-topic. On a fundamental level the terms "dynamic language" and "dynamic typing" are even orthogonal concepts.

Now from the above it should be clear that non-statical-typing is not really a feature but in fact an omission of a feature. Dynamic typing in itself is a rather common feature: Every OOP-language requires a certain amount of dynamic typing (for the method dispatch).

So talking about "Static vs dynamic typing" is in fact nonsense (thats the reason I used the quotes in the title). The whole discussions is in really centered about the following question:

Is it a good idea to have a static type-system in a language or not?

But thats the topic of part 2.

1 comment:

Anonymous said...

I'll be even pickier than you are. Your use of "nominal" to refer explicit type annotations is potentially very confusing, since nominal types are used in a good bit of type theory work opposed to structural types, in defining subtype relations. A nominal type system is one where A is a subtype of B only if I say so; while a structural type system is one where A is a subtype of B if its exposed interface is compatible with B.

As far as words for the concepts you mention: I've heard "manifest" and "implicit", or I have heard "explicit" and "implicit".

Just a nit.