A type system is a set of rules defined by a programming language specification that assigns a type to every variable, expression, function, and possibly other things beyond those.
Why Type Systems Exist
Type systems exist for one reason: to help you write less buggy code in a more self-documenting way.
- Giving variables, values, functions, etc. a type restricts the set of things you can do with them which helps us by minimising the chance of creating situations where the program tries to add the integer
3to an instance ofC[]()at. - It forces users of an interface to always supply an expected value.
Static Typing
A statically typed language is one where the type system’s rules are checked when you run the compiler (ie. at compile-time). It’s called ‘static’ because any type system violations are caught before you execute a single line of your program.
- Languages like C and Java are statically typed. Every valid C or Java program will always know what type an expression, variable, function has before execution.
Dynamic Typing
A dynamically typed language is one where the type system’s rules are checked during the execution of the program rather than at compile-time. In other words, nothing has a type until you run the program, and only then do the types get assigned to expressions, variables, functions, etc.
- Python is a dynamically typed language. You could code up some very obvious type errors like
x = 1 + "hi"but the program will run fine until it actually executes that line. - There is an important trade-off to recognise between static typing and dynamic typing: you would get fewer run-time errors with static typing, however dynamic typing affords you far more flexibility, which generally helps you implement things faster (at least in the short-term).
Strong Typing
There’s a lack of a formal definition for this, but a strongly typed language is basically one where it is not possible for the developer to bypass the type system’s rules. In other words, a value’s type never changes in unexpected ways, such as through implicit casts.
- Python is a strongly typed language. It’s not possible to implicitly typecast values.
- Note: a language can be both strongly and dynamically typed.
x = 42 x = "Hello"
Weak Typing
Just like strong typing, there is a lack of a formal definition, but in general: weakly typed programming languages are ones that have a more relaxed enforcement of its type system’s rules, meaning that it’s possible to violate/bypass them.
- C is a classic weakly typed language. Pointers and integers are pretty much fully interchangeable, and you can freely convert a pointer of any type to a pointer of any other type.
“C is not a strongly-typed language, but as it has evolved, its type checking has been strengthened. ” - Dennis Ritchie.
- JavaScript is also a weakly typed language. It’s notorious for silently producing (sometimes hilariously) unintuitive results.
"11" + 1 === "111" "11" — 1 === 10 ('b' + 'a' + + 'a' + 'a').toLowerCase() === "banana" // See an explanation: https://stackoverflow.com/questions/57456188/why-is-the-result-of-ba-a-a-tolowercase-banana
Sometimes, we talk about the relative weakness of the type system between different programming languages. Eg. C++ is not strongly typed, however it is consider ‘stronger’ than C.
Note: people often confuse weak typing to mean dynamic typing, and strong typing with static typing. They’re completely separate. For example, C is both weakly typed and statically typed, while Python is both strongly typed and dynamically typed.