Miranda is a
lazy,
purely functional programming language
A programming language is a system of notation for writing computer programs.
Programming languages are described in terms of their Syntax (programming languages), syntax (form) and semantics (computer science), semantics (meaning), usually def ...
designed by
David Turner as a successor to his earlier programming languages
SASL and
KRC, using some concepts from
ML and
Hope
Hope is an optimistic state of mind that is based on an expectation of positive outcomes with respect to events and circumstances in one's own life, or the world at large.
As a verb, Merriam-Webster defines ''hope'' as "to expect with confid ...
. It was produced by Research Software Ltd. of England (which holds a trademark on the name ''Miranda'') and was the first purely functional language to be commercially supported.
Miranda was first released in 1985 as a fast interpreter in
C for
Unix
Unix (, ; trademarked as UNIX) is a family of multitasking, multi-user computer operating systems that derive from the original AT&T Unix, whose development started in 1969 at the Bell Labs research center by Ken Thompson, Dennis Ritchie, a ...
-flavour operating systems, with subsequent releases in 1987 and 1989. It had a strong influence on the later
Haskell
Haskell () is a general-purpose, statically typed, purely functional programming language with type inference and lazy evaluation. Designed for teaching, research, and industrial applications, Haskell pioneered several programming language ...
language. Turner stated that the benefits of Miranda over Haskell are: "Smaller language, simpler type system, simpler arithmetic".
[
In 2020 a version of Miranda was released as open source under a BSD licence. The code has been updated to conform to modern C standards ( C11/ C18) and to generate 64-bit binaries. This has been tested on operating systems including ]Debian
Debian () is a free and open-source software, free and open source Linux distribution, developed by the Debian Project, which was established by Ian Murdock in August 1993. Debian is one of the oldest operating systems based on the Linux kerne ...
, Ubuntu
Ubuntu ( ) is a Linux distribution based on Debian and composed primarily of free and open-source software. Developed by the British company Canonical (company), Canonical and a community of contributors under a Meritocracy, meritocratic gover ...
, WSL/Ubuntu, and macOS
macOS, previously OS X and originally Mac OS X, is a Unix, Unix-based operating system developed and marketed by Apple Inc., Apple since 2001. It is the current operating system for Apple's Mac (computer), Mac computers. With ...
( Catalina).
Name
The name ''Miranda'' is taken from the gerundive form of the latin verb , meaning "to be admired".
The logo features a rendition by John William Waterhouse
John William Waterhouse (baptised 6 April 184910 February 1917) was an English painter known for working first in the Academic style and for then embracing the Pre-Raphaelite Brotherhood's style and subject matter. His paintings are known for ...
of the character Miranda from Shakespeare's ''The Tempest''.
Overview
Miranda is a lazy, purely functional programming language. That is, it lacks side effect
In medicine, a side effect is an effect of the use of a medicinal drug or other treatment, usually adverse but sometimes beneficial, that is unintended. Herbal and traditional medicines also have side effects.
A drug or procedure usually use ...
s and imperative programming
In computer science, imperative programming is a programming paradigm of software that uses Statement (computer science), statements that change a program's state (computer science), state. In much the same way that the imperative mood in natural ...
features. A Miranda program (called a ''script'') is a set of equation
In mathematics, an equation is a mathematical formula that expresses the equality of two expressions, by connecting them with the equals sign . The word ''equation'' and its cognates in other languages may have subtly different meanings; for ...
s that define various mathematical functions and algebraic data type
In computer programming, especially functional programming and type theory, an algebraic data type (ADT) is a kind of composite data type, i.e., a data type formed by combining other types.
Two common classes of algebraic types are product ty ...
s. The word ''set
Set, The Set, SET or SETS may refer to:
Science, technology, and mathematics Mathematics
*Set (mathematics), a collection of elements
*Category of sets, the category whose objects and morphisms are sets and total functions, respectively
Electro ...
'' is important here: the order of the equations is, in general, irrelevant, and there is no need to define an entity prior to its use.
Since the parsing
Parsing, syntax analysis, or syntactic analysis is a process of analyzing a String (computer science), string of Symbol (formal), symbols, either in natural language, computer languages or data structures, conforming to the rules of a formal gramm ...
algorithm makes intelligent use of layout (indentation, via off-side rule
The off-side rule describes syntax of a computer programming language that defines the bounds of a code block via indentation.
The term was coined by Peter Landin, possibly as a pun on the offside law in association football.
An off-side ...
), bracketing statements are rarely needed and statement terminators are unneeded. This feature, inspired by ISWIM, is also used in occam and Haskell
Haskell () is a general-purpose, statically typed, purely functional programming language with type inference and lazy evaluation. Designed for teaching, research, and industrial applications, Haskell pioneered several programming language ...
and was later popularized by Python.
Commentary is introduced into regular scripts by the characters , ,
and continue to the end of the same line. An alternative commenting convention affects an entire source code file, known as a " literate script", in which every line is considered a comment unless it starts with a >
sign.
Miranda's basic data type
In computer science and computer programming, a data type (or simply type) is a collection or grouping of data values, usually specified by a set of possible values, a set of allowed operations on these values, and/or a representation of these ...
s are char
, num
and bool
. A character string is simply a list of char
, while num
is silently converted between two underlying forms: arbitrary-precision integers (a.k.a. bignums) by default, and regular floating point
In computing, floating-point arithmetic (FP) is arithmetic on subsets of real numbers formed by a ''significand'' (a signed sequence of a fixed number of digits in some base) multiplied by an integer power of that base.
Numbers of this form ...
values as required.
Tuple
In mathematics, a tuple is a finite sequence or ''ordered list'' of numbers or, more generally, mathematical objects, which are called the ''elements'' of the tuple. An -tuple is a tuple of elements, where is a non-negative integer. There is o ...
s are sequences of elements of potentially mixed types, analogous to records in Pascal-like languages, and are written delimited with parentheses:
this_employee = ("Folland, Mary", 10560, False, 35)
The ''list
A list is a Set (mathematics), set of discrete items of information collected and set forth in some format for utility, entertainment, or other purposes. A list may be memorialized in any number of ways, including existing only in the mind of t ...
'' instead is the most commonly used data structure in Miranda. It is written delimited by square brackets and with comma-separated elements, all of which must be of the same type:
week_days = Mon","Tue","Wed","Thur","Fri"
List concatenation is ++
, subtraction is --
, construction is :
, sizing is #
and indexing is !
, so:
days = week_days ++ Sat","Sun" days = "Nil":days
days!0
⇒ "Nil"
days = days -- Nil" #days
⇒ 7
There are several list-building shortcuts: ..
is used for lists whose elements form an arithmetic series, with the possibility for specifying an increment other than 1:
fac n = product ..n odd_sum = sum ,3..100
More general and powerful list-building facilities are provided by "list comprehension
A list comprehension is a syntactic construct available in some programming languages for creating a list based on existing lists. It follows the form of the mathematical '' set-builder notation'' (''set comprehension'') as distinct from the use o ...
s" (previously known as "ZF expressions"), which come in two main forms: an expression applied to a series of terms, e.g.:
squares = n <- ">..
(which is read: list of n squared where n is taken from the list of all positive integers) and a series where each term is a function of the previous one, e.g.:
powers_of_2 = n <- 1, 2*n ..
As these two examples imply, Miranda allows for lists with an infinite number of elements, of which the simplest is the list of all positive integers: ../code>
The notation for function application is simply juxtaposition, as in sin x
.
In Miranda, as in most other purely functional languages, functions are first-class citizens, which is to say that they can be passed as arguments
An argument is a series of sentences, statements, or propositions some of which are called premises and one is the conclusion. The purpose of an argument is to give reasons for one's conclusion via justification, explanation, and/or persua ...
to other functions, returned as results, or included as elements of data structures. What is more, a function with two or more parameters may be "partially parameterised", or curried, by supplying fewer arguments than the full number of parameters. This gives another function which, given the remaining parameters, will return a result. For example:
add a b = a + b
increment = add 1
is a roundabout way of creating a function "increment" which adds one to its argument. In reality, add 4 7
takes the two-parameter function add
, applies it to 4
obtaining a single-parameter function that adds four to its argument, then applies that to 7
.
Any function with two parameters (operands) can be turned into an infix operator (for example, given the definition of the add
function above, the term $add
is in every way equivalent to the +
operator) and every infix operator taking two parameters can be turned into a corresponding function.
Thus:
increment = (+) 1
is the briefest way to create a function that adds one to its argument. Similarly, in
half = (/ 2)
reciprocal = (1 /)
two single-parameter functions are generated. The interpreter understands in each case which of the divide operator's two parameters is being supplied, giving functions which respectively divide a number by two and return its reciprocal.
Although Miranda is a strongly typed programming language, it does not insist on explicit type declarations. If a function's type is not explicitly declared, the interpreter infer
Inferences are steps in logical reasoning, moving from premises to logical consequences; etymologically, the word '' infer'' means to "carry forward". Inference is theoretically traditionally divided into deduction and induction, a distinctio ...
s it from the type of its parameters and how they are used within the function. In addition to the basic types (char
, num
, bool
), it includes an "anything" type where the type of a parameter does not matter, as in the list-reversing function:
rev [] = []
rev (a:x) = rev x ++ [a]
which can be applied to a list of any data type, for which the explicit function type declaration would be:
rev :: ->
Finally, it has mechanisms for creating and managing program modules whose internal functions are invisible to programs calling those modules.
Sample code
The following Miranda script determines the set of all subsets of a set of numbers
subsets [] =
subsets (x:xs) = x] ++ y , y <- ys] ++ ys
where ys = subsets xs
and this is a literate script for a function primes
which gives the list of all prime numbers
> , , The infinite list of all prime numbers.
The list of potential prime numbers starts as all integers from 2 onwards;
as each prime is returned, all the following numbers that can exactly be
divided by it are filtered out of the list of candidates.
> primes = sieve ..> sieve (p:x) = p : sieve n <- x; n mod p ~= 0
Here, we have some more examples
max2 :: num -> num -> num
max2 a b = a, if a>b
= b, otherwise
max3 :: num -> num -> num -> num
max3 a b c = max2 (max2 a b) (max2 a c)
multiply :: num -> num -> num
multiply 0 b = 0
multiply a b = b + (multiply (a-1) b)
fak :: num -> num
fak 0 = 1
fak n = n * fak (n-1)
itemnumber:: >num
itemnumber [] = 0
itemnumber (a:x) = 1 + itemnumber x
weekday::= Mo, Tu, We, Th, Fr, Sa, Su
isWorkDay :: weekday -> bool
isWorkDay Sa = False
isWorkDay Su = False
isWorkDay anyday = True
tree * ::= E, N (tree *) * (tree *)
nodecount :: tree * -> num
nodecount E = 0
nodecount (N l w r) = nodecount l + 1 + nodecount r
emptycount :: tree * -> num
emptycount E = 1
emptycount (N l w r) = emptycount l + emptycount r
treeExample = N ( N (N E 1 E) 3 (N E 4 E)) 5 (N (N E 6 E) 8 (N E 9 E))
weekdayTree = N ( N (N E Mo E) Tu (N E We E)) Th (N (N E Fr E) Sa (N E Su))
insert :: * -> stree * -> stree *
insert x E = N E x E
insert x (N l w E) = N l w x
insert x (N E w r) = N x w r
insert x (N l w r) = insert x l , if x -> tree *
list2searchtree [] = E
list2searchtree [x] = N E x E
list2searchtree (x:xs) = insert x (list2searchtree xs)
maxel :: tree * -> *
maxel E = error "empty"
maxel (N l w E) = w
maxel (N l w r) = maxel r
minel :: tree * -> *
minel E = error "empty"
minel (N E w r) = w
minel (N l w r) = minel l
, , Traversing: going through values of tree, putting them in list
preorder,inorder,postorder :: tree * -> inorder E = []
inorder N l w r = inorder l ++ [w] ++ inorder r
preorder E = []
preorder N l w r = [w] ++ preorder l ++ preorder r
postorder E = []
postorder N l w r = postorder l ++ postorder r ++ [w]
height :: tree * -> num
height E = 0
height (N l w r) = 1 + max2 (height l) (height r)
amount :: num -> num
amount x = x ,if x >= 0
amount x = x*(-1), otherwise
and :: bool -> bool -> bool
and True True = True
and x y = False
, , A AVL-Tree is a tree where the difference between the child nodes is not higher than 1
, , i still have to test this
isAvl :: tree * -> bool
isAvl E = True
isAvl (N l w r) = and (isAvl l) (isAvl r), if amount ((nodecount l) - (nodecount r)) < 2
= False, otherwise
delete :: * -> tree * -> tree *
delete x E = E
delete x (N E x E) = E
delete x (N E x r) = N E (minel r) (delete (minel r) r)
delete x (N l x r) = N (delete (maxel l) l) (maxel l) r
delete x (N l w r) = N (delete x l) w (delete x r)
References
External links
*
The currently maintained open source version
of Professor Turner's interpreter for Miranda.
The infinite precision math library
a large example of programming in Miranda (and Haskell).
{{Authority control
Declarative programming languages
Functional languages
History of computing in the United Kingdom
Programming languages created in 1985