Version without JavaScript, read-only: workshops, quizzes and running code are not available here. Full version · Catalogue · Sign in
Lecture notes · chapter 5
Imperative features
Side effects, printing, the unit type, sequences and blocks.
Printing
Printing values
There are predefined functions (primitives) that print “simple” values on the screen. They differ according to the type of the value to print.
print_string "Bonjour" ;;The cell first shows the printed text, Bonjour, then, as always, the type and the value of the expression: - : unit = (). In the command-line ocaml interpreter, the two end up glued together on the same line, Bonjour- : unit = (), because print_string does not go to a new line.
What is its type?
print_string ;;There is one for each simple type:
print_char 'a' ;;
print_int 42 ;;And two for going to a new line: print_endline prints a string then goes to a new line, print_newline only goes to a new line.
print_endline "Bonjour" ;;
print_newline () ;;
print_newline ;;The notion of effect, the unit type
All these functions return a value of type unit. Why?
- In Caml, every function must return a value.
- But these functions have nothing to compute: their purpose is to act, here to display. We say that they work by effect (or side effect).
We then use “nothing”, that is (), as the result or argument. The unit type is a predefined type that contains a single value, (), which by convention means “nothing” (there is no interesting result).
() ;;print_newline needs no data: it takes () as its argument. Do not forget the parentheses: print_newline on its own is the function, not a call to it, and prints nothing.
Successive printing: the sequence
It is possible to perform several effects one after the other, in sequence. Evaluating two expressions $e_1$ and $e_2$ in sequence means evaluating them one after the other: $e_1$, then $e_2$. As in most languages, the sequence is written ;: we write e1 ; e2.
print_string "Bon" ; print_string "jour" ; print_newline () ;;The value of a sequence is that of its last expression. The values of the others are lost: they are only there for their effects.
print_int 1 ; 2 ;;If an expression other than the last one is not of type unit, its value is computed for nothing; Caml reports it:
1 ; 2 ;;In a function, the sequence lets us chain displays:
let affiche_somme a b =
print_int a ;
print_string " + " ;
print_int b ;
print_string " = " ;
print_int (a + b) ;
print_newline () ;;
affiche_somme 2 3 ;;Conditional and sequence
The conditional without else
let printEven n =
if n mod 2 = 0 then
print_int n ;;
printEven 4 ;;
printEven 3 ;;What do you make of it? In chapter 3, we said that the else branch was mandatory.
let f n = if n > 0 then 1 ;;Blocks
What happens if a branch of the conditional has to do several things?
let signe_faux n =
if n >= 0 then
print_string "positif" ;
print_newline () ;;
signe_faux (-2) ;;Despite the indentation, ; has lower precedence than the conditional: the function reads (if n >= 0 then print_string "positif") ; print_newline (). The new line happens in every case.
To group several expressions in a branch, we surround them with begin … end (or with parentheses):
let signe n =
if n >= 0 then begin
print_string "positif" ;
print_newline ()
end else begin
print_string "négatif" ;
print_newline ()
end ;;
signe (-2) ;;