Programming Languages: Chapter 7: Strong
Typing and Type Inference
Strong typing
 definitions vary
 a simple, but incomplete definition is:
``a stronglytyped 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 compiletime (i.e., statically
bound)
 another, perhaps more general and all inclusive, definition is:
a stronglytyped 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
weakly typed)
 C and C++ use coercion, int x = 3.4;
 C and C++ support unions which are not type checked
 Ada is almost stronglytyped; 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 stronglytyped
 in safety, Haskell is the Java of functional programming languages
 why use a stronglytyped programming
language? reliability and safety
 why use a weaklytyped programming language? flexibility and efficiency
 LISP is said to be a typeless language
 ML comes with irremovable training wheels
34; (* works *)
(* 34.4; doesn't work *)
(* no coercion in ML, why? *)
real(3)4.4; (* this is a type cast *)
open Real;
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].
Type inference in ML
key point: type inference gives us strong typing without explicit
type declarations
for more information, see [EMLP] p. 63
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.177.43 Error: types of if branches do not agree [literal]
then branch: real
else branch: int
in expression:
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. 6364) for more information.
Overloading
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'
References
[COPL6] 
R.W. Sebesta.
Concepts of Programming Languages.
AddisonWesley, Boston, MA, Sixth edition, 2003. 
[COPL9] 
R.W. Sebesta.
Concepts of Programming Languages.
AddisonWesley, Boston, MA, Ninth edition, 2010. 
[EMLP] 
J.D. Ullman.
Elements of ML Programming.
Prentice Hall, Upper Saddle River, NJ, Second edition, 1997. 
[PIH] 
G. Hutton.
Programming in Haskell.
Cambridge University Press, Cambridge, 2007.

