Caml | |
Paradigm: | Multi-paradigm |
Family: | ML |
Designer: | Gérard Huet, Guy Cousineau, Ascánder Suárez, Pierre Weis, Michel Mauny (Heavy Caml), Xavier Leroy (Caml Light) |
Developer: | INRIA, ENS |
Latest Release Version: | 0.75[1] |
Typing: | inferred, static, strong |
Memory Management: | automatic |
Operating System: | Cross-platform |
License: | QPL 1, LGPL 2 (Caml Light) |
Influenced By: | ML |
Influenced: | OCaml |
Caml (originally an acronym for Categorical Abstract Machine Language) is a multi-paradigm, general-purpose, high-level, functional programming language which is a dialect of the ML programming language family. Caml was developed in France at French Institute for Research in Computer Science and Automation (INRIA) and École normale supérieure (Paris) (ENS).
Caml is statically typed, strictly evaluated, and uses automatic memory management. OCaml, the main descendant of Caml, adds many features to the language, including an object-oriented programming (object) layer.
In the following, represents the Caml prompt.
A "Hello, World!" program is:
Many mathematical functions, such as factorial, are most naturally represented in a purely functional form. The following recursive, purely functional Caml function implements factorial:
Note that the compiler inferred the type of this function to be, meaning that this function maps ints onto ints. For example, 12! is:
Since Caml is a functional programming language, it is easy to create and pass around functions in Caml programs. This ability has very many applications. Calculating the numerical derivative of a function is one example. The following Caml function computes the numerical derivative of a given function at a given point :
The type of the function indicates that it maps a onto another function with the type . This allows us to partially apply arguments. This functional style is known as currying. In this case, it is useful to partially apply the first argument to, to obtain a more specialised function:
val d : (float -> float) -> float -> float =
x3-x-1
x=3
- : float = 26.
f'(x)=3x2-1 → f'(3)=27-1=26
The function is called a "higher-order function" because it accepts another function as an argument.Going further can create the (approximate) derivative of f, by applying while omitting the argument:
val f' : float -> float =
The concepts of curried and higher-order functions are clearly useful in mathematical programs. These concepts are equally applicable to most other forms of programming and can be used to factor code much more aggressively, resulting in shorter programs and fewer bugs.
The 1D Haar wavelet transform of an integer-power-of-two-length list of numbers can be implemented very succinctly in Caml and is an excellent example of the use of pattern matching over lists, taking pairs of elements (and) off the front and storing their sums and differences on the lists and, respectively:
let rec aux l s d = match l, s, d with [s], [], d -> s :: d | [], s, d -> aux s [] d | h1 :: h2 :: t, s, d -> aux t (h1 + h2 :: s) (h1 - h2 :: d) | _ -> invalid_arg "haar" in aux l [] [];;val haar : int list -> int list =
The first Caml implementation was written in Lisp by Ascánder Suárez in 1987 at the French Institute for Research in Computer Science and Automation (INRIA).[2]
Its successor, Caml Light, was implemented in C by Xavier Leroy and Damien Doligez,[2] and the original was nicknamed "Heavy Caml" because of its higher memory and CPU requirements.[2]
Caml Special Light was a further complete rewrite that added a powerful module system to the core language. It was augmented with an object-oriented programming (object) layer to become Objective Caml, eventually renamed OCaml.