Est. 1969 Intermediate

SETL

SETL (SET Language) is a very high-level programming language designed by Jacob T. Schwartz at NYU around 1969-1970, in which finite sets, tuples and maps over arbitrary domains are the primitive data types - the language that produced the first validated Ada compiler and, by way of ABC, gave Python its sets, dictionaries and comprehensions

Created by Jacob T. "Jack" Schwartz, who designed the language at the Courant Institute of Mathematical Sciences, New York University; the implementations and much of the later language design were the work of a large NYU group including Robert B. K. Dewar, Edmond Schonberg, Art Grand, Dave Shields, Henry S. Warren Jr., Stefan M. Freudenberger, Micha Sharir, Malcolm Harrison, Aaron Tenenbaum and Robert Paige

Paradigm Procedural and imperative, with a set-theoretic core: finite sets, tuples and maps over arbitrary domains are primitive, and set formers, tuple formers and first-order universal and existential quantifiers are ordinary expressions. Conservative for its time, it did not include higher-order functions; the final version added a backtracking mechanism and database operations
Typing Dynamic; values carry their own types, there are no type declarations in the core language, and the distinguished undefined value om is returned wherever a map or index has no value
First Appeared Schwartz drafted the first design while working at IBM Research in the summer of 1969, and the project proper began at NYU in 1970: the first public report appeared in September 1970 and the first SETL Newsletter on 5 November 1970. The first running implementation, BALMSETL, was running at NYU by the spring of 1971
Latest Version GNU SETL 8.13.22, released 7 February 2025 by David Bacon; the original NYU LITTLE-based SETL was distributed by the Courant Institute from the mid-1970s until the late 1980s

SETL - short for SET Language - is a very high-level programming language in which the primitive data types are the objects of finite set theory: unordered sets, tuples, and maps over arbitrary domains. Designed by Jacob T. “Jack” Schwartz at New York University’s Courant Institute around 1969-1970, its premise was that a programmer should be able to write down what an algorithm computes, in more or less the notation a mathematician would use, and leave the choice of data structures to the compiler.

SETL never became a widely used language. Its influence, however, is peculiarly large and peculiarly well hidden. It produced the first validated Ada compiler. It supplied the executable notation for Gregory Chaitin’s graph-colouring register allocator. And by way of ABC, it is the reason Python has dictionaries, a set type, and comprehensions.

History and origins

Schwartz was a mathematician - the co-author, with Nelson Dunford, of the three-volume Linear Operators - who came to computing through program optimization. Visiting IBM Research, he worked with John Cocke and Frances Allen on the optimization techniques that they had pioneered, and co-wrote with Cocke an encyclopedic report on compiler construction that, though never formally published, founded compiler optimization as a subject of study.

The algorithms that came out of that work - global data-flow analysis, interval analysis - have a natural expression in terms of sets and relations, and were miserable to write in Fortran, the language of choice at the time. According to a note on the C2 wiki cited by the SETL Historical Sources Archive, Schwartz drafted the first design of a set-theoretic language over the summer of 1969 while at IBM; IBM decided not to pursue it, and he carried it back to NYU. Dave Shields recalled running into him near 90th and Broadway “in late summer 1970 (or perhaps 1971)”, when Schwartz explained that he was building a programming language based on the theory of finite sets: “I thought it then, and have had the same view ever since, that this was the single greatest idea for a programming language that I have ever encountered.”

The first public document, “Set theory as a language for program specification and programming,” is dated September 1970. Its opening states the case plainly:

“It may be remarked in favor of SETL that the mathematical experience of the past half-century, and especially that gathered by mathematical logicians pursuing foundational studies, reveals the theory of sets to incorporate a very powerful language in terms of which the whole structure of mathematics can rapidly be built up from elementary foundations.”

The 298-page “Abstract algorithms and a set theoretic language for their expression” followed in December 1970, and SETL Newsletter number 1 - Malcolm Harrison’s proposal to prototype SETL in his own BALM language - is dated 5 November 1970. The newsletters eventually ran to 234 numbers across 1970-1981 and 1985-1989.

Three generations of implementation

The implementation history came in layers.

GenerationDatesWritten inNotes
BALMSETL, SETLB, SETLA1971-1975BALM (a LISP-like language with ALGOL 60 syntax, by Malcolm Harrison)Prototypes. SETLB was an awkward subset; SETLA was near-complete. Dave Shields wrote the first
CIMS SETLmid-1970s - late 1980sLITTLEThe real thing. Compiler by Dewar and Art Grand, run-time library SRTL by Henry S. Warren Jr. Distributed under licence by the Courant Institute
GNU SETL1990s-presentCDavid Bacon’s reimplementation, extended with POSIX bindings. First public source release December 2022

LITTLE was Schwartz’s own systems language, syntactically Fortran-like with a bit-field extraction notation and only two built-in types - fixed-length bit strings and floating-point numbers. Shields bootstrapped it to self-hosting by the end of 1973, and it was ported from the CDC 6600 to System/360, the DEC-10, and VAX. The 1986 book Programming with Sets records SETL implementations on the CDC 6600, CDC Cyber, DEC VAX, IBM System/370, and Sun and Apollo workstations; in the 1970s, Ershov’s group in Novosibirsk brought it to the BESM-6, and Soviet accounts report that it later reached ES EVM machines.

Design philosophy

The SETL argument runs roughly as follows. A programmer writing in a conventional language spends most of their effort on two things that have nothing to do with the problem: choosing concrete data structures, and writing the loops that walk them. Both are mechanical. Both can, in principle, be done by a compiler. Give the programmer sets and quantifiers instead, and the program shrinks to the size of its specification.

Schwartz’s goal, as the archive puts it, was “to express functionality rather than algorithm and data structure detail, in effect to think like a mathematician rather than a programmer.”

Crucially, this was not a functional language and made no attempt to be. The set-theoretic core sits inside an entirely conventional imperative shell: assignment, if, loops, procedures, recursion, global state. Higher-order functions were, in Davis and Schonberg’s description, deliberately omitted as too radical for the time. SETL is what you get when you take Fortran-era procedural programming and swap out its data types for those of ZF set theory.

Key features

Sets and tuples. The two aggregate types. Elements may be of any type, including other sets and tuples. Sets are unordered and duplicate-free; tuples are indexed sequences.

s := {1, 2, 3, 'apple', [4, 5]};
t := ["age", 21];

Maps as sets of pairs. There is no separate dictionary type - a map is a set of two-element tuples. Applying it with parentheses gives the single value, with braces the set of all values:

f("age")      -- single-valued retrieval
f{"age"}      -- multi-map retrieval: the set of all values
{[y, x] : [x, y] in m}    -- the inverse of a map, in one expression

om. The distinguished undefined value, returned by any map application or index with no value, and never a member of any set. om is SETL’s answer to what a partial function does off its domain, and it predates the null-safety debates by decades.

Set and tuple formers. The comprehension notation, in which the resemblance to modern Python is unmistakable in both directions of borrowing:

{x * x : x in {1..10} | x mod 2 = 1}

First-order quantifiers as expressions. forall, exists and notexists are ordinary boolean expressions, which makes the classic prime sieve a one-liner:

{p in {2..n} | notexists i in {2..p-1} | p mod i = 0}

Compound operators. A reduction operator folds a binary operator over a tuple, so factorial has a conventional recursive definition and a more idiomatic one-expression form:

procedure factorial(n);          -- calculates n!
  return if n = 1 then 1 else n * factorial(n - 1) end if;
end factorial;

*/[1..n]                          -- the same thing, as a product reduction

Compound assignment over maps, which makes word-frequency counting about as short as it can be written:

count := {};
for word in split(getfile stdin) loop
  count(word) +:= 1;
end loop;

The representation sublanguage and automatic data structure choice

The hardest problem SETL set itself was performance, and its most original answer was to make representation a separate concern from the program. A programmer could write the algorithm purely set-theoretically and then, optionally and separately, annotate declarations with hints from a representation sublanguage describing how sets should actually be stored - as hash tables, bit vectors, linked structures, or based on an enumerated “base set.”

Better still, the compiler could choose for itself. Automatic data structure selection was the subject of Ssu-cheng Liu’s thesis and of Schonberg, Schwartz and Sharir’s POPL ‘79 and TOPLAS 1981 papers, and it was implemented in the SETL optimizer alongside Aaron Tenenbaum’s type-inference work and Robert Paige’s finite differencing - the systematic transformation of expensive expressions recomputed inside loops into cheaply updated invariants.

This is where SETL was furthest ahead of its time and, as Fritz Henglein observed, where its influence was most thoroughly forgotten:

“SETL has had a significant (but well-hidden) intellectual impact on programming language research and development; in some cases it was so far ahead of its time, e.g. for classical data flow analysis … value-oriented programming with updatable variables aliasing and hashing to make this work efficiently, flow/dynamic type analysis for structured data (rediscovered in the 90s without knowledge of SETL work in the 70s and 80s), set and map data types (via ABC, a predecessor for Python’s dictionaries), comprehension notation (popularized in 80s and 90s as list comprehensions …).”

The honest caveat is that the optimizer never fully closed the gap. It was a roughly 24,000-line SETL program, and on 1980s hardware it was too large to be applied to itself. SETL programs remained slow enough that the language was pitched as a prototyping medium rather than a production one - which, in the case of Ada/Ed, was exactly the point.

Evolution and descendants

SETL proper stopped evolving at NYU in the mid-1980s, as Schwartz’s attention moved to parallel computing and robotics and then to DARPA. What followed was a diaspora of dialects.

  • SETL2 (W. Kirk Snyder, 1990) is a deliberately backward-incompatible redesign with syntax and style borrowed from Ada. Snyder has described two SETL2s: an officially funded Office of Naval Research effort with a front end in Ada that never ran, and his own skunkworks C implementation that started as fun and became the one people used.
  • ISETL (Gary Levin, from 1986) went the other way: a smaller, interactive subset for teaching, with first-class functions added. Ed Dubinsky built a run of Springer textbooks around it.
  • SETL/E and ProSet (Ernst-Erich Doberkat, Essen and Dortmund, from about 1990) added persistent stores and process creation, and later Linda tuple spaces, aimed at prototyping concurrent and parallel systems.
  • Cantor (Jean-Pierre Keller, from about 1991) derived from ISETL and grew out of the ESPRIT SED (SETL Experimentation and Demonstration) project of the late 1980s, which had built a SETL-to-Ada translator, editor, debugger and profiler.
  • Griffin (NYU, early 1990s) was the ambitious, never-completed general-purpose successor, blending SETL with ML- and Haskell-style type inference. Schonberg’s verdict: the trends “did not lead to a viable new language, but produced a number of extremely stimulating discussions among the participants.”
  • SetlX (designed mostly by Karl Stroetmann, implemented by Tom Herrmann) is a modern reworking with C/Java-influenced syntax, Prolog-like terms, functional programming, backtracking and plotting, intended to make SETL’s ideas accessible to today’s students. It runs on the JVM; per its own documentation, version 2.7.2 dates from 2019.
  • GNU SETL (David Bacon) is the closest thing to a living SETL. Bacon’s January 2000 NYU thesis, SETL for Internet Data Processing, set out to make SETL “play well in the Unix (POSIX) world of processes, pipes, filters, sockets, and programs written in other languages.”

Current status

GNU SETL is the implementation to use today. It is written in C, distributed under the GPL, and available from setl.org and from the davidjbacon/SETL repository on GitHub. Its first public source release was version 3.5.8 on 12 December 2022; subsequent releases have numbered themselves along the Fibonacci sequence - 5.8.13 (8 April 2024) and 8.13.21 (9 November 2024) - then 8.13.22 (7 February 2025), which steps one past it, a fix to non-MAGIC string matching. The project’s INSTALL file says to “expect best results for Posixy (Unix-supportive) environments such as Linux, QNX, Solaris, the BSDs, HP-UX, AIX, IRIX, Darwin, and Cygwin,” and notes that Macs on Apple silicon need a newer GMP than the bundled 6.1.2. There is no official Docker image.

The historical record is in unusually good shape. Since 2020, Paul McJones’s SETL Historical Sources Archive at the Computer History Museum’s Software Preservation Group has collected the LITTLE-based compiler and run-time sources (a VAX UNIX version from around January 1985, donated by Stefan Freudenberger), the optimizer, recovered distribution tapes, the SETL2, ISETL and Ada/Ed sources, theses, manuals, and scans of SETL Newsletters 1 through 217 - roughly 2,700 pages of the project’s internal correspondence.

Schwartz died on 2 March 2009; Robert Dewar, who went on from Ada/Ed to co-found AdaCore and lead GNAT, died in 2015. The language is dormant in the sense that nobody is designing it any further, but its artifacts are better preserved than those of most languages a hundred times more popular.

Why it matters

Fran Allen, asked in 2011 what she thought of SETL, gave the fairest summary anyone has: “It wasn’t the right thing for that time, but it may be an interesting language to go back and look at now that we’re mired in over-specifying.”

The specific things SETL got right, decades early, are now unremarkable. Sets and hash maps as language-level primitives with literal syntax. Dictionaries keyed by arbitrary values. Comprehensions with filters. Arbitrary-precision integers. A distinguished undefined value with defined semantics. Dynamic typing with a type inferencer trying to recover static information behind the programmer’s back - which is, more or less, what every modern JIT for a dynamic language does. Prototyping in a very high-level language before committing to an implementation.

The specific thing it got wrong was timing. A language whose whole proposition is “let the compiler pick the data structures” needs either a very good compiler or a very fast machine, and in 1975 it had neither. What SETL had instead was a set of ideas patient enough to wait: through ABC to Python, through Ada/Ed to GNAT, through the optimizer papers into the analysis literature, and through Chaitin’s appendix into every register allocator since.

Timeline

1969
Jacob T. Schwartz, already known for the Cocke-Schwartz compiler report and for work with John Cocke and Frances Allen on program optimization at IBM, reportedly drafts the design of a programming language built on finite set theory while at IBM Research over the summer - the SETL Historical Sources Archive relays this via a note on the C2 wiki. The motivation is practical: the global data-flow and interval-analysis algorithms developed at IBM have a natural set-theoretic expression but were painful to write in Fortran
1970
The SETL project starts in earnest at the Courant Institute of Mathematical Sciences, NYU. Schwartz circulates "Set theory as a language for program specification and programming" (September, 97 pages) and the 298-page "Abstract algorithms and a set theoretic language for their expression" (December). SETL Newsletter number 1 - Malcolm Harrison, "BALM-SETL: A simple implementation of SETL" - is dated 5 November
1971
The first working implementations run on top of Harrison's LISP-like BALM language: BALMSETL, written by Dave Shields, whose user's guide and status report circulate as SETL Newsletters 20 and 23 in March and April 1971, and the SETLB and SETLA subsets built above it. SETLB was the first of the subsets to reach users; SETLA, specified in 1972, was closer to full SETL
1973
Schwartz publishes "On Programming: An Interim Report on the SETL Project" in two installments (January and October; a combined, revised edition follows in June 1975). Shields bootstraps LITTLE - Schwartz's bit-field-oriented systems language - to a self-hosted compiler by the end of the year, providing the vehicle for the real SETL implementation. Henry Mullish and Max Goldstein publish "A SETLB Primer" in June, and Robert Abes edits the SETL Master Catalog of project reports and files in October
1975
Over the middle years of the decade, Robert B. K. Dewar and Art Grand build the full SETL compiler in LITTLE, with Henry S. Warren Jr. contributing the run-time library SRTL. This is the CIMS SETL that the Courant Institute maintained and distributed from the mid-1970s until the late 1980s, and the platforms recorded for it are the CDC 6600 and Cyber, DEC VAX, IBM System/370, and Sun and Apollo workstations
1979
Dewar's reference manual "The SETL Programming Language" appears, and the group publishes its major optimization work: Schonberg, Schwartz and Sharir on automatic data structure selection at POPL '79, and Dewar, Grand, Liu, Schwartz and Schonberg on the SETL representation sublanguage in the very first issue of ACM TOPLAS. Schwartz and Sharir's report on bitvectoring-class optimizations follows in September
1980
Dewar, Gerald Fisher, Schonberg and colleagues present "The NYU Ada translator and interpreter" at the ACM SIGPLAN Symposium on the Ada Programming Language in November. Ada/Ed is written in SETL as an executable denotational definition of the whole language, tasking and rendezvous included - Schwartz and Dewar's showcase for SETL as a software-prototyping medium, funded by the US Army
1983
On 11 April, SofTech's validation summary report certifies NYU Ada/Ed version 19.7 (dated 21 March 1983) as the first validated Ada implementation: tested against ACVC version 1.1, it passed all 1,311 applicable correct tests of the 1,325 that applied to it. Also in 1983, Freudenberger, Schwartz and Sharir publish "Experience with the SETL Optimizer" in TOPLAS, describing a roughly 24,000-line optimizer written in SETL itself
1986
Springer-Verlag publishes "Programming with Sets: An Introduction to SETL" by Schwartz, Dewar, Dubinsky and Schonberg - the definitive book on the language. In January 1986 Gary Levin, working from Ed Dubinsky's specifications, begins ISETL, an interactive teaching subset with first-class functions added
1988
By the autumn, ISETL 1.0 is stable enough for Dubinsky to teach discrete mathematics and abstract algebra with it; Springer publishes "Learning Discrete Mathematics with ISETL" by Nancy Baxter, Dubinsky and Levin the following year, the first of a series of ISETL-based textbooks. The NYU SETL Newsletters, numbered to 234, wind down around this time
1990
W. Kirk Snyder issues "The SETL2 Programming Language" as Courant Institute Technical Report 490 on 9 September. SETL2 is a deliberately backward-incompatible redesign with Ada-influenced syntax, begun as an Office of Naval Research project and finished by Snyder in C as a personal effort; a version of Ada/Ed was later ported to it
1991
SETL's European descendants take shape: Ernst-Erich Doberkat's SETL/E at Essen and Dortmund is extended with persistent P-files and a process-creation operator and renamed ProSet - the SETL/E language description is dated March 1990 and the ProSet definition April 1992 - and later hybridised with Linda tuple spaces as ProSet-Linda; Jean-Pierre Keller, who had led the ESPRIT SED project, derives Cantor from ISETL
2000
David Bacon completes his NYU PhD thesis "SETL for Internet Data Processing" in January, describing the implementation that became GNU SETL - a reworking of the language aimed at making it a first-class citizen of the Unix world of processes, pipes, filters and sockets
2009
Jack Schwartz dies on 2 March at the age of 79. His unfinished draft "Programming in SETL", adapted from the 1986 book for SETL2, remains online at settheory.com
2020
Paul McJones establishes the SETL Historical Sources Archive at the Computer History Museum's Software Preservation Group, gathering source code, manuals, theses and scans of SETL Newsletters 1 through 217 - some 2,700 pages - donated largely by Stefan M. Freudenberger, along with recovered distribution tapes and the SETL2, ISETL and Ada/Ed sources
2022
GNU SETL gets its first public source release, version 3.5.8, on 12 December, under the GPL. The version numbers thereafter walk the Fibonacci sequence: 5.8.13 on 8 April 2024 and 8.13.21 on 9 November 2024, with 8.13.22 - a regression fix in non-MAGIC string matching - stepping one past it on 7 February 2025

Notable Uses & Legacy

NYU Ada/Ed, the first validated Ada compiler

Robert Dewar wrote what was in essence an executable denotational definition of Ada 83 in SETL, including the full tasking and rendezvous model, while Edmond Schonberg wrote the static semantic analyser. Because the definition was executable, it could be used to check SofTech's ACVC test suite as that suite was being written. Ada/Ed version 19.7 was certified on 11 April 1983 as the first validated Ada implementation, passing all 1,311 applicable correct tests of ACVC 1.1; version 1.4 was validated again on 28 June 1984. Schonberg recalled that it was "extremely slow - we used to say that it was for the real-time simulation of paper-and-pencil calculations" - but that it was politically convenient for the Department of Defense that the first validated Ada was not a commercial product. Ada/Ed was later rewritten in C, and the NYU team went on to build GNAT, the GCC Ada front end

Gregory Chaitin's graph-colouring register allocator

Chaitin's 1982 SIGPLAN Compiler Construction paper "Register allocation and spilling via graph coloring" - long among the most-cited papers in the compiler literature, and the basis for register allocation in production compilers ever since - presents its algorithm in an appendix as roughly four and a half pages of executable SETL, prefaced with the note that the program "outlines in executable form the main ideas and algorithms presented in this paper"

ABC, and through it Python

Guido van Rossum has stated flatly that "Python's predecessor, ABC, was inspired by SETL - Lambert Meertens spent a year with the SETL group at NYU before coming up with the final ABC design." Meertens has described writing his ABC data-type selection program in SETL, and redesigning ABC's data types after seeing SETL's sets and associative arrays indexed by arbitrary values rather than integers. Python's dictionaries, its set type and its comprehension notation all descend from that line

The SETL optimizer

Written by Freudenberger, Grand, Schwartz, Sharir and Leonard Vanek as "pass two and a half" of the SETL compiler - running between the semantic pass and the code generator - the optimizer was a roughly 24,000-line program written in SETL itself, performing automatic data structure selection and type inference to turn naive set-theoretic code into something with reasonable representations. It was an unusually large exercise in bootstrapping a very high-level language, though as Bacon notes, on the machines of the day it was too large to apply to itself

ISETL in mathematics education

Gary Levin's Interactive SET Language, built to Ed Dubinsky's specifications from 1986, stripped SETL to a teaching subset and added first-class functions. Dubinsky and colleagues built a series of Springer textbooks around it - "Learning Discrete Mathematics with ISETL" (1989), "Learning Abstract Algebra with ISETL" (1994) and "Introduction to Discrete Mathematics with ISETL" (1996) - using the interpreter to let students manipulate mathematical objects directly. ISETL 3.0 (1990) was distributed for PC/MS-DOS and for the Macintosh, with C sources that Levin has since updated to build on modern Linux, and a Windows version, ISETLW 2.0, followed on 29 June 1996

SETL in the Soviet Union

Schwartz and other SETL project members visited Andrey Ershov's group at Akademgorodok in Novosibirsk several times during the 1970s; Schwartz deposited "Notes on the design of SETL" in the Ershov Archive in December 1972, and the project ran a parallel series of Russian-language SETL newsletters. Ershov's group implemented a version of SETL for the BESM-6 using the EPSILON language, and Soviet accounts of the project report a subsequent port to ES EVM machines

Robert Paige's RAPTS and APTS transformation systems

Paige, whose 1979 NYU thesis on formal differentiation of algorithms came out of the SETL optimizer work, built the Rutgers Abstract Program Transformation System and its successor APTS as experimental systems for constructing program transformations, compilers and analysis tools. APTS was begun around 1992 as a rewrite of RAPTS in Snyder's SETL2

Language Influence

Influenced By

Influenced

ABC Python SETL2 ISETL ProSet Cantor SetlX Griffin

Running Today

Run examples using the official Docker image:

docker pull
Last updated: