Mercury is a purely declarative logical/functional language. It features a strong, static, polymorphic type system, as well as a strong mode and determinism systems. The type system is similar to that of Haskell, while the syntax is derived from Prolog's.
The Mercury Project
Mercury is a purely declarative logical/functional programming language. It is a very high-level language that allows programmers to concentrate on the problem rather than the low-level details such as memory management. Unlike other high-level languages Mercury is designed for the construction of large, reliable, efficient software systems by teams of programmers. As a consequence, programming in Mercury has a different feel than programming in most other high-level languages.
Main Features
Mercury has several key features that give it its unique, although familiar (to Prolog programmers) flavour. For more details, consult the introductory documentation.
Purely declarative
Predicates and functions in Mercury do not have non-logical side effects. I/O is performed by library predicates that take an old state of the world and some other parameters, and return a new state of the world and possibly some other results. Haskell uses monads to ensure purity of I/O operations, Mercury does not require the use of Monads.
Strongly typed
Mercury's type system is based on many-sorted logic with parametric polymorphism, very similar to the type systems of modern functional languages such as ML and Haskell. Programmers must declare the types they need using declarations such as
:- type list(T)
---> []
; [T | list(T)].
:- type maybe(T)
---> yes(T)
; no.
Programmers should declare the type signatures of the predicates they define, for example
:- pred append(list(T), list(T), list(T)).
The compiler infers the types of all variables for which there is no declaration in the program. Type errors are reported at compile time.
Strongly moded
The programmer should declare the mode of each parameter of a predicate. A parameter's mode describes the instantiation state change of a variable that is passed as an argument to a predicate. A predicate may have more than one mode. For example, append is usually used in at least these two modes:
:- mode append(in, in, out).
:- mode append(out, out, in).
in
modes are input to the predicate. A variable passed as an in
argument is ground before and after the call. out
modes are output from the predicate, a variable passed as an out
argument is free before the call but ground after the call.
If a predicate has only one mode, the mode information can be given in the predicate declaration.
:- pred factorial(int::in, int::out).
Strong determinism
For each mode of each predicate, the programmer should declare whether the predicate will succeed exactly once (det), at most once (semidet), at least once (multi) or an arbitrary number of times (nondet). These declarations are attached to mode declarations like this:
:- mode append(in, in, out) is det.
:- mode append(out, out, in) is multi.
:- pred factorial(int::in, int::out) is det.
A module system
Programs consist of one or more modules. Each module has an interface section that contains the declarations for the types, functions and predicates exported from the module, and an implementation section that contains the definitions of the exported entities and also definitions for types and predicates that are local to the module.
Higher-order programming
Mercury allows programming with closures, currying, and lambda expressions.
Strong error checking
The type, mode and determinism systems require the programmer to make assertions about their programs. These assertions are checked by the compiler, this can make various common programming errors impossible. For example, a pure Mercury program (a program containing only Mercury code) can never dereference a NULL pointer.
Very efficient
In comparison with existing logic programming languages, strong types, modes, and determinism provide the compiler with the information it needs to generate very efficient code.
Multiple back-ends
Mercury can compile to high-level C, low-level C (using C effectively as a portable assembler). It can also compile to Java, to C# and to Erlang, providing full FFI facilities in all supported targets.
Community
Mercury's home page, "The Mercury Project", is the hub of the community. From there you can find the documentation, access the mailing lists) (as well as their archives) and access the bug tracker. There is also an IRC channel, although it can be a little slow on the response times. (The Mercury community is not large, but it is friendly and helpful when it connects.)