Английская Википедия:Caml

Материал из Онлайн справочника
Версия от 09:50, 14 февраля 2024; EducationBot (обсуждение | вклад) (Новая страница: «{{Английская Википедия/Панель перехода}} {{Short description|Programming language}} {{About|the programming language||CAML (disambiguation)}} {{Infobox programming language | name = Caml | logo = File:Caml.gif | paradigm = Multi-paradigm: functional, imperative | family =...»)
(разн.) ← Предыдущая версия | Текущая версия (разн.) | Следующая версия → (разн.)
Перейти к навигацииПерейти к поиску

Шаблон:Short description Шаблон:About Шаблон:Infobox programming language

Caml (originally an acronym for Categorical Abstract Machine Language) is a multi-paradigm, general-purpose programming language which is a dialect of the ML programming language family. Caml was developed in France at INRIA and 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 layer.

Examples

In the following, Шаблон:OCaml represents the Caml prompt.

Hello World

print_endline "Hello, world!";;

Factorial function (recursion and purely functional programming)

Many mathematical functions, such as factorial, are most naturally represented in a purely functional form. The following recursive, purely functional Caml function implements factorial:

let rec fact n = if n=0 then 1 else n * fact(n - 1);;

The function can be written equivalently using pattern matching:

let rec fact = function
  | 0 -> 1
  | n -> n * fact(n - 1);;

This latter form is the mathematical definition of factorial as a recurrence relation.

Note that the compiler inferred the type of this function to be Шаблон:OCaml, meaning that this function maps ints onto ints. For example, 12! is:

 # fact 12;;
 - : int = 479001600

Numerical derivative (higher-order functions)

Since Caml is a functional programming language, it is easy to create and pass around functions in Caml programs. This capability has an enormous number of applications. Calculating the numerical derivative of a function is one such application. The following Caml function Шаблон:OCaml computes the numerical derivative of a given function Шаблон:OCaml at a given point Шаблон:OCaml:

let d delta f x =
  (f (x +. delta) -. f (x -. delta)) /. (2. *. delta);;

This function requires a small value Шаблон:OCaml. A good choice for delta is the cube root of the machine epsilonШаблон:Citation needed.

The type of the function Шаблон:OCaml indicates that it maps a Шаблон:OCaml onto another function with the type Шаблон:OCaml. 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 Шаблон:OCaml to Шаблон:OCaml, to obtain a more specialised function:

# let d = d (sqrt epsilon_float);;
val d : (float -> float) -> float -> float = <fun>

Note that the inferred type indicates that the replacement Шаблон:OCaml is expecting a function with the type Шаблон:OCaml as its first argument. We can compute a numerical approximation to the derivative of <math>x^3 - x - 1</math> at <math>x=3</math> with:

# d (fun x -> x *. x *. x -. x -. 1.) 3.;;
- : float = 26.

The correct answer is <math>f'(x) = 3x^2 - 1 \rightarrow f'(3) = 27 - 1 = 26</math>.

The function Шаблон:OCaml is called a "higher-order function" because it accepts another function (Шаблон:OCaml) as an argument. We can go further and create the (approximate) derivative of f, by applying Шаблон:OCaml while omitting the Шаблон:OCaml argument:

# let f' = d (fun x -> x *. x *. x -. x -. 1.) ;;
val f' : float -> float = <fun>

The concepts of curried and higher-order functions are clearly useful in mathematical programs. In fact, 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.

Discrete wavelet transform (pattern matching)

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 (Шаблон:OCaml and Шаблон:OCaml) off the front and storing their sums and differences on the lists Шаблон:OCaml and Шаблон:OCaml, respectively:

# let haar l =
   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 = <fun>

For example:

  # haar [1; 2; 3; 4; -4; -3; -2; -1];;
   - : int list = [0; 20; 4; 4; -1; -1; -1; -1]

Pattern matching allows complicated transformations to be represented clearly and succinctly. Moreover, the Caml compiler turns pattern matches into very efficient code, at times resulting in programs that are shorter and faster than equivalent code written with a case statement (Cardelli 1984, p. 210.).

History

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).[1]

Its successor, Caml Light, was implemented in C by Xavier Leroy and Damien Doligez,[1] and the original was nicknamed "Heavy Caml" because of its higher memory and CPU requirements.[1]

Caml Special Light was a further complete rewrite that added a powerful module system to the core language. It was augmented with an object layer to become Objective Caml, eventually renamed OCaml.

See also

References

Шаблон:Reflist

Bibliography

External links

  1. 1,0 1,1 1,2 "A History of Caml", inria.fr