Caml

Last updated
Caml
Caml.gif
Paradigm Multi-paradigm: functional, imperative
Family ML
Designed by Gérard Huet, Guy Cousineau, Ascánder Suárez, Pierre Weis, Michel Mauny (Heavy Caml), Xavier Leroy (Caml Light)
First appeared1985
Stable release
0.75 [1] / January 26, 2002;19 years ago (2002-01-26)
Typing discipline Inferred, static, strong
OS Cross-platform
Website caml.inria.fr
Influenced by
ML
Influenced
OCaml

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.

Contents

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, # 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:

letrecfactn=ifn=0then1elsen*fact(n-1);;

The function can be written equivalently using pattern matching:

letrecfact=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 int->int, meaning that this function maps ints onto ints. For example, 12! is:

#fact12;;-: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 d computes the numerical derivative of a given function f at a given point x:

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

This function requires a small value delta. A good choice for delta is the cube root of the machine epsilon [ citation needed ].

The type of the function d indicates that it maps a float onto another function with the type (float->float)->float->float. 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 delta to d, to obtain a more specialised function:

#letd=d(sqrtepsilon_float);;vald:(float->float)->float->float=<fun>

Note that the inferred type indicates that the replacement d is expecting a function with the type float->float as its first argument. We can compute a numerical approximation to the derivative of at with:

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

The correct answer is .

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

#letf'=d(funx->x*.x*.x-.x-.1.);;valf':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 (h1 and h2) off the front and storing their sums and differences on the lists s and d, respectively:

#lethaarl=letrecauxlsd=matchl,s,dwith[s],[],d->s::d|[],s,d->auxs[]d|h1::h2::t,s,d->auxt(h1+h2::s)(h1-h2::d)|_->invalid_arg"haar"inauxl[][];;valhaar:intlist->intlist=<fun>

For example:

#haar[1;2;3;4;-4;-3;-2;-1];;-:intlist=[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). [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 layer to become Objective Caml, eventually renamed OCaml.

See also

Related Research Articles

In computer science, functional programming is a programming paradigm where programs are constructed by applying and composing functions. It is a declarative programming paradigm in which function definitions are trees of expressions that map values to other values, rather than a sequence of imperative statements which update the running state of the program.

ML is a general-purpose functional programming language. It is known for its use of the polymorphic Hindley–Milner type system, which automatically assigns the types of most expressions without requiring explicit type annotations, and ensures type safety – there is a formal proof that a well-typed ML program does not cause runtime type errors. ML provides pattern matching for function arguments, garbage collection, imperative programming, call-by-value and currying. It is used heavily in programming language research and is one of the few languages to be completely specified and verified using formal semantics. Its types and pattern matching make it well-suited and commonly used to operate on other formal languages, such as in compiler writing, automated theorem proving, and formal verification.

OCaml is a general-purpose, multi-paradigm programming language which extends the Caml dialect of ML with object-oriented features. OCaml was created in 1996 by Xavier Leroy, Jérôme Vouillon, Damien Doligez, Didier Rémy, Ascánder Suárez, and others.

Standard ML (SML) is a general-purpose modular functional programming language with compile-time type checking and type inference. It is popular among compiler writers and programming language researchers, as well as in the development of theorem provers.

In programming language theory, subtyping is a form of type polymorphism in which a subtype is a datatype that is related to another datatype by some notion of substitutability, meaning that program elements, typically subroutines or functions, written to operate on elements of the supertype can also operate on elements of the subtype. If S is a subtype of T, the subtyping relation is often written S <: T, to mean that any term of type S can be safely used in a context where a term of type T is expected. The precise semantics of subtyping crucially depends on the particulars of what "safely used in a context where" means in a given programming language. The type system of a programming language essentially defines its own subtyping relation, which may well be trivial, should the language support no conversion mechanisms.

F Sharp (programming language) Microsoft programming language

F# is a functional-first, general purpose, strongly typed, multi-paradigm programming language that encompasses functional, imperative, and object-oriented programming methods. F# is most often used as a cross-platform Common Language Infrastructure (CLI) language on .NET, but it can also generate JavaScript and graphics processing unit (GPU) code.

In mathematics and computer science, a higher-order function is a function that does at least one of the following:

In computing, memoization or memoisation is an optimization technique used primarily to speed up computer programs by storing the results of expensive function calls and returning the cached result when the same inputs occur again. Memoization has also been used in other contexts, such as in simple mutually recursive descent parsing. Although related to caching, memoization refers to a specific case of this optimization, distinguishing it from forms of caching such as buffering or page replacement. In the context of some logic programming languages, memoization is also known as tabling.

In functional programming, continuation-passing style (CPS) is a style of programming in which control is passed explicitly in the form of a continuation. This is contrasted with direct style, which is the usual style of programming. Gerald Jay Sussman and Guy L. Steele, Jr. coined the phrase in AI Memo 349 (1975), which sets out the first version of the Scheme programming language. John C. Reynolds gives a detailed account of the numerous discoveries of continuations.

Camlp4 is a software system for writing extensible parsers for programming languages. It provides a set of OCaml libraries that are used to define grammars as well as loadable syntax extensions of such grammars. Camlp4 stands for Caml Preprocessor and Pretty-Printer and one of its most important applications was the definition of domain-specific extensions of the syntax of OCaml.

In programming languages and type theory, parametric polymorphism is a way to make a language more expressive, while still maintaining full static type-safety. Using parametric polymorphism, a function or a data type can be written generically so that it can handle values identically without depending on their type. Such functions and data types are called generic functions and generic datatypes respectively and form the basis of generic programming.

JoCaml is an experimental functional programming language derived from OCaml. It integrates the primitives of the join-calculus to enable flexible, type-checked concurrent and distributed programming. The current version of JoCaml is a re-implementation of the now unmaintained JoCaml made by Fabrice Le Fessant, featuring a modified syntax and improved OCaml compatibility compared to the original.

A structural type system is a major class of type systems in which type compatibility and equivalence are determined by the type's actual structure or definition and not by other characteristics such as its name or place of declaration. Structural systems are used to determine if types are equivalent and whether a type is a subtype of another. It contrasts with nominative systems, where comparisons are based on the names of the types or explicit declarations, and duck typing, in which only the part of the structure accessed at runtime is checked for compatibility.

Haxe is an open source high-level cross-platform programming language and compiler that can produce applications and source code, for many different computing platforms from one code-base. It is free and open-source software, released under the MIT License. The compiler, written in OCaml, is released under the GNU General Public License (GPL) version 2.

In functional programming, a generalized algebraic data type is a generalization of parametric algebraic data types.

In computer programming, an anonymous function is a function definition that is not bound to an identifier. Anonymous functions are often arguments being passed to higher-order functions or used for constructing the result of a higher-order function that needs to return a function. If the function is only used once, or a limited number of times, an anonymous function may be syntactically lighter than using a named function. Anonymous functions are ubiquitous in functional programming languages and other languages with first-class functions, where they fulfil the same role for the function type as literals do for other data types.

In programming languages and type theory, an option type or maybe type is a polymorphic type that represents encapsulation of an optional value; e.g., it is used as the return type of functions which may or may not return a meaningful value when they are applied. It consists of a constructor which either is empty, or which encapsulates the original data type A.

This article describes the features in Haskell.

Join-patterns provides a way to write concurrent, parallel and distributed computer programs by message passing. Compared to the use of threads and locks, this is a high level programming model using communication constructs model to abstract the complexity of concurrent environment and to allow scalability. Its focus is on the execution of a chord between messages atomically consumed from a group of channels.

Flix is a functional, imperative, and logic programming language developed at Aarhus University, with funding from the Independent Research Fund Denmark, and by a community of open source contributors. The Flix language supports algebraic data types, pattern matching, parametric polymorphism, currying, higher-order functions, extensible records, channel and process-based concurrency, and tail call elimination. Two notable features of Flix are its type and effect system and its support for first-class Datalog constraints.

References

  1. "Latest Caml Light release" . Retrieved 22 February 2020.
  2. 1 2 3 "A History of Caml", inria.fr

Bibliography