Version without JavaScript, read-only: workshops, quizzes and running code are not available here. Full version · Catalogue · Sign in
Lecture notes · chapter 3
Functions
Defining and applying functions, with one or several parameters, and reading their type.
Functions with a single parameter
A word about a Caml program
What is a Caml program?
Defining a function
In mathematics: “Let successor be the function defined by $successeur(x) = x + 1$.”
In Caml:
let successor(x) = x + 1 ;;Caml answers that successor is a function (<fun>), of type int -> int: it takes an integer and returns an integer. We did not give it this type, it inferred it: x + 1 only makes sense if x is an integer.
Applying a function
successor(1) ;;The parentheses around the arguments, in the definition as well as in the application, are optional. So we will drop them:
let successor x = x + 1 ;;
successor 4 ;;successor -1 ;;
successor (-1) ;;Notation and convention
Function applications are implicitly parenthesised and take precedence over any other operation:
successor 2 * 3 ;;
successor (2 * 3) ;;The first line reads (successor 2) * 3.
Predefined functions
Caml has predefined functions:
- on floats:
sqrt,sin,exp…; - for conversion:
int_of_float,float_of_int,string_of_int…; - in modules, referred to by their name followed by a dot:
String.length,Char.code…
sqrt 2.0 ;;
int_of_float 3.7 ;;
string_of_int 42 ;;
String.uppercase_ascii "caml" ;;
Char.code 'a' ;;“Nested” function applications
Multiple definitions are possible:
let succ x = x + 1
and double x = 2 * x
and square x = x * x ;;We can also use the result of a function as the actual parameter of another (or the same) function. Note the parentheses:
double (square (succ 3)) ;;
let square_of_succ x = square (succ x) ;;
square_of_succ 3 ;;succ 3 is 4, its square 16, its double 32.
Functions and local definitions
Local definition of a function in an expression
Since a function is a value, nothing prevents us from defining a function locally, as we did with plain integers:
let pred x = x - 1 in pred 3 * pred 4 ;;Local definitions of values in function definitions
Let us define the function square_of_pred, which returns the square of the predecessor of a number (the function $x \longmapsto (x - 1)^2$). We locally define the predecessor of the argument, then square it:
let square_of_pred x =
let pred_x = x - 1 in
pred_x * pred_x ;;
square_of_pred 5 ;;The local name avoids computing x - 1 twice.
Local definition of a function in a global function definition
A function can also locally define another function:
let cube x =
let square y = y * y in
x * square x ;;
cube 3 ;;square only exists inside cube.
Using the same function several times
One benefit of local definitions is that a function already defined can be used several times in the same expression (which was not the case in the previous example):
let power4 x =
let square y = y * y in
square (square x) ;;
power4 3 ;;Mind the parentheses: square square x would apply square to two arguments, square and x, and Caml would refuse it.
Functions with several arguments
Functions with several arguments
Functions that have several arguments simply have several formal parameters in their definition:
let average a b = (a + b) / 2 ;;
average 10 20 ;;average2 (10, 20) ;;
average (10, 20) ;;The multi-parameter case
When functions have several arguments, you must supply all their arguments when applying them. Otherwise, the result is not an error, but a function waiting for the missing arguments:
average 10 ;;We will come back to this: it is an important property of Caml functions.
Here too, the parentheses around the arguments are not needed. However, as for applying a function to a single argument, they become necessary when one of the arguments is not an atomic expression!
average (succ 3) (double 5) ;;Mind the parentheses!
succ (succ 1) ;;
succ succ 1 ;;succ succ 1 reads (succ succ) 1: succ is applied to two arguments, succ then 1.