Download as doc, pdf, or txt
Download as doc, pdf, or txt
You are on page 1of 21

A Concise Introduction to Objective Caml General

Caml is a dialect of ML, developed primarily in France. This paper describes Objective Caml version .!", or OCaml #pronounced $oh%camel$& for short' it does not (o into the object% oriented features of OCaml, ho)ever. Another dialect, Caml Lite !.*+, has almost identical synta,, but the modules and many of the functions in the modules differ to a (reater or lesser e,tent. OCaml is case%sensitive. OCaml is interactive' you start it up, then you type e,pressions #at the prompt& to be evaluated. OCaml responds )ith both the value and the type of the result. -,ample.
# 3 * 4;; - : int = 12

-very e,pression ends )ith )ith two semicolons. The # si(n is OCaml/s usual input prompt. In this paper, I typically include the prompt in one%line e,amples, and leave it off lon(er e,amples that are best loaded from a file. 0imilarly, I use boldface to indicate user input that is typed in at a prompt. To define a constant, use the form.
let pi = 3.1416;;

Most values in OCaml are immutable #constants&. 1o)ever, arrays and strin(s can be altered in place. OCaml is an expression-oriented lan(ua(e, not a statement%oriented lan(ua(e. That is, everythin( in it is considered to be an e,pression and to have a value. A fe) e,pressions that are e,ecuted for their side effects rather than their value #mostly output e,pressions& return the unit, (), as their value%%this is li2e void in C or 3ava. To define a function, use one of the forms.
let sum (x, y) = x + y;; let add x y = x + y;;

