Est. 1991 Intermediate

Gofer

Mark P. Jones's small, portable Haskell-like interpreter from Oxford - a favourite teaching system of the early 1990s and the testbed where constructor classes, multi-parameter type classes and do-notation were first implemented.

Created by Mark P. Jones

Paradigm Functional (purely functional, lazy/non-strict, higher-order)
Typing Static, strong, inferred, polymorphic with type classes and constructor classes
First Appeared 1991 (version 2.20, announced August 1991 and distributed in September)
Latest Version Gofer 2.30b (final release; interpreter banner reads Copyright 1991-1995)

Gofer is a lazy, purely functional programming language and interactive environment created by Mark P. Jones, first released in 1991 while he was a doctoral student at the University of Oxford. It implemented a large subset of Haskell (initially Haskell 1.1, later based on the Haskell 1.2 report), and it was small enough to run on an ordinary MS-DOS PC at a time when the full Haskell compilers needed workstation-class memory and disk. That made it a popular teaching system for several years. It also mattered for language design: Jones used Gofer as the testbed for his type-class research, and several of its experiments, most notably constructor classes (the mechanism behind Haskell’s Functor and Monad classes) and do-notation, went into standard Haskell. In 1995 Gofer was succeeded by Hugs, the “Haskell User’s Gofer System”, which was built from a rewrite of the Gofer code base.

History & Origins

From Orwell to equational reasoning

Jones first met lazy functional programming through Orwell, the language Philip Wadler developed at Oxford’s Programming Research Group. What attracted him, he later wrote in the Gofer 2.28 release notes, was equational reasoning: proving properties of programs by rewriting them step by step. Doing this by hand was tedious and error-prone, so in 1989 he wrote eqr, a crude tool for machine-assisted equational reasoning.

That gave Gofer its name, a backronym for GOod For Equational Reasoning. Jones admitted he had not realised that “gofer” is also English for someone who runs errands, and that he would have used a lower-case “g” if he had. He also asked users to spell it with an “f”, to keep it from being confused with the Internet Gopher information system.

Versions 1.xx and 2.xx

Jones’s own history, included with the 2.28 release, describes the early versions:

  • Gofer 1.xx (1990) was meant to support typed equational reasoning. It used Orwell syntax plus Haskell-style type classes and had a lexer, parser, type checker and a simple interactive loop. It could not run programs.
  • Gofer 2.xx (from January 1991) was a complete rewrite. In February 1991 Jones came up with a new way to implement type classes that builds every dictionary before evaluation begins, and the project’s focus moved from deriving programs to running them. By around May he realised he “had something that might be useful to other people.”
  • Gofer 2.20 was announced in August 1991 and distributed in September. It was the first public release.

Gofer was written in C. According to the History of Haskell paper (HOPL III, 2007), whose Gofer section was largely written by Jones, it was developed on an 8 MHz 8086 PC with 640 KB of memory and was small enough to fit on a single 360 KB floppy disk. The 2.20 user guide says it was built with Borland’s Turbo C 1.5 and a public-domain yacc. Jones wrote it as a side project to his D.Phil. and reportedly did not tell his thesis adviser about it until it was essentially finished.

Yale and the later releases

Jones took a post-doctoral position at Yale in 1992 and kept developing Gofer there:

VersionDateHighlights
2.20Aug/Sep 1991First public release
2.21Nov 1991Better user interface, command-line options, bug fixes
2.23Aug 1992Bug-fix release
2.28Jan 1993Constructor classes, monad comprehensions, gofc Gofer-to-C compiler
2.30 / 2.30a1994Haskell arrays, monadic I/O, do-notation, external C calls
2.30bc. 1995Final release

Version 2.28 jumped past 2.24 to 2.27, which were internal steps. Jones used them to merge separate development branches back together: the compiler, and a constructor-class prototype called “ccgofer”.

Hugs takes over

After leaving Yale in summer 1994, Jones rewrote the Gofer code base to track the Haskell standard much more closely. The rewrite was briefly called “Hg” (Haskell-gofer) and then renamed Hugs. He announced it on 14 February 1995 with the greeting “Hugs on Valentine’s Day!” Hugs 1.0 supported almost all of Haskell 1.2, including derived instances, defaults, overloaded numeric literals and bignums, several of which Gofer had never implemented. The module system was still missing. From then on Hugs, not Gofer, was the actively developed system.

Design Philosophy

Jones always said Gofer was not a rival to Haskell. He described the gap between Gofer and the full Haskell systems as “quite large” and hoped Gofer would move closer to Haskell over time. Gofer had two jobs:

  1. Be small and interactive. Gofer was an interpreter with a read-evaluate-print loop. It loaded scripts quickly and gave immediate feedback, so it suited students working on their own PCs.
  2. Be a research vehicle. The 2.30a README calls Gofer “an experimental language, particularly where type classes are involved”. Its extensions to the type system came out of Jones’s research on qualified types, the subject of his thesis, which Cambridge University Press published in 1994.

