Professional Documents
Culture Documents
OCaml
OCaml
OCaml
Philosophy
ML-derived languages are best known for their static type systems and type-inferring compilers. OCaml
unifies functional, imperative, and object-oriented programming under an ML-like type system. Thus,
programmers need not be highly familiar with the pure functional language paradigm to use OCaml.
By requiring the programmer to work within the constraints of its static type system, OCaml eliminates
many of the type-related runtime problems associated with dynamically typed languages. Also, OCaml's
type-inferring compiler greatly reduces the need for the manual type annotations that are required in most
statically typed languages. For example, the data types of variables and the signatures of functions usually
need not be declared explicitly, as they do in languages like Java and C#, because they can be inferred from
the operators and other functions that are applied to the variables and other values in the code. Effective use
of OCaml's type system can require some sophistication on the part of a programmer, but this discipline is
rewarded with reliable, high-performance software.
OCaml is perhaps most distinguished from other languages with origins in academia by its emphasis on
performance. Its static type system prevents runtime type mismatches and thus obviates runtime type and
safety checks that burden the performance of dynamically typed languages, while still guaranteeing runtime
safety, except when array bounds checking is turned off or when some type-unsafe features like
serialization are used. These are rare enough that avoiding them is quite possible in practice.
Aside from type-checking overhead, functional programming languages are, in general, challenging to
compile to efficient machine language code, due to issues such as the funarg problem. Along with standard
loop, register, and instruction optimizations, OCaml's optimizing compiler employs static program analysis
methods to optimize value boxing and closure allocation, helping to maximize the performance of the
resulting code even if it makes extensive use of functional programming constructs.
Xavier Leroy has stated that "OCaml delivers at least 50% of the performance of a decent C compiler",[3]
although a direct comparison is impossible. Some functions in the OCaml standard library are implemented
with faster algorithms than equivalent functions in the standard libraries of other languages. For example,
the implementation of set union in the OCaml standard library in theory is asymptotically faster than the
equivalent function in the standard libraries of imperative languages (e.g., C++, Java) because the OCaml
implementation exploits the immutability of sets to reuse parts of input sets in the output (see persistent data
structure).
Features
OCaml features a static type system, type inference, parametric polymorphism, tail recursion, pattern
matching, first class lexical closures, functors (parametric modules), exception handling, and incremental
generational automatic garbage collection.
OCaml is notable for extending ML-style type inference to an object system in a general-purpose language.
This permits structural subtyping, where object types are compatible if their method signatures are
compatible, regardless of their declared inheritance (an unusual feature in statically typed languages).
A foreign function interface for linking to C primitives is provided, including language support for efficient
numerical arrays in formats compatible with both C and Fortran. OCaml also supports creating libraries of
OCaml functions that can be linked to a main program in C, so that an OCaml library can be distributed to
C programmers who have no knowledge or installation of OCaml.
The native code compiler is available for many platforms, including Unix, Microsoft Windows, and Apple
macOS. Portability is achieved through native code generation support for major architectures: IA-32, X86-
64 (AMD64), Power, RISC-V, ARM, and ARM64.[4]
OCaml bytecode and native code programs can be written in a multithreaded style, with preemptive context
switching. However, because the garbage collector of the INRIA OCaml system (which is the only
currently available full implementation of the language) is not designed for concurrency, symmetric
multiprocessing is unsupported.[5] OCaml threads in the same process execute by time sharing only. There
are however several libraries for distributed computing such as Functory (http://functory.lri.fr/About.html)
and ocamlnet/Plasma (http://projects.camlcity.org/projects/ocamlnet.html).
Development environment
Since 2011, many new tools and libraries have been contributed to the OCaml development environment:
Development tools
opam (http://opam.ocaml.org/) is a package manager for OCaml.
Merlin (https://github.com/ocaml/merlin) provides IDE-like functionality for multiple
editors, including type throwback, go-to-definition, and auto-completion.
Dune (https://github.com/ocaml/dune) is a composable build-system for OCaml.
OCamlformat (https://github.com/ocaml-ppx/ocamlformat) is an auto-formatter for OCaml.
ocaml-lsp-server (https://github.com/ocaml/ocaml-lsp) is a Language Server Protocol for
OCaml IDE integration.
Web sites:
OCaml.org (https://ocaml.org/) is the primary site for the language.
discuss.ocaml.org (https://discuss.ocaml.org/) is an instance of Discourse that serves as
the primary discussion site for OCaml.
Alternate compilers for OCaml:
js_of_ocaml, developed by the Ocsigen team, is an optimizing compiler from OCaml to
JavaScript.
BuckleScript (https://bucklescript.github.io/), which also targets JavaScript, with a focus
on producing readable, idiomatic JavaScript output.
ocamlcc is a compiler from OCaml to C, to complement the native code compiler for
unsupported platforms.
OCamlJava, developed by INRIA, is a compiler from OCaml to the Java virtual machine
(JVM).
OCaPic, developed by Lip6, is an OCaml compiler for PIC microcontrollers.
Code examples
Snippets of OCaml code are most easily studied by entering them into the top-level REPL. This is an
interactive OCaml session that prints the inferred types of resulting or defined expressions.[6] The OCaml
top-level is started by simply executing the OCaml program:
$ ocaml
Objective Caml version 3.09.0
#
Code can then be entered at the "#" prompt. For example, to calculate 1+2*3:
# 1 + 2 * 3;;
- : int = 7
OCaml infers the type of the expression to be "int" (a machine-precision integer) and gives the result "7".
Hello World
and executed:
$ ./hello
Hello World!
$
The first argument to ocamlc, "hello.ml", specifies the source file to compile and the "-o hello" flag
specifies the output file.[7]
# sum [1;2;3;4;5];;
- : int = 15
Another way is to use standard fold function that works with lists.
# sum [1;2;3;4;5];;
- : int = 15
Since the anonymous function is simply the application of the + operator, this can be shortened to:
Furthermore, one can omit the list argument by making use of a partial application:
let sum =
List.fold_left (+) 0
Quicksort
OCaml lends itself to concisely expressing recursive algorithms. The following code example implements
an algorithm similar to quicksort that sorts a list in increasing order.
Birthday problem
The following program calculates the smallest number of people in a room for whom the probability of
completely unique birthdays is less than 50% (the birthday problem, where for 1 person the probability is
365/365 (or 100%), for 2 it is 364/365, for 3 it is 364/365 × 363/365, etc.) (answer = 23).
birthday_paradox 1.0 1
Church numerals
The following code defines a Church encoding of natural numbers, with successor (succ) and addition
(add). A Church numeral n is a higher-order function that accepts a function f and a value x and applies f
to x exactly n times. To convert a Church numeral from a functional value to a string, we pass it a function
that prepends the string "S" to its input and the constant string "0".
let zero f x = x
let succ n f x = f (n f x)
let one = succ zero
let two = succ (succ zero)
let add n1 n2 f x = n1 f (n2 f x)
let to_string n = n (fun k -> "S" ^ k) "0"
let _ = to_string (add (succ two) two)
A variety of libraries are directly accessible from OCaml. For example, OCaml has a built-in library for
arbitrary-precision arithmetic. As the factorial function grows very rapidly, it quickly overflows machine-
precision numbers (typically 32- or 64-bits). Thus, factorial is a suitable candidate for arbitrary-precision
arithmetic.
In OCaml, the Num module (now superseded by the ZArith module) provides arbitrary-precision arithmetic
and can be loaded into a running top-level using:
# #use "topfind";;
# #require "num";;
# open Num;;
The factorial function may then be written using the arbitrary-precision numeric operators =/, */ and -/ :
Triangle (graphics)
let () =
ignore (Glut.init Sys.argv);
Glut.initDisplayMode ~double_buffer:true ();
ignore (Glut.createWindow ~title:"OpenGL Demo");
let angle t = 10. *. t *. t in
let render () =
GlClear.clear [ `color ];
GlMat.load_identity ();
GlMat.rotate ~angle: (angle (Sys.time ())) ~z:1. ();
GlDraw.begins `triangles;
List.iter GlDraw.vertex2 [-1., -1.; 0., 1.; 1., -1.];
GlDraw.ends ();
Glut.swapBuffers () in
GlMat.mode `modelview;
Glut.displayFunc ~cb:render;
Glut.idleFunc ~cb:(Some Glut.postRedisplay);
Glut.mainLoop ()
The LablGL bindings to OpenGL are required. The program may then be compiled to bytecode with:
or to nativecode with:
and run:
$ ./simple
Far more sophisticated, high-performance 2D and 3D graphical programs can be developed in OCaml.
Thanks to the use of OpenGL and OCaml, the resulting programs can be cross-platform, compiling without
any changes on many major platforms.
Fibonacci sequence
The following code calculates the Fibonacci sequence of a number n inputted. It uses tail recursion and
pattern matching.
let fib n =
let rec fib_aux m a b =
match m with
| 0 -> a
| _ -> fib_aux (m - 1) b (a + b)
in fib_aux n 0 1
Higher-order functions
Functions may take functions as input and return functions as result. For example, applying twice to a
function f yields a function that applies f two times to its argument.
# add2 98;;
- : int = 100
# add_str "Test";;
- : string = "Test Test Test Test"
The function twice uses a type variable 'a to indicate that it can be applied to any function f mapping from a
type 'a to itself, rather than only to int->int functions. In particular, twice can even be applied to itself.
Derived languages
MetaOCaml
As an example: if at compile time it is known that some power function x -> x^n is needed often, but
the value of n is known only at runtime, a two-stage power function can be used in MetaOCaml:
Users
Several dozen companies use OCaml to some degree.[14] Notable examples include:
References
1. "Modules" (https://ocaml.org/learn/tutorials/modules.html). Retrieved 22 February 2020.
2. "A History of OCaml" (http://ocaml.org/learn/history.html). Retrieved 24 December 2016.
3. Linux Weekly News (https://lwn.net/Articles/19378/).
4. "ocaml/asmcomp at trunk · ocaml/ocaml · GitHub" (https://github.com/ocaml/ocaml/tree/trunk/
asmcomp). GitHub. Retrieved 2 May 2015.
5. "Archives of the Caml mailing list > Message from Xavier Leroy" (http://mirror.ocamlcore.org/
caml.inria.fr/pub/ml-archives/caml-list/2002/11/64c14acb90cb14bedb2cacb73338fb15.en.ht
ml). Retrieved 2 May 2015.
6. "OCaml - The toplevel system or REPL (ocaml)" (https://ocaml.org/manual/toplevel.html).
ocaml.org. Retrieved 2021-05-17.
7. "OCaml - Batch compilation (Ocamlc)" (https://caml.inria.fr/pub/docs/manual-ocaml/comp.ht
ml).
8. oleg-at-okmij.org. "BER MetaOCaml" (http://okmij.org/ftp/ML/MetaOCaml.html). okmij.org.
9. "Messenger.com Now 50% Converted to Reason · Reason" (https://reasonml.github.io/blog/
2017/09/08/messenger-50-reason.html). reasonml.github.io. Retrieved 2018-02-27.
10. "Flow: A Static Type Checker for JavaScript" (https://flow.org/en/). Flow.
11. "Infer static analyzer" (https://fbinfer.com/). Infer.
12. "GitHub - facebook/pyre-check: Performant type-checking for python" (https://github.com/fac
ebook/pyre-check). 9 February 2019 – via GitHub.
13. "WebAssembly/spec: WebAssembly specification, reference interpreter, and test suite" (http
s://github.com/WebAssembly/spec). World Wide Web Consortium. 5 December 2019.
Retrieved 2021-05-14 – via GitHub.
14. "Companies using OCaml" (https://ocaml.org/learn/companies.html). OCaml.org. Retrieved
2021-05-14.
15. "BuckleScript: The 1.0 release has arrived! | Tech at Bloomberg" (https://www.techatbloomb
erg.com/blog/bucklescript-1-0-release-arrived/). Tech at Bloomberg. 8 September 2016.
Retrieved 21 May 2017.
16. Yaron Minsky (1 November 2011). "OCaml for the Masses" (http://cacm.acm.org/magazines/
2011/11/138203-ocaml-for-the-masses/fulltext). Retrieved 2 May 2015.
External links
Official website (https://ocaml.org/)
OCaml manual (http://caml.inria.fr/pub/docs/manual-ocaml/)
OCaml Package Manager (https://opam.ocaml.org/)
Real World OCaml (https://realworldocaml.org)
Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using
this site, you agree to the Terms of Use and Privacy Policy. Wikipedia® is a registered trademark of the Wikimedia
Foundation, Inc., a non-profit organization.