Typing

Typing #

A typing system restricts the values that can be used in certain contexts.

Example. In Java, the following instruction is incorrect, because the variable x has type int, whereas the value "Hi" is a string.

int x = "Hi";

This line of code would generate a compile-time error.

Terminology. In this example, int is called a type annotation.

Static vs dynamic typing #

Static typing #

Definition. A programming language is statically typed if type checks are performed at compile time.

A statically typed language often lets programmers write type annotations (and sometimes requires them to), like in Java.

Languages. Statically typed languages include:

  • C/C++,
  • C#,
  • Go,
  • Haskell,
  • Java/Kotlin/Scala,
  • Rust,
  • Typescript.

Benefits.

  • A type mismatch usually results in a compile time error, as opposed to a bug.
  • Type annotations can improve readability (they document the code).
  • Expressive types enable more advanced tooling (analysis, refactoring, autocompletion, …).
  • Compilers can generate more optimized code when types are fixed.

In practice. An expressive type system often means:

  • more time spent writing code,
  • less time spent debugging it.

Illustration. The catchphrase “if it compiles, it is correct” (or “if it compiles, it works”) is often used for languages with expressive type systems, in particular:

  • functional languages (like Haskell or OCaml),
  • Rust (more recently).

This is (obviously) an overstatement.

Drawbacks.

  • Type annotations means boilerplate code.
  • Writing type annotations can be tedious (interferes with problem solving/algorithmic thinking).
  • In order to produce generic code, an advanced typing system is required.

Example. One may want to implement a generic algorithm that sorts an array.

The same implementation should work for:

  • an array of integers,
  • an array of strings,
  • etc.

This may require a generic type, intuitively “array of $X$”, where $X$ is a type variable.

Type inference #

Some statistically typed languages provide automatic type inference (at compile time). This allows programmers to omit some type annotations.

Example. In Java (since 2018), the keyword var can sometimes be used in place of a type annotation, e.g.:

var name = "Alice";

In this example, the compiler can infer that the variable name has type String.

Some languages (more specifically the compilers for these languages) are known for their type inference capabilities. These include:

  • Haskell,
  • Kotlin (which significantly improves Java’s type inference).

Dynamic typing #

Definition. A programming language is dynamically typed if type checks are performed at run time.

Languages. Dynamically typed languages include:

  • Lua,
  • JavaScript,
  • PHP,
  • Python,
  • Ruby.

The benefits and drawbacks are symmetric to the ones listed above for statically typed languages.

Applications. Dynamically typed languages are often preferred for:

  • smaller projects,
  • rapid prototyping/experimentation,
  • manipulating objects with flexible structures,
  • scripting.

Illustration. JavaScript was originally designed for small programs.
When it started powering more complex ones (including some backends), developers faced the limitations of dynamic typing:

  • bugs,
  • difficult refactoring,
  • limited tooling,
  • etc.

TypeScript (2012) was developed to address these issues. It extends JavaScript with static typing.