Type Checking and Conversion


This post covers facets of the larger topic of type systems — specifically, the concepts of Static and Dynamic typing and also of Strongly and Weakly typed languages. I start with Static and Dynamic typing, defining each and comparing the two with each other. I then do the same with Strongly and Weakly typed languages. Finally, I compare and combine the larger categories and explain what results.

The first and biggest point that almost every discussion of Static/Dynamic typing and Strongly/Weakly typed languages is that they are not the same thing.

The next big point is that one should be cautious to use the terms Strongly and Weakly typed languages, since they don’t have a universally agreed upon technical meaning. Despite this shortcoming, understanding these concepts can be useful in a relative manner for understanding languages.

Static and Dynamic typing, however, have a much more agreed upon definition. They describe when object type information (e.g., string, integer, boolean, etc.) is acquired — either at compile time or at runtime.

To contrast, Strongly and Weakly typed languages describe how strictly types are distinguished from each other (e.g. whether the language tries to do implicit conversion from strings to numbers).

Static vs. Dynamic Typing

As stated above, static and dynamic typing describe when type information is acquired. Static typing checks types at compile time, while dynamic typing checks types at runtime.

Static Typing

To put it concisely, object type is acquired at compile time. Because of this, once you set a variable to a type, you cannot change it — i.e., the type is static. If you try to change a variable’s type (e.g., from a string to an integer), the program will refuse to compile, even if the program would have never even used the variable. Thus, you CANNOT declare x to be an integer and, a few lines later, redeclare it to be a string.

Example of a statically typed language (Java):

int x;
x = 3;
x = "Hello World";
=> this will produce a compiler error because the type cannot be changed from integer to string.

Example where the type conversion is never encountered (Java):

int x = 2;
if (x > 1) {
System.out.println("Hello World");
} else {
x = true;
=> this will still produce a compiler error even though the erroneous line of code is never run.

Dynamic Typing

Dynamic typing, by contrast, acquires type at runtime. Thus, the variable’s type can change (e.g., from a string to an integer) and be resolved at the moment it gets parsed by the interpreter.

Example of dynamically typed language (Ruby):

x = 2
x = []
x = {one: 1, two: "shoe", three: [6, 9]}
x = true
x = "hi"
puts x
=> "hi"

In this example, even though the variable type for x changed repeatedly, no compile error occurred because type is checked at runtime — i.e., when the variable is finally called.

Yet although type can change, poorly typed operations might still cause the program to raise an exception. Take the following for example:

x = 2
puts x + "hi"

=> TypeError: no implicit conversion of Fixnum into String

However, this exception is not the focus of static/dynamic typing, but of strongly/weakly typed languages. Which leads to a discussion about…

Strongly vs. Weakly Typed Languages

As mentioned above, the distinction between strongly and weakly typed languages is not so well defined. Yet even if the distinction is not clear, there is an underlying topic that is worth discussing. In addition, it may contribute to a better understanding of static and dynamic typing.

As a brief introduction, strongly typed languages do not implicitly convert type at runtime (e.g., they will raise an exception rather than convert an integer to a string when there is a type mismatch). A weakly typed language will make this type conversion; however, it may produce unpredictable results.

Strongly Typed Languages

Once the language knows the type of an object, it expects you to do something that makes sense with it. If you start mixing several different types together in an expression, a strongly typed language won’t understand what it means.

Example that works:

x = "7"
y = x + “eleven”
puts y
=> “7eleven” 
// both are type String, so combining them is no problem.

Example that doesn’t work:

x = "7"
y = x + 11
puts y
=> TypeError: no implicit conversion of Fixnum into String

Weakly Typed Languages

By contrast, a weakly typed language lets you mix types together in your expressions without throwing an exception at runtime. This can lead to unpredictable results (JavaScript):

x = '3';
y = 5 + x;
=> '53' 
// this is because 5 is converted into a string and then concatinated with '3'

The Distinction

So why is there no universally agreed upon technical meanings for strongly and weakly typed languages? The difference between the two appears clear-cut. Well, the problem comes with treating these terms as categories and trying to fit programming languages into one or the other.

Does a language that raises an error on most mismatched types fit into the strongly typed category? Or is it considered weakly typed since it allows some implicit type conversion? Or does it fit into neither since it is, strictly speaking, neither?

Even though I label these as categories, I think most people consider them different ends of a spectrum. Thus, the concepts help us classify one language relative to other languages. Though, doing so is still muddy, and somewhat less informative than taking the categorical approach.

Static/Dynamic + Weakly/Strongly typed languages

Setting aside the hangup with distinguishing strongly and weakly typed languages, let’s try to figure out what it means for a language to have static or dynamic typing AND be strongly or weakly typed.

Static Typing + Strongly Typed Language: This is a language that checks type at compile time (not runtime), and will raise an exception if different types are mixed together.

Static Typing + Weakly Typed Language: This is a language that checks type at compile time (not runtime), and will not raise an exception if different types are mixed together. (very rare)

Dynamic Typing + Strongly Typed Language: This is a language that checks type at runtime (not compile time), and will raise an exception if different types are mixed together.

Dynamic Typing + Weakly Typed Language: This is a language that checks type at runtime (not compile time), and will not raise an exception if different types are mixed together.


Static/Dynamic typing → Describe when variable types are acquired.
Strongly/Weakly typed languages → Describe whether differently typed variables can be mixed and matched.
Static typing → Types are checked at compile time (cannot change type)
Dynamic typing → Types are checked at runtime (can change type)
Strongly typed languages → No implicit type conversion
Weakly typed languages → Implicit type conversion

Sources & Further Reading

  1. Lamontagne, F., “Ruby is dynamically AND strongly typed”, http://www.rubyfleebie.com/ruby-is-dynamically-and-strongly-typed/ (July 2007)
  2. “Wikipedia: Type Safety”, https://en.wikipedia.org/wiki/Type_safety
  3. “Wikipedia: Strong and Weak Typing”, https://en.wikipedia.org/wiki/Strong_and_weak_typing
  4. “StackOverflow: Static/Dynamic vs. Strong/Weak”, http://stackoverflow.com/questions/2351190/static-dynamic-vs-strong-weak
  5. “StackOverflow: What is the difference between statically typed and dynamically typed languages?”, http://stackoverflow.com/questions/1517582/what-is-the-difference-between-statically-typed-and-dynamically-typed-languages
  6. “Stack Overflow: Is there a statically weak typed language?” http://stackoverflow.com/questions/14046246/is-there-a-statically-weak-typed-language