Type checking

Type checking #

Statically vs dynamically typed languages #

A compiled programming language is said to be statically typed if (most) type checks are performed during the compilation of a program, rather than during its execution.

Such languages include , C/C++, C#, Go, Java, Kotlin, Typescript, Rust, etc., as well as functional (or functional-like) languages like Haskell or Scala.

Example. The following Java program does not compile.

String banana = "banana";
banana += 1;

Languages that are not statically typed are called dynamically typed.

This include interpreted (or just-in-time compiled) languages like Javascript, Lua, PHP or Ruby, but also Python (which is precompiled, like Java).

Dynamically typed languages have limited (if any) syntactic support for types (like int or Set<String> in Java), whereas statically-typed languages (especially functional languages) can have complex typing systems.

Static and dynamic typing have their respective benefits and drawbacks (each being more adapted to certain use cases). Here are some of some common arguments:

  • Robustness: static typing allows some errors to be identified earlier during the development process. In a dynamic context, type-related bugs can only be identified via testing (possibly after release).

  • Documentation: the signature of a method (i.e. its input and return types) can be a useful indication of how it is meant to be used.

  • Productivity: dynamically typed languages allow focusing on algorithmic aspects, without the need to write or reason about types. As a result, programs may be written significantly faster. Conversely, the absence of compile-time type checks may increase debugging time.

  • Conciseness: an algorithm can be significantly easier to understand without the overhead introduced by a (possibly complex) typing system.

Type safety and generic programming #

Type safety is the extent to which a typing system prevents or discourages type errors. This is usually understood as a property of statically typed languages.

Type safety often conflicts with reusing and factorizing code, in particular for algorithms that manipulate data structures. This is one of the main practical motivations behind generic programming, which allows maintaining type safety (to some extent) while abstracting from specific data types.

For instance, with generic programming, a sorting algorithm (like Mergesort) can be implemented only once for different types of arrays (Integer[], City[], Unit[], etc.) and sorting criteria, while preventing some typing errors.