For reasons )hich )ill be e,plained later, if you use parentheses around the ar(uments in the definition, you must use parentheses in the function call. If you omit parentheses in the function definition, you must omit them in the function call. 1ence.
# # sum 3 5;; : int = 8 add (3, 5);; : int = 8

OCaml is stron(ly typed' ho)ever, OCaml almost al)ays fi(ures out the types for itself. If you need to help it alon(, you can specify the type of any identifier by follo)in( it by a colon and the name of the type, enclosed in parentheses, any)here the identifier occurs #not just in the parameter list&. For e,ample, in the function
let max (x, y) = if x > y then x else y;;

the variables x and y could be int, float, char, or strin(. To define this function to use only char values, (ive OCaml a hint by attachin( :char to any one of the variables, anyplace in the function. For e,ample, you could say
let max (x: ha!) (y) = if x > y then x else y;;

o let max (x) (y: ha!) = if x > y then x else y;; r o let max (x) (y) = if x > y then (x: ha!) else y;; r or any of several other possibilities. To e,ecute the e,pressions in file myFile.sml #usually definitions that you are testin(&, use
use "my#ile.sml";;

4redefined OCaml functions are in (roups called modules, often or(ani5ed around some particular data type. A module is li2e a function library. The collection of these modules is called the common basis. The most common functions are in the $Pervasives module,$ )hich means you don/t have to do anythin( special to use them. For less commonly used functions, you have to either prefi, the function name )ith the name of the module, or you have to $open$ the module. Openin( the module means ma2in( the contents visible to the pro(ram. For e,ample, the follo)in( se6uence sho)s that the function length is not defined for strin(s until the open tring command is issued.
# len$th "hell%";; !haracters "-#: $n%o&nd val&e length # %pen &t!in$;; # len$th "hell%";; - : int = '

7ote. Caml Li(ht uses a sli(htly different synta,%% #open (string()) %% )here the # is typed by the user. The functions provided by each module are also different, often only in havin( a different name. Finally, comments are indicated as.
(* +his is a comment (* and comments may %e nested. *) *)

Identifiers
Identifiers must be(in )ith a lowercase letter or underscore, and may contain letters, di(its, underscores, and sin(le 6uotes. Most implementations also reco(ni5e accented characters, such as 8. Alphanumeric identifiers be(innin( )ith a , #sin(le 6uote& are used only for type identifiers. Often OCaml )ill use ,a to indicate a variable #un2no)n or arbitrary& type. For e,ample, ,a list means a list )hose elements are of type ,a. Additional variable types are indicated by ,%, ,c, and so on. The variable - #an underscore all by itself& is used as a $)ildcard$ or $don/t care$ variable, for e,ample,
let second (-. x) = x))

Types
There are several primitive types in OCaml' the follo)in( table (ives the most important ones.

Primitive type

Examples

Notes
-

is used for unary minus' there is no unary 9

int

". '. /2. -10. "x or "1 starts a he,adecimal number' "o or "2 "x""FF. "o00. "%11"1 starts an octal number' and "% or "3 starts a binary

number
4loat ".". -'.5. 1.0e1/. 1.0e61/. 1e-1" tr&e. 4alse

Can/t start )ith a decimal point These are the only bool values.
(7n( (7t( (77(

%ool

string

((. (2ne7n+8o(

is ne)line, is tab, is bac2slash

char &nit

,a,. ,7n, ()

0in(le 6uotes for chars, double 6uotes for strin(s. This is a value. It is the only value of its type, and is

often used )hen the value isn/t important #much li2e void in C&. There are three families of constructed types in OCaml. lists, tuples, and functions. Lists are enclosed in brac2ets and the list elements are separated by semicolons. All elements in a list must be of the same type. Tuples are usually enclosed in parentheses, and the elements are separated by commas. The elements of a tuple may be of different types. Functions are first-class objects. they can be created, manipulated, passed as parameters, and other)ise treated li2e other 2inds of values. #1o)ever, )hen OCaml prints the result of an e,pression, and that result is a function, OCaml doesn/t print out the entire function' it just prints the )ord fn.& -very function ta2es e,actly one parameter as input and returns one value as its result' ho)ever, that parameter and that result may each be of a constructed type, such as a tuple. The follo)in( table (ives a fe) e,amples of constructed types. Pay special attention to the second column, )hich sho)s ho) OCaml e,presses type information.

Example expression

Expression type

Notes Lists may be of any len(th, but all elements must be of the same type. The empty list can be represented by 9:. The type of this list is allo)ed to be un2no)n. The type of a tuple depends on its len(th and the types in each position. Tuples can contain lists, and vice versa. A tuple )ith one element is the same as that one element. All functions ta2e e,actly one parameter, and parentheses are optional. In this e,ample the one parameter is a tuple.

92) 5) ') 0:

int list

9:

,a list

('. (hello(. ;1#)

int * string * int

((a%c(. 91) 2) 5:)

string * int list

(5.')

4loat

let do&%le x = 2." *. x))

4loat -< 4loat

let s&m (x. y) = x 6 int * int -< int

y)) let hi () = print-string (hello7n())

&nit -< &nit

In this e,ample the one parameter is the $unit,$ and so is the result.

(do&%le. 9s&m:)

(4loat -< 4loat) * (int * int -< int) list

Functions are values, and can be put into lists and tuples.

Built In Functions
This section lists the most (enerally useful of the built%in functions' it is not a complete listin(. 0ee the appropriate reference manual for additional functions. An operator is just a function )ith a special synta,. 0ynta, that is added just for the sa2e of convenience, and not for any technical reasons, is called syntactic sugar. In OCaml, operators can be $de%su(ared$ by enclosin( them in parentheses, for e,ample.
# (+) 3 5;; - : int = 8

This also provides a handy )ay to pee2 at the type of an operator.


# (+);; - : int -< int -< int = =4&n<

!tandard "ool operators#

Function
not : %ool -< %ool

Examples
not tr&e. not (i = >)

Notes #4refi,& :nary ne(ation. #Infi,, left associative& Conjunction, )ith short% circuit evaluation. #Infi,, left associative& ;isjunction, )ith short% circuit evaluation.

?? : %ool * %ool -< %ool

(i = >) ?? (> = @)

AA : %ool * %ool -< %ool

(i = >) AA (> = @)

!tandard arithmetic operators on inte$ers#

Function
- : int -< int

Examples
-'. -limit

Notes #4refi,& :nary ne(ation. #Infi,, left associative& Multiplication' operands and result are all ints. #Infi,, left associative& ;ivision' truncates fractional part. #Infi,, left associative& Modulus' result has si(n of first operand. #Infi,, left associative& Addition.

* : int * int -< int

2 * limit

B : int * int -< int

0 B 5. score B average

mod : int * int -< int

limit mod 2

6 : int * int -< int - : int * int -< int a%s : int -< int

2 6 2. limit 6 1

2 - 2. limit - 1 a%s (-')

#Infi,, left associative& 0ubtraction. #4refi,& Absolute value.

!tandard arithmetic operators on real num"ers#

Function
** : 4loat *. 4loat -< 4loat sCrt : 4loat -< 4loat

Examples
1'.' ** 2." sCrt 8."

Notes #Infi,, ri(ht associative& -,ponentiation. #4refi,& 06uare root. #4refi,& :nary ne(ation. #Infi,, left associative& Multiplication' operands and result are all real numbers. #Infi,, left associative& ;ivision of real

-. : 4loat -< 4loat

-1e1". -average

*. : 4loat *. 4loat -< 4loat

5.1/1# *. r *. r

B. : 4loat * 4loat -< 4loat

0." B. 5.'. score B.

average

numbers. #Infi,, left associative& Addition of real numbers. #Infi,, left associative& 0ubtraction of real numbers. #Infi,, ri(ht associative& -,ponentiation. 06uare root. <ound up to nearest inte(er #but result is still a real number&. <ound do)n to nearest inte(er #but result is still a real number&. The usual transcendental functions.

6. : 4loat * 4loat -< 4loat

score 6. 1."

-. : 4loat * 4loat -< 4loat ** : 4loat *. 4loat -< 4loat sCrt : 4loat -< 4loat ceil : 4loat -< 4loat

score -. 1."

1'.' ** 2." sCrt 8." ceil D.'

4loor : 4loat -< 4loat

4loor D.'

exp. log. log1". cos. sin. tan. acos. ... : 4loat -< exp 1"." 4loat

%oercions

Function
4loat : int -< 4loat

Examples
4loat '. 4loat (')

Notes Convert inte(er to real. Fractional part is discarded. A0CII value of character. Character correspondin( to A0CII value' ar(ument must be in ran(e !..=>>. Convert strin( to inte(er.

tr&ncate : 4loat -< int

tr&ncate average

int-o4-char : char -< int

int-o4-char ,a,

char-o4-int: int -< char

char-o4-int D0

int-o4-string : string -< int

int-o4-string ('/(

string-o4-int : int -< string

string-o4-int '/

Convert inte(er to strin(. Convert strin( to float. Convert float to strin(. Convert strin( to bool. Convert bool to strin(.

4loat-o4-string : string -< 4loat-o4-string 4loat (5.08( string-o4-4loat : 4loat -< string %ool-o4-string : string -< %ool string-o4-%ool : %ool -< string string-o4-4loat 5.08 %ool-o4-string (tr&e( string-o4-%ool tr&e

%omparisons

Function

Examples

Notes Less than. a, can be int. 4loat. char. or string. Less than or e6ual to. a, can be int. 4loat. char. or string. -6uals. a, can be int. char. or string. but not 4loat. 7ot e6ual. a, can be int. char. or string. but not 4loat. ?reater than or e6ual to. a, can be int. 4loat. char. or string. ?reater than. a, can be int. 4loat. char. or string. 4hysical e6uality' meanin( is some)hat implementation%dependent. 4hysical ine6uality' meanin( is some)hat implementation%dependent. <eturns the lar(er of the t)o ar(uments.

= : ,a * ,a -< %ool

i = "

== : ,a * ,a -< %ool

x == "."

= : ,a * ,a -< %ool

s = (a%c(

=< : ,a * ,a -< %ool

ch =< ,7n,

<= : ,a * ,a -< %ool

i <= >

< : ,a * ,a -< %ool

x < y

== : ,a -< ,a -< %ool x == y

E= : ,a -< ,a -< %ool x E= y max : ,a -< ,a -< ,a max ,a, ,v,.

max " n min : ,a -< ,a -< ,a min ch1 ch2

<eturns the smaller of the t)o ar(uments.

&perations with strin$s


The operators = == = E= <= < can be applied to strin(s for le,ical comparisons. Many of the follo)in( operations can be used only by openin( the tring module or prefi,in( the name of the operation )ith tring #e.(. tring.length (hello(&.

Function
F : string * string -< string

Examples

Notes Infi, concatenation of t)o strin(s. Concatenates the strin(s of the list )ith the first ar(ument inserted bet)een each pair. 7umber of characters in strin(. <eturn a (iven character of the strin(, countin( from !. Modifies the ori(inal strin( by chan(in( the character at the (iven location. <eturns the position of the first occurrence of the char in the strin(. <eturns the position of the last occurrence of the char in the strin(. Tests )hether the char occurs in the strin(. <eturns a substrin( of len(th n startin( at position p. <eturns a strin( consistin( of n copies of character c.

(Gello. ( F name

tring.concat : string -< string list -< string

tring.concat ( and ( 9(a%() (c() (de(:

tring.length : string -< int tring.get : string -< int -< char tring.set : string -< int -< char -< &nit

tring.length (hello(

tring.get (hello( "

tring.set name / ,s,

tring.index : string -< char -< int

tring.index (radar( ,a,

tring.rindex : string -< char -< int tring.contains : string -< char -< %ool tring.s&% : string -< int -< int -< string tring.ma@e : int -< char -< string

tring.rindex (radar( ,a, tring.contains (radar( ,a, tring.s&% (a%cde4g( p

tring.ma@e n c

tring.&ppercase : string -< string

tring.&ppercase (2!aml(

<eturns a copy of the strin( )ith all letters translated to uppercase. <eturns a copy of the strin( )ith all letters translated to lo)ercase. <eturns a copy of the strin( )ith the first character translated to uppercase. <eturns a copy of the strin( )ith the first character translated to lo)ercase.

tring.lo8ercase : string -< string

tring.lo8ercase (2!aml(

tring.capitaliHe : string -< string

tring.capitaliHe (2!aml(

tring.&ncapitaliHe : string -< string

tring.&ncapitaliHe (2!aml(

0pecial syntactic su(ar for accessin( characters of a strin(.


s.9i: s.9i: =- c

<eturns the ith character of strin( s. 0ets the ith character of strin( s to c.

&perations on characters
The operators =
== = E= <= <

can be applied to characters.

The follo)in( functions are in the !har structure. To use these functions )ithout typin( !har. each time, enter %pen 'ha!;;.

Function
!har.&ppercase : char -< char

Notes ?iven a lo)ercase letter, returns the correspondin( capital letter. ?iven any other character, returns that same character. ?iven a capital letter, returns the correspondin( lo)ercase letter. ?iven any other character, returns that same character. <eturns a strin( consistin( of the sin(le character. The name refers to the fact that the character may be escaped #6uoted&.

!har.lo8ercase : char -< char !har.escaped : char -< string

&perations on lists

A list is a set of elements, all of the same type, enclosed in brac2ets and separated by semicolons. -,ample. 9(hello() (%on>o&r() (g&ten +ag(:. The type of this e,ample is string list. The empty list is represented by 9:. Only the :: operator #LI04 cons& and I operator #list concatenation& can be used )ithout openin( the Jist module or prefi,in( the function name )ith Jist. .

Function

Examples

Notes Add an element to the front of the list. This operator is ri(ht associative. List concatenation. 7umber of elements in the list The $head$ of a list is its first element. 0ame as car in LI04. The $tail$ of a list is the list )ith its first element removed. 0ame as cdr in LI04. <eturns the nth element of a list, countin( from 5ero. <everse the list.

:: : ,a -< ,a list -< ' :: 9#) 0: ,a list I : ,a list -< ,a list -< ,a list 9': I 9#) 0:

Jist.length : ,a list Jist.length 9') -< int #) 0:

Jist.hd : ,a list -< ,a

Jist.hd 95) ') 0:

Jist.tl : ,a list -< ,a list

Jist.tl 95) ') 0:

Jist.nth : ,a list -< Jist.nth 95) ') int -< ,a 0: 2

Jist.rev : ,a list -< Jist.rev 91) 2) ,a list 5:

&perations on tuples
<emember that a tuple consists of 5ero or more values, separated by commas and enclosed in parentheses. The parentheses can usually #but not al)ays& be omitted. If + is a pair #a tuple of t)o elements&, then 4st(+) is the first element and snd(+) is the second element. 0tandard ML defines additional operations on tuples, but OCaml does not. The type of a tuple describes the number and type of each element in the tuple. For e,ample,
# ("(%hn ). &tudent", *+, ,-,);; - : string * int * char = (Kohn L. t&dent(. D0. ,M,

0ometimes you may )ant a function to return more than one value. That isn/t possible, but the ne,t best thin( is to return a tuple of values.
# let di.ide x y = x / y, x m%d y;; val divide : int -< int -< int * int = =4&n< # di.ide 01 3;; - : int * int = #. 2

@ou can easily define functions to )or2 )ith tuples, by usin( patterns. For e,ample.
# let thi!d2%f2f%u! (2, 2, x, 2) = x;; val third-o4-4o&r : ,a * ,% * ,c * ,d -< ,c = =4&n< # thi!d2%f2f%u! (,a,, ,3,, , ,, ,d,);; - : char = ,c,

Functions with side effects


The most useful functions )ith side effects are the IAO functions. 0ince OCaml automatically prints the values of e,pressions entered at the prompt, you can often avoid doin( any e,plicit IAO.

Function
print-char : char -< &nit

Examples
print-char ,a,

Notes 4rints one character 4rints an inte(er. 4rints a real number. 4rints a strin(. 4rints a strin( follo)ed by a ne)line. 4rints a strin( follo)ed by a ne)line, then flushes the buffer.

print-int : int -< &nit print-int (x 6 1) print-4loat : 4loat -< &nit print-string : string -< &nit print-endline : string -< &nit print-4loat '.5 print-string mystring print-endline (Gello(

print-ne8line : &nit -< print-ne8line &nit (Gello(

The printin( functions all return the unit, (), )hich is OCaml/s )ay of sayin( that nothin( important is returned. Examples
read-line ()

Function
read-line : &nit -< string

Notes <eads a strin( from standard input. <eads an inte(er from standard input.

read-int : &nit -< int

read-int ()

read-4loat : &nit -< 4loat

read-4loat ()

<eads a real number from standard input.

Expressions '"ut not statements(


OCaml is a purely functional lan(ua(e. everythin( is built from functions. Functions return values. 0tatements don/t return values, they have side effects. There are no statements in OCaml. Thin(s in OCaml that loo2 li2e statements are actually e,pressions, and return values. The state of a pro(ram is the collection of values in the environment. 0tatements, especially assi(nment statements, have side effects%%that is, they chan(e the state of a pro(ram by alterin( values in the environment. To understand )hat a pro(ram is doin(, you have to 2no) the state of the pro(ram. 0ince states can be very lar(e, understandin( a pro(ram can be difficult. OCaml claims to be stateless. That is, you don/t need to 2no) about any environmental variables in order to understand a pro(ram. -verythin( you need is either in the function parameters or in the e,ecution stac2 #the set of function calls that (ot you to this point&. In theory, this should ma2e an OCaml pro(ram easier to understand than a pro(ram in a nonfunctional lan(ua(e. There is actually some truth in this point of vie). Because you can open structures and define and redefine values and functions at the prompt, the ar(ument that OCaml is stateless is a little difficult to justify. 1o)ever, if all your functions are defined in a file, and you just read in that file and use the functions, the stateless nature of OCaml is more obvious.

)atch expressions
The match expression loo2s li2e this.
match <expression> 8ith <match>

)here a <match> has the form.


<pattern1> -< <expression1> A <pattern2> -< <expression2> A . . . <patternN> -< <expressionN>

First, the initial <expression> is evaluated, then its value is compared a(ainst each of the <patterns>. Chen a matchin( <patterni> is found, the correspondin( <expressioni> is evaluated and becomes the value of the case e,pression. The most common patterns are

a variable #matches anythin(&, a tuple, such as (x. y), a literal #constant& value, such as ' or (a%c(, an e,pression x::xs, to match the head and tail of a nonempty list, and an as e,pression to have a name for the entire actual parameter as )ell as its parts' for e,ample, J as x::xs, )hich matches the same thin(s as x::xs, but also assi(ns to J the entire list.

-,amples.
match (n 6 1) 8ith 1 -< (a( A 2 -< (%( A 5 -< (c( A / -< (d()) match myJist 8ith 9: -< (empty( A x::xs -< (nonempty())

Because every e,pression must have a value, OCaml )ill )arn you if it does not thin2 you have a pattern for every possible case. Chen e,pressions are nested, it can be difficult to tell e,actly )here the case e,pression ends. As )ith any e,pression, it doesn/t hurt to put parentheses around it, as for e,ample,
(match (n 6 1) 8ith 1 -< (a( A 2 -< (%( A 5 -< (c( A / -< (d()))

If expressions
The if expression loo2s li2e this.
i4 <bool expression> then <expression1> else <expression2>

If the <bool expression> is true, then <expression1> is evaluated and is the value of the e,pression, other)ise <expression2> is evaluated and is the value of the e,pression. 0ince the if e,pression is an e,pression and not a statement, it must have a value' therefore, the else part is re6uired. The if e,pression is really shorthand for the follo)in( match e,pression.
match <bool expression> 8ith tr&e -< <expression1> A 4alse -< <expression2>

Chen the OCaml compiler detects an error in an if e,pression, it reports the error as thou(h it occurred in the correspondin( case e,pression.

!e*uence of expressions
Ce can e,ecute a se6uence of e,pressions by separatin( them )ith semicolons and enclosin( the (roup in parentheses' the value of the se6uence is the value of the last e,pression in the

se6uence. Any values produced by earlier e,pressions are discarded. This is only useful )ith e,pressions that are evaluated for their side effects.
let name = (Nave( in (print-string (Gello. () print-string name) print-string (7n()))

OCaml is supposed to be a purely functional lan(ua(e, )hich means that it has no e,pressions )ith side effects. 1o)ever, printin( output is a side effect, and output is the primary use of side effects in OCaml. Output operations produce the unit, (), as their value. OCaml therefore e,pects all the e,pressions #e,cept the last& in a semicolon%separated list to have a unit value, and )ill )arn you if that isn/t the case.

Exceptions
An $e,ception$ is an error. @ou can declare ne) types of e,ceptions, )ith or )ithout a parameter, as follo)s.
exception <Name> )) exception <Name> o4 <type> ))

The name of an e,ception must be(in )ith a capital letter. For e,ample.
exception FormatOrror o4 int * string))

To si(nal that one of these e,ceptions has occurred, use


raise (<name> arguments)))

The )ay you use e,ceptions is as follo)s.


try <expression> 8ith <match>

If no e,ception is raised, the result of the try is the result of the <expression>. If an e,ception is raised, the first rule in <match> that matches the e,pression )ill be e,ecuted. If you raise an e,ception and fail to handle it, OCaml )ill (ive you an $uncau(ht e,ception$ error. 7ote that the results of the match must all have the same type as the result of a correct <expression>. 1o)ever, it/s o2ay to use a se6uence of e,pressions for printin(, ended )ith a value of the correct type, as in the follo)in( e,ample. -,ample.
exception Prong2rder o4 int*int)) let rec 4rom+o (m. n) = i4 m < n then raise (Prong2rder(m. n)) else i4 m = n then 9m: else m::4rom+o(m 6 1. n)))

let ma@eJist (m. n) = try 4rom+o (m. n) 8ith Prong2rder(m. n) -< (print-int m) print-string ( is greater than () print-int n) print-ne8line ()) 9:)))

Functions
The usual form of a function definition is
let <name> <parameter> = <expression> ))

+ function always has exactly one parameter, and returns one result, It often appears that a function ta2es more than one ar(ument or returns more than one result, but appearances can be misleadin(. For instance,
let s8ap (x. y) = (y. x)))

In this case, the one ar(ument is a tuple, and the one result is a tuple.
print-ne8line ()))

1ere, the one ar(ument is the unit, (), )hich is a value%%it is not synta, to indicate an empty parameter list. 0imilarly, the unit is returned as a result. Finally,
let max x y = i4 x < y then x else y))

This is an operation called currying, in )hich max ta2es the sin(le ar(ument x, and returns a new function )hich ta2es the sin(le ar(ument y. Curryin( is e,plained in more detail later in this paper. It doesn/t hurt to use a tuple of len(th " in place of a sin(le parameter' the follo)in( are e6uivalent definitions.
let score x = i4 x = " then " else x)) let score (x) = i4 x = " then " else x))

Functions that don/t use their parameter must still have one' they can be (iven the unit as the parameter.
let ta% () = print-char ,7t,))

0imilarly, a function can only return one value, but that value can easily be a tuple. For e,ample,
let vectorMdd ((x1. y1). (x2. y2)) = (x1 6 x2. y1 6 y2)))

<ecursive functions must include the 2ey)ord rec, for e,ample.


let rec 4irstNigit (x: int) = i4 x = 1" then x else 4irstNigit (x B 1")))

Patterns in functions 0imple functions consist of only a sin(le case, but more comple, functions typically use pattern matchin( to separate cases. Consider the )ell%2no)n Fibonacci function,
4i%(") = 4i%(1) = 1 4i%(n) = 4i%(n-1) 6 4i%(n-2). 4or n < 1

Ce can implement this in OCaml as follo)s.


let rec 4i%onacci x = match x 8ith " -< 1 A 1 -< 1 A n -< 4i%onacci (x - 1) 6 4i%onacci (x - 2)))

:sin( a match in this )ay is so common that there is a special synta, for it, as follo)s.
let rec 4i%onacci2 = 4&nction " -< 1 A 1 -< 1 A n -< 4i%onacci2 (n - 1) 6 4i%onacci2 (n - 2)))

7otice that.

The parameter #in this case, x& is omitted The )ord 4&nction replaces match x 8ith Instead of usin( parameter x, the parameter is matched a(ainst a variable n, )hich can then be used in place of x

-,amples.
let rec length = 4&nction 9: -< " A (x :: xs) -< 1 6 length xs)) let rec mem%er = 4&nction (e. 9:) -< 4alse A (e. x::xs) -< i4 (e = x) then tr&e else mem%er (e. xs) ))

)utually recursive functions Functions must be defined before they are used. To define mutually recursive functions #functions that call one another&, use let rec...and...and.... The follo)in( e,ample #to return every other element of a list& is adapted from Elements of Caml Programming by 3effrey ;. :llman.

let rec ta@e (ls) = i4 ls = 9: then 9: else Jist.hd(ls) :: s@ip(Jist.tl(ls)) and s@ip (ls) = i4 ls = 9: then 9: else ta@e(Jist.tl(ls)) ))

Local varia"les in functions It is sometimes convenient to declare local variables and functions usin( let...in... For e,ample,
# let i! le4ata (!adius:fl%at) = let pi = 3.1415*06536 in let i! umfe!en e = 0.1 *. pi *. !adius in let a!ea !adius = pi *. !adius *. !adius in ( i! umfe!en e, a!ea !adius) ;; val circleNata : 4loat -< 4loat * 4loat = =4&n< # i! le4ata 11.1;; - : 4loat * 4loat = #2.8518'5"02. 51/.1'D2#'5# The let and let...in e,pressions )or2 )ith patterns, so it is possible

to do $multiple

assi(nment$ by assi(nin( one tuple to another, as for e,ample


# let x, y, 5 = 5, 11, "hell%";; val x : int = ' val y : int = 1" val H : string = (hello( # let (a, 3) = (6, +) in (3, a, 3);; - : int * int * int = 0. #. 0

It is useful to 2no) that multiple assi(nments happen simultaneously rather than one after another, so that the follo)in( code correctly s)aps t)o values.
# let s6ap (x, y) = y, x;; val s8ap : ,a * ,% -< ,% * ,a = # s6ap (3, 5);; - : int * int = '. 5

+nonymous functions Matches can also be used to define anonymous functions.


(4&n x -< x 6 1) 5

#<esult is +.& Anonymous functions cannot be recursive because, bein( anonymous, they have no name by )hich you can call them. 1o)ever, an anonymous function can be (iven a name in the usual )ay, by usin( let.
# let in ! = fun x 7> x + 1;; val incr : int -< int = =4&n< # in ! 5;; - : int = #

Polymorphic functions

In other lan(ua(es, $polymorphic$ means that you have t)o or more functions )ith the same name' in OCaml it means that a sin(le function can handle more than one type of parameter. An e,ample of a built%in polymorphic function is the list function Jist.hd' it returns the first element of any type of list. OCaml functions that you )rite )ill be polymorphic if their parameters are used only )ith polymorphic functions and operators. For e,ample, the follo)in( function to reverse the t)o components of a =%tuple is polymorphic.
let revPair (x. y) = (y. x)))

To )rite a polymorphic function, you need to avoid:


arithmetic operators #because OCaml needs to 2no) )hether the arithmetic is inte(er or floatin( point&, strin( concatenation boolean operators type conversion operators.

@ou can use.


lists and the list operators hd, tl, ::, I, alon( )ith the constant 9: the e6uality tests = and E=.

-i$her order functions A hi(her%order function is one )hich ta2es a function #or a function%containin( structure& as an ar(ument, or produces a function #or function%containin( structure& as its result, or both. For e,ample,
# let test (f, x) = f x;; val test : (,a -< ,%) * ,a -< ,% = =4&n< # test (8ist.hd, 91;0;3:);; - : int = 1 # test (8ist.tl, 91;0;3:);; # - : int list = 92) 5:

7otice in particular the type returned )hen test is defined. (,a -< ,%) * ,a -< ,%. 1ere, (,a -< ,%) is a function from type ,a to type ,%, type ,a is the needed parameter type, and ,% is the result type. %urried functions As )as stated earlier, every function ta2es e,actly one ar(ument and produces one result. A curried function is a hi(her%order function that ta2es an ar(ument and produces as result a ne) function )ith that ar(ument embedded in the function. For e,ample,
# let in ! x y = x + y;; val incr : int -< int -< int = =4&n<

# in ! 5 3;; - : int = 8 # (in ! 5) 3;; - : int = 8 # let in !5 = in ! 5;; val incr' : int -< int = =4&n< # in !5 3;; - : int = 8

7otice the )ay the function incr is defined, as if it had t)o blan2%separated ar(uments. In fact, incr ta2es one ar(ument, x, and produces the curried function (incr x), )hich then has y as an ar(ument. 7o) incr can be called as incr ' 5 or as (incr ') 5, but cannot be called as incr ('. 5). This is because incr ta2es one ar(ument, an inte(er, and returns a function as a result' it does not ta2e a tuple as an ar(ument. The fact that incr ' returns a function as a result is further emphasi5ed in the assi(nment of this value #a function that adds > to its ar(ument& to the variable incr',. 7ote also that )e don/t need to specify a parameter' a function is just another 2ind of value. Ce could, if )e )ished, have defined incr' by let incr' x = incr ' x)) )ith e,actly the same result.
map

is a curried function that ta2es a function that applies to one thin( of type ,a and produces a function that applies to a list ,a. For e,ample,
Jist.map # t!un ate 5.;;; - : int = ' # 8ist.map t!un ate 90.+; 3.1; 3.;; *.4; 6.5:;; - : int list = 92) 5) 5) D) #: # (8ist.map t!un ate) 90.+; 3.1; 3.;; *.4; 6.5:;; - : int list = 92) 5) 5) D) #: # let list<!un = 8ist.map t!un ate;; val list+r&nc : 4loat list -< int list = =4&n< # list<!un 90.+; 3.1; 3.;; *.4; 6.5:;; - : int list = 92) 5) 5) D) #: 8ist.filte!

The function Jist.4ilter ta2es a bool test and returns a function that )ill e,tract from a list those elements that pass the test.
# 8ist.filte! (fun x 7> x > 1) 93; 1; 0; 75; 7;; 4:;; - : int list = 95) 2) /:

.edefinin$ functions Important: Chen you define a function, you may use other values #includin( other functions& in the definition. Later chan(es to those values do not chan(e the meanin( of the function you have defined. For e,ample, loo2 at the follo)in( se6uence #for clarity, only some of OCaml/s responses are sho)n&.
# let x = 3;; # let aa () = 5;; # let 33 () = aa () + x;;

# # # # -

33 ();; : int = 8 let x = 1+;; let aa () = ;3;; 33 ();; : int = 8

1ere, %%() )as defined in terms of aa() and x. Callin( %%() (ave the result 8. Later chan(es to aa() and x did not affect the definition of %%(). The above may seem stran(e, but there is a parallel in al(orithmic lan(ua(es. Consider the se6uence of statements a := ') % := a) a := 1") @ou )ould not e,pect the value of % to chan(e just because the value of a chan(ed. In OCaml, functions are values, and they are treated just li2e any other values. A definition is said to have referential transparency if its meanin( does not depend on the conte,t it is in. Functions in OCaml have referential transparency, that is, chan(in( the conte,t #other variables and other functions& does not chan(e the meanin( of any functions you have already defined. This fact can be crucial )hen you are debu((in( a pro(ram, because you are li2ely to be redefinin( functions fairly fre6uently.

&missions
This is a brief document, and a (reat deal has been omitted. Amon( the more important omissions are records, arrays, the inputAoutput system, most of the module system, and practically everythin( havin( to do )ith object%oriented pro(rammin(. Loops, also, have been omitted, but they are not terribly useful in a purely functional lan(ua(e, any)ay. More information #and more trust)orthy informationD& can be obtained from the documents mentioned in the ne,t section.

.esources
The &"/ective %aml system release 0,12, ;ocumentation and user/s manual. Eavier Leroy #)ith ;amien ;oli(e5, 3ac6ues ?arri(ue, ;idier <8my and 38rFme Gouillon&, March H, =!!". This is available at http.AAcaml.inria.frAocamlAhtmlmanAinde,.html and on the Bur2s > C;. +n introduction to &%+)L for %!E 231. 4eter Buneman, October ", =!!!. This is available as an Acrobat document at http.AA))).seas.upenn.edu.H!H!AIcse"=!AresourcesAprimerAprimer.pdf and as a postscript document at http.AA))).seas.upenn.edu.H!H!AIcse"=!AresourcesAprimerAprimer.ps.

You might also like