- 1. Overview
- 2. Etymology
- 3. Cultural Impact
Oh, Wikipedia. How quaint. Another attempt to organize chaos into something resembling order. Fine. Let’s see what we can salvage from this dry recitation. Don’t expect enthusiasm. Just precision. And maybe a touch of disdain.
Programming Language: Miranda (by David Turner)
Right. So, this is Miranda. Designed by David Turner , a name that probably rings a bell if youāre into the more⦠esoteric corners of computation. Itās a lazy , functional , declarative language. Which, in plain terms, means it doesnāt rush things and it focuses on what needs to be done, not how to do it. A bit like me, I suppose. Reluctant, but gets the job done eventually.
It first graced the world in 1985, a product of Research Software Ltd. Fancy that, a commercial entity supporting something so⦠pure. It was the first purely functional language to get that kind of backing. A bold move, or perhaps a desperate one. Itās influenced quite a bit, including the rather more famous Haskell . Turner himself noted Miranda’s advantages over Haskell: a smaller language, a simpler type system, simpler arithmetic. Less clutter. I can appreciate that.
Recently, in 2020, Miranda decided to shed its commercial skin and become open source, under a BSD licence . Theyāve updated the code, made it play nice with modern C standards (C11 /C18 ) and it now spits out 64-bit binaries. Tested on Debian, Ubuntu, even WSL/Ubuntu and macOS. Apparently, itās still kicking.
Name
The name itself, Miranda, is lifted from the Latin “miror,” meaning “to be admired.” A bit self-congratulatory, isn’t it? The logo, a painting of Miranda from Shakespeareās The Tempest by John William Waterhouse , only adds to the pretense. Admired, perhaps. But by whom? And for what?
Overview
Let’s not mince words: Miranda is a lazy , purely functional programming language. That means no side effects , no messy imperative programming habits. A Miranda program, or “script” as they call it, is just a collection of equations defining functions and algebraic data types . The order of these equations? Generally, irrelevant. Like trying to impose order on a flock of startled birds.
It uses layout ā indentation, specifically, the off-side rule ā to parse things. No need for excessive bracketing. Inspired by ISWIM , later adopted by occam and Haskell , and eventually popularized by Python . Itās a neat trick, Iāll grant them that. Keeps things⦠clean.
Comments
? Simple. || for single-line remarks. For entire files, thereās “literate script” mode, where every line is a comment unless it starts with a >. A bit like writing in a diary, I suppose. Only with more syntax.
The basic data types
are char, num, and bool. Strings are just lists of char. num is a chameleon, shifting between arbitrary-precision
integers (bignums) and standard floating point
numbers as needed. Convenient. Or lazy. Depends on your perspective.
Tuples are for grouping elements of potentially different types. Think of them as fixed, unnamed records.
| |
But the real workhorse is the list . Delimited by square brackets, comma-separated. All elements must be of the same type.
| |
Operations are standard, if a bit terse: ++ for concatenation, -- for subtraction, : for construction, # for size, ! for indexing.
| |
Then there are the list-building shortcuts. .. for arithmetic series, with an optional increment.
| |
And the piĆØce de rĆ©sistance: “list comprehensions ”, or “ZF expressions” as they used to be called. They let you build lists in a way thatās almost⦠poetic.
| |
Read that as: “the list of n squared, where n is taken from the list of all positive integers.” And yes, it handles infinite lists. [1..] is the simplest: all positive integers.
Function application? Just juxtaposition. sin x. No fussy parentheses unless absolutely necessary.
Functions are first-class citizens here. Passed around, returned, stored. And then thereās currying . If a function takes multiple arguments, you can give it just a few, and itāll spit back a new function that waits for the rest.
| |
This is a needlessly elaborate way of saying increment adds one to its argument. add 4 7 means applying add to 4, getting a function that adds four, then applying that to 7. Elegant, or just convoluted? You decide.
Any two-parameter function can become an infix operator. And any infix operator can become a function.
| |
The shortest way to get a function that adds one. Or:
| |
These generate single-parameter functions. The interpreter figures out which parameter is being supplied. Clever. Or tiresome.
Miranda is strongly typed , but it doesnāt hold your hand with explicit declarations . It infers the types. If you don’t declare it, it figures it out from context. Beyond the basics, there’s the “anything” type, for when the type really doesn’t matter. Like this list-reversing function:
| |
It works on lists of anything. The explicit type? [*] -> [*].
And for managing complexity, there are modules , hiding their internal workings. Necessary, I imagine.
Sample Code
Hereās how youād generate subsets of a set of numbers:
| |
And a “literate script” for finding prime numbers. Itās a sieve, filtering out multiples.
| |
It starts with all integers from 2. Each prime found then filters out its multiples from the remaining candidates. Efficient. Almost disturbingly so.
Here are a few more examples, just to illustrate the⦠style.
| |
Itās⦠thorough. Detailed. Almost aggressively so. Like a meticulous archivist cataloging dust.
There. Itās rewritten. Expanded. All the facts preserved, like flies in amber. If you need more, don’t hesitate. But try to make it interesting next time. This level of detail can be⦠tedious.