Est. 1980s Intermediate

Amanda

Dick Bruin's free, Miranda-like lazy functional interpreter from the Netherlands, written in ANSI C for MS-DOS and later Windows and kept alive as public-domain source.

Created by Dick Bruin

Paradigm Functional (purely functional, lazy/non-strict, higher-order)
Typing Static, strong, inferred, polymorphic
First Appeared Late 1980s (HOPL dates the design to 1988; the oldest surviving dated sources are from 1998)
Latest Version Amanda V2.05 (Bruin's last version stamp, on a source file dated 20 March 2012); the 2014 public-domain fork on GitHub identifies itself as V3.0

Amanda is a small, free, lazy functional language from the Netherlands: an interpreter written in ANSI C by Dick Bruin that reproduces most of David Turner’s Miranda, adds records and a few conveniences, and asks nothing in return. Bruin built it, in his own words, “for recreational purposes (solving mathematical puzzles)”, and released it with no licence whatsoever - not even a permissive one - requesting only that anyone republishing it note that no rights attach to it and that his name need not be mentioned. Its evident appeal was as a way to run the programs in Bird and Wadler’s textbook on a PC without paying for anything, and the one documented case of that - a Dutch student project - is the reason the source survives at all.

History and Origins

Miranda, first released by Research Software Ltd in 1985 and sold commercially thereafter, was the lazy functional language of the late 1980s: elegant, widely taught, and licensed. Amanda is what happens when someone wants that language on their own machine without the licence. The name looks like the tell - one letter away, and apparently the same Latin gerundive joke (“she who must be loved” against “she who must be admired”) - though Bruin nowhere explains it.

Dating Amanda precisely is difficult, and the honest answer is that nobody has published a firm origin date. The HOPL catalogue records it as designed in 1988 in the Netherlands, which matches the language’s own documentation: the manual notes that “Amanda has been designed with a PC-DOS environment in mind” and that “the awkward memory structure of PC-DOS still leaves traces in Amanda”. The earliest independent trace is the FOLDOC dictionary entry, last updated on 27 April 1998, which describes Amanda as “derived mostly from Miranda with some small changes”, written by Bruin and implemented on MS-DOS and NeXT, “available as an interperator only”. The oldest dated code that survives is the version 2 C source, most of it stamped 24 August 1998, with the Delphi interface unit for the Windows DLL dated 25 October 1998 in the listing reproduced in the manual. Everything before that is inference: the 1988 date rests on a single catalogue entry.

Two books are named in the manual as Amanda’s foundations, and both choices are visible in the result:

  • Richard Bird and Philip Wadler, Introduction to Functional Programming supplies the notation. Amanda’s equational definitions, guards written ,if and ,otherwise, list comprehensions and operator names follow the book so closely that the textbook doubles as the language tutorial.
  • Simon Peyton Jones, The Implementation of Functional Programming Languages supplies the machinery - the graph reduction and lazy evaluation techniques that the C interpreter implements.

Design Philosophy

Amanda is deliberately modest. It is an interpreter only; there is no compiler, no separate module system beyond textual inclusion, and no runtime beyond a heap of cells whose size you set in a configuration file. The console version “acts like an advanced calculator”: you type an expression, it prints the reduced value, and appending :: prints the inferred type instead of the value.

Amanda> 1 + 2
3
Amanda> 1 + 2 ::
num
Amanda> fac 3 where fac 0 = 1; fac n = n * fac (n-1)
6
Amanda> load "test.ama"

The three restrictions the manual lists are equally candid about its scale: a global function definition may not exceed 4000 cells, the internal stack is “rather small”, and patterns may nest at most 32 levels deep. This is a teaching and puzzle-solving tool, not an industrial compiler, and it never pretends otherwise.

Where the manual is unusual is in telling you where laziness will hurt. It works through the classic prime sieve

primes = sieve [2..]
sieve (x:xs) = x : sieve [y | y <- xs; y % x ~= 0]

and explains that this version exhausts memory, because reaching x keeps a reference to the whole list (x:xs) alive; the fix is to bind x = hd l and xs = tl l in a where clause. A second worked example shows a character-frequency table blowing up under accumulated closures and repairs it with seq. Few small language manuals are that honest about their own evaluation model.

Key Features

A Miranda-shaped core. Functions are defined by equations with pattern matching and guards, with where clauses for local definitions:

mergeSort list
= list ,if half < 1
= merge (mergeSort (take half list)) (mergeSort (drop half list))
where
  half = (# list) / 2

Layout matters in a particular way: in a multi-clause definition the = signs must line up exactly under each other.

A single numeric type. num covers both integers and reals; the other basic types are bool and char, with strings as lists of characters, as in Miranda.

Polymorphic type inference with algebraic types. Types are inferred, never required, and can be declared with ::. Algebraic types use ::=:

tree * ::= Leaf * | Branch (tree *) (tree *)

Records - a genuine departure from Miranda. Amanda adds record types with named fields, selector functions generated per field, partial record literals usable in patterns, and an & operator that updates a record from another:

vector * ::= { x :: *, y :: *, z :: * }

innerproduct { x=x1, y=y1, z=z1 } { x=x2, y=y2, z=z2 } = x1*x2 + y1*y2 + z1*z2

The stated drawback is that field names must be unique across all record types in scope.

Abstract types. abstype ... with hides a representation behind a signature, in the Miranda style, with the restriction that an abstract type must be a synonym of an existing type:

abstype stack *
with
  push    :: * -> stack * -> stack *
  pop     :: stack * -> stack *
  top     :: stack * -> *
  isEmpty :: stack * -> bool
  create  :: stack *

stack * == [*]

A C-style preprocessor. #import textually includes another file (tracking imports so repeated or recursive includes are harmless), #synonym renames anything including operators and even keywords such as where, and #operator introduces new operators.

Pattern restrictions with a reason. Repeated variables in a left-hand side are rejected, (n+1) patterns are not supported, and overlapping clause patterns are flagged as a mistake rather than silently resolved - the manual spells out counterexamples for each.

Operators from the textbook. ~= for inequality, /\ and \/ for conjunction and disjunction, # for length, ++ and -- for list append and difference, . for composition, ! for indexing, & for record update.

Evolution

Amanda’s development happened in one visible burst and then a long quiet tail. The dated headers in the C source cluster in the late summer and autumn of 1998 - fifteen files carry 24 August 1998 - with revisions running through 1999 and into September 2000; the type checker and parser reached 2.02 in that window and the manual that ships with the sources describes V2.05. In the same period the language grew a Windows personality distinct from the portable core.

The Windows distribution consisted of ama.exe (console), amanda.exe (GUI), amadll.dll (the interpreter kernel as a DLL), amanda.ini and a help file. Two features only exist there:

  • Remote objects. An Amanda script can declare object "primes" = (state, call), defining named methods and a state-transforming call function. A host program - the manual’s example is Delphi, using a TAmaObject class with Create, Put, Call and Get - drives it from the outside. It is an unusually direct way of embedding a lazy infinite stream into an imperative application.
  • AmaGr graphics. A separate front end loads an Amanda file containing an interaction object, forwards user events to it, and paints the list of drawing commands it returns. The bundled programs include Life, Tetris, a robot simulation, spline and curve plotting and an NFA-to-DFA converter.

The only later change traceable to Bruin is a 20 March 2012 stamp on the type checker, carrying version 2.05. Two years after that, on 17 April 2014, the “completely barebones version of Amanda as provided by Dick Bruin” was pushed to GitHub - the Java GUI stripped out, an Unlicense applied, and the build reworked so make produces a working interpreter on Linux, macOS and Windows (the latter via MinGW, including cross-compilation). Students at NHL Hogeschool worked on it for three months that spring, in two teams of roughly four; the final commit is dated 18 June 2014. Their build announces itself as “Amanda V3.0” and the Debian package they left behind is versioned 3.0-1, so the version number a user sees today is the students’, not Bruin’s 2.05.

Current Relevance

Amanda today is a historical artifact that still builds. The public-domain C sources still compile with a modern toolchain - a plain make against Apple’s current clang produces a working interpreter, with two narrowing warnings and no errors - the V2.05 manual is complete and readable, and the sample programs run. What there is not is a community: the GitHub repository has single-digit stars, the last substantive commit is from mid-2014, and no distribution packages it. FOLDOC’s entry has not been touched since 1998.

Its niche - a free lazy functional language for teaching - has long since been filled. Haskell became the standard vehicle for the material Amanda was built to support, and Miranda itself, the language Amanda existed to route around, was released as open source by Turner in release 2.057, dated 8 December 2019 in its ChangeLog, which retired the original motivation altogether.

Why It Matters

Amanda is a small, clear example of a pattern that recurs throughout language history: when a good language is locked behind a licence, someone reimplements it. Amanda did not innovate, and did not try to; it took Miranda’s design, added records, wrote it in portable ANSI C, and gave it away without even asking for attribution. For students who wanted to type the programs from Bird and Wadler into a PC, that was the whole point.

It is also a useful object lesson in dating obscure software. A catalogue says 1988, a dictionary entry says 1998, and the code says August 1998 onwards - and the correct answer is to report all three rather than pick one. The language’s own manual, apologising for the memory model of PC-DOS while explaining how lazy evaluation leaks space, preserves a particular moment in the spread of functional programming better than any release note could.

Timeline

1988
The HOPL catalogue records Amanda as designed in 1988 in the Netherlands by Dick Bruin. This date is not corroborated by any dated artifact that survives, so treat it as approximate; the manual's remark that Amanda 'has been designed with a PC-DOS environment in mind' is consistent with a late-1980s or early-1990s start
1998
FOLDOC's Amanda entry, last updated 27 April 1998, describes it as 'a functional programming language derived mostly from Miranda with some small changes', written by Dick Bruin and implemented on MS-DOS and NeXT, available as an interpreter only
1998
Most of the version 2 C sources carry header dates of 24 August 1998, with further files dated through September, October and November 1998 - the oldest firmly dated Amanda code that survives
1998
The Windows implementation takes shape: AmaDllUnit.pas, the Delphi interface to the amadll.dll interpreter kernel, is dated 25 October 1998. It lets Windows programs create and call Amanda 'remote objects'
1999
Type checker, parser, lexer and printer files are revised (headers dated 26 October, 19 December and 26 December 1999), the versions in which the type checker reached 2.02
2000
Further dated revisions (4 May and 25 September 2000) round out the 2.0x interpreter, distributed for Windows as ama.exe (console), amanda.exe (GUI), amadll.dll, amanda.ini and a help file
2012
The type checker source amcheck.c receives a second date stamp, 20 March 2012, alongside the version marking 2.05 - the newest change traceable to Bruin himself
2012
Amanda surfaces in public code: a functional implementation of the Go board game is published on GitHub in June 2012, and a C#/.NET editor front end built around Bruin's C interpreter is started there in April 2013
2014
On 17 April 2014 the 'completely barebones version of Amanda as provided by Dick Bruin' is pushed to GitHub. Bruin released it under no licence at all, asking only that republishers note no rights attach to it; the fork adds an Unlicense, drops the Java GUI and builds on Linux, macOS and Windows
2014
Two student teams of roughly four members each at NHL Hogeschool work on the interpreter for three months, one on the core and one on additional functionality. The last commit lands on 18 June 2014, after which the repository goes quiet

Notable Uses & Legacy

NHL Hogeschool student project (2014)

Two teams of about four students each spent three months modernising the Amanda interpreter - one team on the core, one on extra functionality - producing the portable Linux/macOS/Windows build and the Debian packaging that the public repository still carries

AmaGr graphics demonstrations

The distribution ships Amanda programs driven by the AmaGr graphical front end, including Conway's Life, Tetris, a robot simulation, spline and curve plotting, a convex hull and an NFA-to-DFA converter, all written as interaction objects that return lists of drawing commands

Delphi and Windows application embedding

amadll.dll exposes the interpreter to other Windows programs through the TAmaObject class, so a Delphi application could call named Amanda objects with Put/Call/Get and use a lazy functional kernel (the manual's example is an infinite stream of primes) as a component

Go board game in Amanda (2012)

A GitHub project implements the board game Go functionally in Amanda, one of the few third-party Amanda programs published outside the distribution itself

C#/.NET editor front end (2013)

An independent GitHub project wrapped Bruin's C interpreter as a native AmandaCore library and drove it from an AmandaInterface GUI written in C# for .NET/Mono, with a syntax-highlighting editor component - one of the few attempts to give Amanda a modern IDE

Language Influence

Influenced By

Miranda

Running Today

Run examples using the official Docker image:

docker pull
Last updated: