411 REFERENCE · Wikibooks
Introduction to Programming Languages/Type Annotations
Reference material by Wikibooks contributors. This retains its source identity and is not 411 news reporting.
Type Annotations
Many programming languages allow or require explicit type declarations for variables, function parameters, and return values. These annotations:
Provide static type information to the compiler
Serve as documentation for human readers
Make programs more readable and maintainable
SML Example
fun sum (x: int, y: int) : int = x + y
val a: int = 10
val b: real = 3.14
Java Example
int sum(int a, int b) {
return a + b;
}
int x = 10;
double y = 3.14;Type annotations increase compile-time safety, reduce errors, and serve as self-documentation.
Intrinsic Types
Intrinsic types are deduced automatically from the value or naming convention, without explicit annotations.
SML (Standard ML)
val x = 10 (* inferred as int *)
val y = 3.14 (* inferred as real *)
val z = "hello" (* inferred as string *)Note: no need to declare int or string; the compiler deduces the type automatically.
Java
Since Java 10, var allows the compiler to infer the variable type:var z = 42; // inferred as int
var pi = 3.14; // inferred as double
var name = "Alice"; // inferred as StringThis is a modern form of intrinsic type, where the type is deduced from the assigned value.
Prolog
Prolog is dynamically typed, but the type of a term is intrinsic to the value:X = 10. % number
Y = 'hello'. % atom (symbol)
Z = [1,2,3]. % listNo type declaration is required; the interpreter deduces the category of the term.
Python
Python is dynamically typed, but types are also intrinsic to the valuex = 10 # x is an int
y = 3.14 # y is a float
name = "Alice" # name is a strUnlike SML, Python does not perform static type inference, but the value itself carries the type intrinsically.
Simple Type Inference
Even languages that require some type annotations can infer types for constants and expressions.
Java
int a = 10; // 10 is int
long b = 10L; // 10L is long
double c = a * 0.0; // inferred as double
C
#define PI 3.14
double area = PI * 10 * 10; // 3.14 inferred as doubleThe compiler deduces expression types from literals and operators.
Extreme Type Inference
Some languages, like SML, ML, and Haskell, perform full type inference:
Types for all expressions and functions are deduced automatically
Usually no annotations required
Type safety is guaranteed at compile-time
SML / ML Example
fun square x = x * x (* inferred: int -> int *)
fun identity x = x (* inferred: 'a -> 'a *)
Java (limited)
var x = 10; // inferred as int
var y = 3.14; // inferred as double
public static <T> T identity(T value) {
return value;
}
int a = identity(42); // T inferred as Integer
String s = identity("hello"); // T inferred as String
Python (dynamic)
def identity(x):
return x
a = identity(42) # a is int
b = identity("hello") # b is strExtreme type inference reduces boilerplate, increases abstraction, and supports polymorphic code, while relying on strong static type systems in languages like SML.
Type Comparison Across Languages
ConceptSML / MLJavaPythonPrologType Annotationsval x: int = 10int x = 10;optionalnot applicableIntrinsic / inferred typeval x = 10var x = 42x = 10X = 10.Simple Type Inferenceinferred for constsinferred in exprsn/an/aExtreme Type Inferencefun identity x = xvar, genericsdynamicdynamic