Jones meant the name “Gofer” for the implementation and wanted the language itself to stay anonymous. As he put it, “common usage has given it the same name.”

Key Features

The README for Gofer 2.30a lists the system’s features:

  • Lazy evaluation, higher-order functions and pattern matching
  • Haskell 1.2 expression and pattern syntax, including lambdas, case, let, list comprehensions, operator sections, and as, wildcard and irrefutable patterns
  • A polymorphic type system with overloading through type classes
  • Partial support for Haskell 1.2 I/O, enough for simple interactive programs and for reading and writing text files
  • Constructor classes and overloaded monad comprehensions
  • A “simple minded” Gofer-to-C translator with a runtime system, for building standalone programs
  • Source code, documentation and sample programs, all freely available

Beyond Haskell’s type classes

The 2.30a README lists these departures from Haskell 1.2:

  • Multi-parameter type classes. The History of Haskell paper calls Gofer’s 1991 release the first implementation of them. The Haskell committee chose not to include them at the time.
  • Instances at arbitrary non-overlapping types, not only at a type constructor applied to type variables
  • Contexts that may contain arbitrary type expressions, not only type variables
  • A different dictionary strategy. All dictionaries are built before evaluation starts, which avoids rebuilding them and lets overloaded constants be shared.

These choices meant some Haskell programs would not run under Gofer and some Gofer programs would not run under Haskell.

Missing Haskell features

The same README lists the most significant Haskell features Gofer did not support: modules, overloaded numeric constants, default declarations and derived instances. Closing some of these gaps was one aim of Hugs: according to the History of Haskell paper, Hugs 1.0 added derived instances, defaults and overloaded numeric literals, although it still parsed and ignored module declarations.

Constructor classes

Gofer’s best-known contribution is the constructor class, which is a class whose parameter is a type constructor such as a list or a tree rather than a type. The cc.prelude shipped with Gofer 2.30 defines the classes that later became standard in Haskell:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
class Functor f where
    map :: (a -> b) -> (f a -> f b)

class Functor m => Monad m where
    result    :: a -> m a
    join      :: m (m a) -> m a
    bind      :: m a -> (a -> m b) -> m b

class Monad m => Monad0 m where
    zero   :: m a

The names are not the same as in later Haskell. Gofer used map where Haskell uses fmap, result where Haskell uses return, and bind where Haskell uses >>=. The Monad0 class (monads with a zero) is a forerunner of Haskell’s MonadPlus.

Do-notation

Gofer 2.30 added an experimental do syntax for monadic programming, which required the constructor-class prelude. The release notes give this example of a general filter over any monad with a zero:

1
2
3
4
myFilter     :: Monad0 m => (a -> Bool) -> m a -> m a
myFilter p xs = do x <- xs
                   if p x
                   result x

Unlike later Haskell, a Gofer do block could contain a guard written as if <expr>, which shows that it grew out of monad comprehensions. The same function written as a comprehension is [ x | x <- xs, p x ].

Interchangeable preludes

Gofer shipped with several prelude files that set the language level, including standard.prelude, simple.prelude, min.prelude, nofloat.prelude and cc.prelude (constructor classes). An instructor could choose a simpler prelude for beginners and switch to the constructor-class version for teaching monads.

Platforms

Jones developed Gofer on an IBM PC compatible, and the 2.30a README says it “also works on Sun workstations.” The 2.21 release notes add that users had reported compiling it on Apollo, DECstation, MIPS, MicroVAX and Acorn ARM machines with little or no change to the source. The archive Jones still hosts has PC executables built with Borland C 3.1, a 386 build made with DJGPP (larger heap and 32-bit integers), and Atari (gofatari.zip) and Macintosh (macgofer/) versions.

Evolution and Legacy

Gofer had a short active life, from 1991 to 1994, but a long influence:

  • Hugs. Gofer’s code base became Hugs, which was one of the most widely used Haskell implementations for teaching. Hugs 98 (March 1999) was the first version to support the Haskell 98 standard.
  • Haskell itself. Constructor classes, published by Jones at FPCA ‘93 and first available to users in Gofer 2.28, became part of Haskell in the 1.3 report (May 1996), together with monadic I/O and do-notation. Gofer had the first implementation of do-notation, in 1994. Haskell’s minimalist record syntax was also originally suggested by Jones.
  • Type-class research. Multi-parameter type classes, which were first implemented in Gofer, were later supported as an extension by Hugs and GHC. The 2.30a README credits Gofer’s approach to dictionary construction to a proposal Jones posted to the Haskell mailing list in February 1991. Jones later used the Gofer-to-C compiler to build the first “dictionary-free” implementation of type classes, using partial evaluation to specialise away dictionary passing.
  • Teaching. The History of Haskell paper says that when Gofer was released in 1991 it “made an ‘almost Haskell’ system available with a fast, interactive interface, good for teaching,” and that Hugs filled the same role from 1995.

