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) |
Developer | INRIA, ENS |
First appeared | 1985 |
Stable release | 0.75 [1] / January 26, 2002 |
Typing discipline | inferred, static, strong |
Memory management | automatic |
OS | Cross-platform: Unix, Linux, macOS; Windows |
License | QPL 1, LGPL 2 (Caml Light) |
Website | caml |
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:
print_endline"Hello, world!";;
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
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 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. Going further can 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. 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 (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.).
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.
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, high-level, functional programming language. It is known for its use of the polymorphic Hindley–Milner type system, which automatically assigns the data 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. While a general-purpose programming language, ML 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, high-level, 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, high-level, modular, functional programming language with compile-time type checking and type inference. It is popular for writing compilers, for programming language research, and for developing theorem provers.
In combinatory logic for computer science, a fixed-point combinator, is a higher-order function that returns some fixed point of its argument function, if one exists.
F# is a general-purpose, high-level, strongly typed, multi-paradigm programming language that encompasses functional, imperative, and object-oriented programming methods. It is most often used as a cross-platform Common Language Infrastructure (CLI) language on .NET, but can also generate JavaScript and graphics processing unit (GPU) code.
In mathematics and computer science, a higher-order function (HOF) is a function that does at least one of the following:
In complex analysis, the Hardy spacesHp are certain spaces of holomorphic functions on the unit disk or upper half plane. They were introduced by Frigyes Riesz, who named them after G. H. Hardy, because of the paper. In real analysis Hardy spaces are certain spaces of distributions on the real line, which are boundary values of the holomorphic functions of the complex Hardy spaces, and are related to the Lp spaces of functional analysis. For 1 ≤ p < ∞ these real Hardy spaces Hp are certain subsets of Lp, while for p < 1 the Lp spaces have some undesirable properties, and the Hardy spaces are much better behaved.
In computing, memoization or memoisation is an optimization technique used primarily to speed up computer programs by storing the results of expensive function calls to pure functions 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. It is a type of caching, distinct from other forms of caching such as buffering and 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 allows a single piece of code to be given a "generic" type, using variables in place of actual types, and then instantiated with particular types as needed. Parametrically polymorphic functions and data types are sometimes called generic functions and generic datatypes, respectively, and they form the basis of generic programming.
JoCaml is an experimental general-purpose, high-level, multi-paradigm, functional and object-oriented 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 a 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 an MIT License. The compiler, written in OCaml, is released under the GNU General Public License (GPL) version 2.
In computing, ATS is a multi-paradigm, general-purpose, high-level, functional programming language. It is a dialect of the programming language ML, designed by Hongwei Xi to unify computer programming with formal specification. ATS has support for combining theorem proving with practical programming through the use of advanced type systems. A past version of The Computer Language Benchmarks Game has demonstrated that the performance of ATS is comparable to that of the languages C and C++. By using theorem proving and strict type checking, the compiler can detect and prove that its implemented functions are not susceptible to bugs such as division by zero, memory leaks, buffer overflow, and other forms of memory corruption by verifying pointer arithmetic and reference counting before the program compiles. Also, by using the integrated theorem-proving system of ATS (ATS/LF), the programmer may make use of static constructs that are intertwined with the operative code to prove that a function conforms to its specification.
This article describes the features in the programming language Haskell.
In mathematics, Sobolev spaces for planar domains are one of the principal techniques used in the theory of partial differential equations for solving the Dirichlet and Neumann boundary value problems for the Laplacian in a bounded domain in the plane with smooth boundary. The methods use the theory of bounded operators on Hilbert space. They can be used to deduce regularity properties of solutions and to solve the corresponding eigenvalue problems.
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.
F* is a high-level, multi-paradigm, functional and object-oriented programming language inspired by the languages ML, Caml, and OCaml, and intended for program verification. It is a joint project of Microsoft Research, and the French Institute for Research in Computer Science and Automation (Inria). Its type system includes dependent types, monadic effects, and refinement types. This allows expressing precise specifications for programs, including functional correctness and security properties. The F* type-checker aims to prove that programs meet their specifications using a combination of satisfiability modulo theories (SMT) solving and manual proofs. For execution, programs written in F* can be translated to OCaml, F#, C, WebAssembly, or assembly language. Prior F* versions could also be translated to JavaScript.