Programming Languages: Chapter 7: Strong
Typing and Type Inference
- definitions vary
- a simple, but incomplete definition is:
``a strongly-typed programming language is one in which each name in a program
has a single type associated with it, and that type can be
determined at compile time'' [COPL6] (i.e., by looking at the program)
not running it;
this means that all types are bound at compile-time (i.e., statically
- another, perhaps more general and all inclusive, definition is:
a strongly-typed programming language is one in which ``type errors are always
detected'' [COPL9]; means we must be able to determine the type of everything
just by looking at the program, and not by running it
- FORTRAN, C, and C++ are not strongly typed
- languages with coercion (e.g., FORTRAN, C, and C++ are
- C and C++ use coercion, int x = 3.4;
- C and C++ support unions which are not type checked
- Ada is almost strongly-typed; the programmer can suspend type checking
- C# and Java (even though they are based on C/C++) are strongly typed
but have casting
- ML and Haskell are strongly-typed
- in safety, Haskell is the Java of functional programming languages
- why use a strongly-typed programming
language? reliability and safety
- why use a weakly-typed programming language? flexibility and efficiency
- LISP is said to be a typeless language
- ML comes with irremovable training wheels
3-4; (* works *)
(* 3-4.4; doesn't work *)
(* no coercion in ML, why? *)
real(3)-4.4; (* this is a type cast *)
Real.< (2.9, 3.0); (* Real is called a structure; open a class in OO *)
false andalso (1 / 0); (* doesn't work, why? *)
false andalso (1 div 0); (* still doesn't work, but not because of a divide by 0 *)
Type inference in Haskell
``In Haskell every expression must have a type, which is
calculated prior to evaluating the expression by a process
called type inference. The key to this process is a typing
rule for function application, which states that if f
is a function that maps arguments of type A to results of type
B, and e is an expression type A, then the
application f e has type B:
f :: A → B e :: A
f e :: B
For example, the typing not False :: Bool can be inferred from
this rule using the fact that not :: Bool → Bool
and False :: Bool'' [PIH].
key point: type inference gives us strong typing without explicit
for more information, see [EMLP] p. 63
Type inference in ML
How ML deduces types: examples
(* the 0 returned in the first case
causes ML to use the type
"int list -> int" for summing *)
fun summing (nil) = 0
| summing (x::xs) = x + summing (xs);
fun f1 (a, b) = if (a < b) then 3.0 else 2.0;
(* val f1 = fn : int * int -> real *)
fun f2 (a, b) = if (a < b) then 3.0 else 2;
stdIn:7.17-7.43 Error: types of if branches do not agree [literal]
then branch: real
else branch: int
if a < b then 3.0 else 2
fun f3 (a, b) = if (a + 0.0) < b then 1 else 2;
(* val f1 = fn : real * real -> int *)
See [EMLP] § 3.2.4 (pp. 63-64) for more information.
contrast square function in Haskell with that in ML
square n = n*n
Main> :type square
square :: Num a => a -> a
-- the type of square is a 'qualified type'
-- and Num is a 'type class'
Concepts of Programming Languages.
Addison-Wesley, Boston, MA, Sixth edition, 2003.
Concepts of Programming Languages.
Addison-Wesley, Boston, MA, Ninth edition, 2010.
Elements of ML Programming.
Prentice Hall, Upper Saddle River, NJ, Second edition, 1997.
Programming in Haskell.
Cambridge University Press, Cambridge, 2007.