Miranda
David Turner's lazy, purely functional language with polymorphic type inference - the first such language to be sold commercially, and the main model for Haskell.
Created by David Turner (Research Software Ltd, Canterbury, England)
Miranda is a lazy, purely functional programming language designed by David Turner and sold from 1985 by his company, Research Software Ltd of Canterbury, England. It combined three ideas that had previously appeared separately: the non-strict, equational style of Turner’s own SASL and KRC, the algebraic data types of the Edinburgh languages, and Robin Milner’s polymorphic type inference. The result was small, consistent and supported as a commercial product. For the second half of the 1980s Miranda was the most widely used language of its kind. It gave a generation of students its notation for functional programming, and when a committee of researchers set out in 1987 to design a common lazy language, Miranda was the model. That language became Haskell.
History and Origins
From SASL and KRC
Miranda is the third in a line of languages that Turner developed over fifteen years. SASL (St Andrews Static Language) began in 1972-73 as a teaching language at the University of St Andrews. In 1976 it gained multi-equation definitions with pattern matching, an offside rule for layout, and lazy evaluation. After moving to the University of Kent in 1977, Turner reimplemented lazy SASL by compiling it to SK combinators and evaluating them with graph reduction, a technique he published in 1979. KRC (Kent Recursive Calculator, 1980-81) was a smaller version of SASL for teaching. It introduced guards on equations and was the testbed for what Turner called “ZF expressions”. Philip Wadler later named these list comprehensions.
SASL and KRC were both dynamically typed. In his 2012 history of functional programming languages, Turner describes Miranda, developed from 1983 to 1986, as “essentially SASL plus algebraic types and the polymorphic type discipline of Milner (1978)”. It kept SASL’s lack of explicit lambdas and its optional offside rule, both of which Turner traces back to Landin’s ISWIM. Miranda writes type variables as *, **, ***, a convention borrowed from the original LCF version of ML. Turner notes that Standard ML had not yet appeared when he was designing Miranda.
A commercial product
Unusually for a research language, Miranda was a product from the start. Turner founded Research Software Ltd in 1983 to take lazy functional programming with Hindley-Milner typing into the commercial world. The release history recorded in the system’s own manual is:
| Date | Release | Notes |
|---|---|---|
| 1 May 1985 | Alpha test | University of Kent only |
| October 1985 | Beta test (0.292 VAX, 0.293 Sun) | Distributed to 88 sites |
| April 1987 | Release one (1.009 / 1.016 / 1.019) | Literate scripts, %export/%include, (n+k) patterns; around 250 sites |
| October 1989 | Release two (2.0xx) | Unbounded-size integers, %free, faster SK reduction machine; around 550 sites by the mid-1990s |
| May 2006 | 2.032 | Free software, but not open source |
| December 2019 | 2.057 | Open source (BSD licence) |
| January 2020 | 2.064-2.066 | C11 source, 64-bit compatible |
Turner described the language publicly at a Royal Society meeting in February 1984 and at the FPCA conference in Nancy in September 1985. His December 1986 SIGPLAN Notices paper, “An Overview of Miranda”, remained the standard introduction. The implementation was a compiler to an intermediate code based on combinatory logic, run by a fast interpreter written in C for Unix systems. The name, Turner explained, comes from the Latin for “to be wondered at”. It also refers to the heroine of Shakespeare’s The Tempest, who lives on an enchanted island protected from the evils of the world, which “in this context may stand for side effects and other imperative features”. Her line “O brave new world!” stood for the brave new world of functional programming that the language was meant to introduce.
Miranda and Haskell
By 1987 there were many similar lazy functional languages, including Miranda, Lazy ML, Orwell, Alfl, Id and Ponder. At the FPCA conference in Portland, Oregon, in September 1987, a group of researchers agreed to design a common one. According to “A History of Haskell” (Hudak, Hughes, Peyton Jones and Wadler, 2007), Miranda was “by far the most mature” candidate. It was pure, well designed, had a robust implementation and, by their count, was running at 120 sites. (Turner’s own release notes give a figure of around 250 sites for release one, apparently over its whole life, not at the time of the 1987 meeting.) The committee’s first action was to ask Turner whether they could adopt it as their starting point.
Turner declined. The committee wanted a language anyone could extend, modify and implement. Turner was committed to a single standard with complete portability of programs across the Miranda community, and he asked that the new language be distinct enough from Miranda that the two would not be confused. The Haskell authors call this “an important fork in the road”. Starting from scratch let them try more radical designs, and they doubt they would have invented type classes if they had begun with Miranda. Haskell still borrowed heavily from Miranda: equational function definitions with pattern matching and guards, where clauses, algebraic types, list and list-comprehension notation, capitalised data constructors, a layout rule and the names of many standard functions.
Design Philosophy
Miranda is meant to be a simple language. Turner later summed up its advantages over Haskell as a “smaller language, simpler type system, simpler arithmetic”. Its main principles are:
- Purity. Miranda has no side effects and no imperative features. A program, called a script, is a set of equations, and their order does not matter. A name can be used before it is defined.
- Laziness. Expressions are evaluated only when their values are needed. This makes infinite data structures ordinary, and lazy lists replace coroutines and backtracking.
- Static typing without type declarations. Types are inferred. Writing type specifications with
::is optional, though it is encouraged as documentation. - Notation close to mathematics. Function application is written by juxtaposition, definitions are equations, and the condition for each case is written to the right of the equation.
Turner kept the language small on purpose. When the Haskell committee met in January 1988 its stated goal was a language based on ideas that “enjoy a wide consensus”. Turner later argued that type classes, Haskell’s main innovation, went against that goal, even though they proved very fruitful.
Key Features
Equations, guards and layout
Functions are defined by several equations that use pattern matching, with guards (conditions) written after a comma. The if keyword in guards has been required syntax since 1988. Local definitions go in a where clause, and indentation shows scope:
ham = 1 : foldr1 merge [mult 2 ham, mult 3 ham, mult 5 ham]
where
mult n x = [n*a|a<-x]
merge (a:x) (b:y) = a : merge x y, if a=b
= a : merge x (b:y), if a<b
= b : merge (a:x) y, if a>b
This example comes from the Miranda distribution. It defines ham, the infinite, ascending list of Hamming numbers (numbers of the form 2^a·3^b·5^c), in terms of itself. Laziness makes this work: each element is computed only when it is needed.
Comments start with ||. A literate script reverses the convention: every line is commentary unless it begins with >.
List comprehensions and infinite lists
List comprehensions came to Miranda from KRC by way of SASL. With laziness they make many search problems easy to write. The sieve of Eratosthenes appears on Miranda’s own home page:
primes = sieve [2..]
where
sieve (p:x) = p : sieve [n | n<-x ; n mod p > 0]
The 8-queens solver in the distribution’s examples builds the list of every solution instead of backtracking. Qualifiers in a comprehension are separated by semicolons:
queens 0 = [[]]
queens (n+1) = [q:b|b<-queens n;q<-[1..8];safe q b]
safe q b = and[~checks q b i|i<-index b]
checks q b i = q=b!i \/ abs(q-b!i)=i+1
The (n+1) pattern is an (n+k) pattern. Turner added them in 1986 because Richard Bird wanted them for the textbook he was writing with Philip Wadler.
Algebraic and abstract data types
User-defined types are written as type equations in a BNF-like syntax with ::=. Constructors begin with a capital letter and variables with a lower-case letter, so the compiler can tell a pattern match from a function definition:
tree * ::= NILT | NODE * (tree *) (tree *)
treesort = flatten.build
build::[*]->tree *
build = foldr insert NILT
insert b NILT = NODE b NILT NILT
insert b (NODE a x y) = NODE a (insert b x) y, if b<=a
= NODE a x (insert b y), if b>a
flatten::tree *->[*]
flatten NILT = []
flatten (NODE a x y) = flatten x ++ [a] ++ flatten y
Type synonyms use ==, as in string == [char]. Abstract types use abstype ... with, which hides a representation behind a signature:
abstype stack *
with empty::stack *; push::*->stack *->stack *;
pop::stack *->stack *; top::stack *->*; isempty::stack *->bool
stack * == [*]
empty = []
push a x = a:x
pop(a:x) = x
top(a:x) = a
isempty x = (x=[])
Haskell left out abstract types and used its module system for the same job. Early Miranda also allowed algebraic types with laws, which were equations that constructors had to satisfy. Release two declared them obsolete and the 2019 open-source release removed them. Strictness annotations (!) on constructor fields are still part of the language.
One number type
Miranda has a single numeric type, num. It covers unbounded-size integers and double-precision floating point, and converts integers to floats automatically when needed. The other basic types are bool and char. A string is a list of characters. “A History of Haskell” notes the cost of this simplicity: Miranda accepts an expression such as mod 8 3.4 as well typed, where a richer numeric type system would reject it. Equality has a polymorphic type, so comparing two functions type-checks and fails only at run time.
Programming environment and modules
The Miranda system is an interactive environment. You load a script, evaluate expressions at the prompt, and edit with an external editor such as vi. A built-in “make” recompiles object code when the source changes. Scripts can be combined with %include and %export, which keep types checked across module boundaries. Scripts can also be run as Unix commands.
Evolution
The language itself has been essentially fixed since release two in 1989. Later versions changed the implementation, not the language. The 2019 open-source release notes describe it as “Miranda release two of October 1989 rereleased thirty years on as open source - as historical record and in the hope that it may still be useful”.
Miranda’s decline is documented in “A History of Haskell”. Research Software was a small company that needed a return on its capital. Academic licences were cheaper than commercial ones, but neither kind was free, while Haskell implementations were publicly funded and free to everyone. The paper also says Miranda ran only under Unix and that the lack of a Windows version increasingly worked against it. Haskell implementations improved faster: Hugs offered an interactive environment like Miranda’s on both Unix and Windows. Miranda’s licence also required permission before anyone distributed an implementation of a substantially similar language. This caused friction between Oxford University and Research Software over Wadler’s Orwell, though Turner raised no objection to Haskell. By the mid-1990s, the Haskell authors write, Haskell had become the more practical choice.
The implementation lived on. Binary releases for Linux, Solaris, Mac OS X and 32-bit Cygwin on Windows were offered free of charge from 2006. The source was opened in December 2019 and modernised to C11 and 64-bit in January 2020. Turner died in October 2023. Martin Guy then moved maintenance to Codeberg with the blessing of Turner’s family and the University of Kent. The maintainers report that the current source builds on many Unix-like systems and processor architectures, but does not work on Solaris with SPARC sun4u processors, and that a native Windows port has not been attempted. Releases 2.067 (June 2025), 2.068 (August 2026) and 2.069 (October 2026) have kept it building on current compilers and added command-line editing.
Current Relevance
Miranda is listed as historical. The language has not changed since 1989, and Haskell long ago took its place in teaching and research. The implementation is not dead, though: it is open source, maintained, and has a small mailing list. It is still useful for working through the older literature on lazy functional programming, including Bird and Wadler, Thompson, Holyer and Clack, Myers and Poon, and many research papers from the late 1980s and early 1990s. It is also a much smaller system than a modern Haskell toolchain.
No official Docker image exists. The usual route is to build from source: clone the Codeberg repository, run make, and start the interpreter with mira.
Why It Matters
Miranda took lazy, purely functional programming with static polymorphic types out of individual research labs. Hundreds of universities taught it as a supported product with textbooks and a stable definition. Its syntax shaped Haskell so closely that much of what programmers think of as Haskell style, including equations with guards, where clauses, list comprehensions and the layout rule, was already in Miranda. Because Turner refused to let Miranda become the community’s base language, Haskell was designed from scratch, which led to type classes and monadic I/O. “A History of Haskell” concludes that Miranda “was certainly no failure, either commercially or scientifically”: it contributed “a small, elegant language design with a well-supported implementation” and helped spread functional programming through university curricula.
Timeline
Notable Uses & Legacy
University teaching of functional programming
Miranda's main use. Hudak, Hughes, Peyton Jones and Wadler report that by the early 1990s it was installed at around 250 universities and about 50 companies in 20 countries. Courses were built around Bird and Wadler's textbook, Thompson's book from the University of Kent and Clack, Myers and Poon's book from University College London
The 1987 Declarative Programming school, Austin, Texas
In August 1987 the University of Texas at Austin held a meeting on declarative programming as part of its 'Year of Programming'. Its papers were published in 1990 as 'Research Topics in Functional Programming' (Addison-Wesley, edited by Turner). Ham Richards of UT reportedly co-organised it with Turner, and it reportedly included a course in lazy functional programming with practical classes in Miranda, but we have not found a primary source for those two details
Three-dimensional modelling of RNA
'A History of Haskell' names Major and Turcotte's 1991 paper in Science, 'The combination of symbolic and numerical computation for three-dimensional modelling of RNA', as one of the large projects that used Miranda and showed a lazy functional language could do industrial-scale work
Large scientific application (Page and Moe, FPCA 1993)
Page and Moe's FPCA 1993 paper 'Experience with a large scientific application in a functional language' is the second project 'A History of Haskell' cites as large-scale industrial use of Miranda
Starting point for Haskell's design
In 1987 the group that became the Haskell committee asked to adopt Miranda as its base language, calling it 'by far the most mature' of the lazy languages then in development. Turner declined, but Haskell took much of its look and feel from Miranda, including equational definitions with guards, where clauses, list comprehensions and the layout rule