Typed Language
A typed language is one that enforces rules about how values of different types (e.g. int
, string
, boolean
) can be used. There are two orthogonal axes to understand types in programming:
- Static vs Dynamic Typing: When type checking happens
- Strong vs Weak Typing: How strictly types are enforced
Static vs Dynamic
Static Typing
A statically typed language is a language where the type of a variable is known at compile time. Type checks happen before the program runs
-
Explicit static typing: For some languages, the type is specified by the programmer, and the compiler checks that the type is correct
- Example: Java, C, C++
-
Type Inference: For other languages, the type is inferred by the compiler
- Example: TypeScript, Kotlin, Haskell, OCaml
Dynamic Typing
A dynamically typed language is a language where the type of a variable is known at runtime. The type is associated with values, not named variable, and the type checks only happen when the code is executed
-
The interpreter infers the type of the variable from the value at runtime
- Example: Python, Ruby, JavaScript, PHP, Perl
Strong vs Weak
At its core, strong vs weak typing refers to how strictly a programming language distinguishes between different data types and how rigorously it enforces those distinctions during operations
A key factor in this classification is implicit type conversion (also known as type coercion) — that is, whether the language automatically converts values from one type to another when performing operations
However, it's important to note that this classification is not always clear-cut. The boundary between "strong" and "weak" typing is often subjective and varies across programming languages. What one language community considers "strongly typed" may be viewed differently in another context, leading to some debate and inconsistency in usage
Strong Typing
In a strongly typed language, the type system strictly enforces data type rules and prevents implicit operations on incompatible types. The language requires that values be used in ways consistent with their types, and attempts to perform invalid operations — such as adding a string to a number — result in explicit errors unless explicit type conversions are used
This means that:
- We cannot perform operations on mismatched types without explicitly converting them
- Type coercion is minimal or forbidden
- Prevents type errors like adding a number to a string without conversion
Python Example (Dynamic & Strong)
3 + "3" # ❌ TypeError: unsupported operand types
int("3") + 3 # ✅ Works – explicit type conversion
Java Example (Static & Strong)
int x = "5"; // ❌ Compile-time error
int x = Integer.parseInt("5"); // ✅ Works – explicit conversion
Weak Typing
In a weakly typed language, the type system loosely enforces data type constraints, often allowing implicit type conversions (type coercion). This means that operations between different data types — such as adding a number to a string — may be automatically handled by the language without raising an error, sometimes in unpredictable ways. As a result, programmers can more easily circumvent type restrictions, often without realizing it
This means that:
- The language tries to "guess" what the programmer meant
- Implicit coercion is common
- Type errors are often silent (or deferred until runtime)
PHP Example (Dynamic & Weak)
$result = "5" + 1; // 6 — coerces string to int
$result = "hello" + 1; // 1 — quietly coerces "hello" to 0