Current Relevance

Gofer is a historical system. Jones’s ERRATA file for 2.30b says it is “no longer under active development.” He still hosts the Gofer archive on his Portland State University pages, with the 2.30a and 2.30b source distributions and an older PC binary for 2.28 (the 2.30a README also lists one for 2.23, which is no longer in the directory). The C source can still be studied, and in principle compiled. Gofer has no official Docker image or maintained package, and anyone wanting the same Haskell-learning experience today would use GHC’s interactive GHCi.

Gofer is still worth reading about because a lot of everyday Haskell, such as Functor and Monad and do blocks, was first tried in this small interpreter written on a home PC.

Why It Matters

Gofer showed that a lazy functional language with a sophisticated type system could run comfortably on cheap hardware, which brought Haskell-style programming to students who had no access to workstations. It also showed that one researcher’s implementation can change a language: by making constructor classes, multi-parameter type classes and do-notation available to real users, Gofer gave the Haskell community experience with those features before they were standardised. Its descendant Hugs carried that role forward for more than a decade.

Timeline

1989
Mark Jones, a student at Oxford's Programming Research Group, writes eqr, a crude tool for machine-assisted equational reasoning about functional programs - the project that Gofer grew out of
1990
Gofer 1.xx: a typed successor to eqr, based on Wadler's Orwell syntax and later extended with Haskell-style type classes. It has a lexer, parser, type checker and interactive loop, but cannot yet run programs
1991
Gofer 2.xx, a complete rewrite, begins in January; in February Jones devises a new implementation technique for type classes, and the focus shifts from deriving programs to running them
1991
Gofer 2.20, the first public release, is announced in August and distributed in September. It already supports multi-parameter type classes - the first implementation of them anywhere
1991
Gofer 2.21 (November) adds a more comprehensive user interface and command-line options and fixes bugs in the first release
1992
Gofer 2.23 (August), a bug-fix release; meanwhile Jones keeps separate private versions including a Gofer-to-C compiler and 'ccgofer', a prototype of constructor classes
1993
Gofer 2.28 (January), the largest update since the first release, merges in constructor classes, monad comprehensions and gofc, the Gofer-to-C compiler. Jones presents constructor classes at FPCA '93 the same year
1994
Gofer 2.30 (source headers dated March 1994; 2.30a README dated 23 June 1994) adds Haskell arrays, monadic I/O, contexts in datatype definitions, external function calls and the first implementation of do-notation
1995
On 14 February Jones announces Hugs, the 'Haskell User's Gofer System' - a rewrite of the Gofer code base that tracks the Haskell standard much more closely and becomes Gofer's successor. Gofer's final version, 2.30b, carries a 1991-1995 copyright
1996
The Haskell 1.3 report (May 1996) adopts constructor classes and monadic I/O with do-notation, ideas first implemented and tried out in Gofer
1997
The ERRATA file for Gofer 2.30b, with entries dated March to September 1997 (the latest, on 24 September, a space-leak patch from Mike Spivey), notes that Gofer is 'no longer under active development' and that the file is distributed from the Gofer ftp site at Nottingham

Notable Uses & Legacy

Utrecht University: Fokker's Functional Programming notes

Jeroen Fokker's course text 'Functional Programming' (Dutch first print September 1992, fifth revised print September 1995, later translated into English) taught functional programming using the Gofer interpreter at Utrecht University

University of Mississippi: Notes on Functional Programming with Gofer

H. Conrad Cunningham's 200-page course notes, technical report UMCIS-1995-01 (August 1995, replacing a January 1994 edition, revised January 1997), used Gofer as the language for an entire functional programming course

Algebra of Programming (Bird and de Moor)

Richard Bird and Oege de Moor's Prentice Hall textbook (September 1996) on calculating programs from specifications was accompanied by a downloadable archive of Gofer programs from Oxford's Department of Computer Science

TkGofer GUI library

A Tcl/Tk-based graphical user interface library for Gofer built on constructor classes by Ton Vullinghs, Wolfram Schulte and colleagues at the University of Ulm, described at PLILP '95 and AMAST '96 and packaged by Debian (non-free) in the late 1990s

Monad transformers research

Liang, Hudak and Jones's POPL '95 paper 'Monad Transformers and Modular Interpreters', the first to build a modular interpreter from monad transformers, relied on type class extensions that at the time only Gofer supported

Language Influence

Influenced By

Haskell Orwell

Influenced

Hugs Haskell

Running Today

Run examples using the official Docker image:

docker pull
Last updated: