The pymdl book
Appendix G. References and provenance
Hand-written. Where this book's text came from, where pymdl's vendored era material came from, and how to check either.
G.1. The two manuals
This book is based on two manuals published by MIT's Laboratory for Computer Science. Its scope is their complete contents, edited into a self-contained account of pymdl and extended with implementation-specific material. The vendored transcriptions preserve the original wording and organization for historical reference; they are not required reading.
S. W. Galley and Greg Pfister, The MDL Programming Language. MIT
Laboratory for Computer Science, 1979. Twenty-four chapters and nine
appendices, covering release 55 (ITS) and release 105 (Tenex/Tops-20). Its language chapters form
Part II of this book, chapters 4 through 26; its chapter 19 on compiled
programs appears in book chapter 33. This book reorganizes the appendix
material by subject. That reorganization does not reduce its scope: any
source material not yet incorporated must be treated as an omission to fix,
not as a reason to send the reader to the original.
The vendored Markdown transcription is docs/mdl/, converted from
https://github.com/taradinoc/mdl-docs (vendored 2026-06-27).
P. David Lebling, The MDL Programming Environment. MIT Laboratory for
Computer Science, May 1980, 142 pages. The companion manual, documenting
everything the language manual defers to "Lebling (1979)": the package system,
the editor, the pretty-printer, TRACE and the monitors, CRITIC, the library
system, the compiler interface, and GLUE/PDUMP/SUBRFY. This is Part III,
chapters 27 through 32, plus chapters 34 and 35. The vendored transcription is
docs/mdl-environment/.
The second manual's provenance needs a sentence more, because its transcription
is less certain than the first's. It survives as a scanned PDF; the Markdown in
docs/mdl-environment/ began as an OCR pass over that scan and was then audited
page by page against it, an audit completed 2026-08-28. The PDF,
MDL_Programming_Environment.pdf, is kept beside the text and is authoritative
whenever a word, a form or a page layout looks suspect. The raw OCR layer and
the script that cleaned it have since been retired, because the audit left the
chapter files better than rerunning that pipeline produced; the chapters are now
the text itself, maintained by hand, and a future re-transcription should start
from a fresh scan of the PDF rather than from the old layer. (Both retired files
remain in git history.) That directory's README states the transcription
conventions: OCR restoration is silent, but a correction to something the manual
actually said is marked.
Both manuals are also cited in the introduction, which is where a reader meets them first. The chapter sources are collected in section G.6. Historical text is incorporated into the prose rather than enclosed in quotation marks. Introductions and sections numbered for this book develop the pymdl account; labelled notes identify implementation details, measurements, and discoveries.
The storage-layout account is included in appendix H. Appendix I supplies topic and name indexes with links into this book. The historical prefaces, acknowledgements, publication statements, and distribution record are preserved in appendix J. These supplement the subroutine catalogue, type classifications, error explanations, and initial settings in appendices A–D.
Works the manuals themselves cite
- Hewitt, Carl. Planner: A Language for Manipulating Models and Proving Theorems in a Robot. Proceedings of the International Joint Conference on Artificial Intelligence, May 1969. Cited in the historical abstract for Planner's role in MDL's original design goals.
- Moon, David A. MacLisp Reference Manual. MIT, 1974. Cited throughout
the language manual for Lisp comparisons -- the
ATOMT, "pure Lisp", and the origin of the word "special" for the control stack. - Lebling, P. David, 1979. The language manual's forward reference to the environment manual above, made repeatedly and never resolved in that volume. Chapters 27 through 32, 34, and 35 cover that material here.
G.2. The era material pymdl vendors
pymdl ships a quantity of MIT's own MDL source, because running the era's
programs is the point. Every vendored file is recorded in
src/pymdl/mdl/MANIFEST.tsv, which has one row per file with five columns:
| column | meaning |
|---|---|
file |
the path under src/pymdl/mdl/ |
provenance |
the archive path it came from |
era-date |
the file's own date from the archive |
sha1-12 |
the first twelve hex digits of its SHA-1 |
note |
anything else worth saying, such as "extracted from a longer file" |
There are 116 vendored files, in these groups:
| directory | files | what |
|---|---|---|
compil/ |
60 | MIT's MDL compiler, in source |
mudbug/ |
37 | the debugger, the library tools, NEWLF and its kin |
mprog/ |
7 | assorted MDL programs, including SQUOZE |
libmud/ |
7 | the package and library system: NPCK, NL, NLIB, NLUP |
mudsav/ |
2 | save-file machinery |
| loose files | 3 | MAT, MATXGP, INQUIRE |
The manifest is generated and checked by tools/mdl_manifest.py; --check
verifies that every file still hashes to what the manifest records, which is how
an accidental edit to vendored material is caught.
The archive directory numbers in the provenance column -- 9006255,
7005458, 2100099 and the rest -- are the MIT tape and dump identifiers in
the mdl-1971-1987 collection. They matter because several of these files
exist in more than one copy with different contents, and chapter 38 has what
that costs: nine of the ten copies of one file on the tape have rotted, and the
tenth is intact. Chapter 34's box on symana.mud is the same problem in the
compiler: two of its analyzers carry bugs their sibling copies lack.
Changes to vendored material
The standing rule is that vendored era material is read, not edited. The one
exception is the compiler, where era bugs are fixed rather than preserved as
data, because the compiler has to work for chapters 33 and 34 to exist. Every
such change is recorded in src/pymdl/mdl/compil/CHANGES.md, with the diff and
the reason, and the manifest records the current hash. A reader who wants MIT's
file exactly as the tape has it should take the archive path from the manifest
and read that.
G.3. Checking this book
The following checks cover executable examples and generated reference material. They support technical review but do not replace reading the prose against the manuals and implementation.
- The examples are tests. Every fenced
```mdlblock indocs/pymdl/*.mdis executed against a fresh interpreter bytests/test_book_examples.py, and an answer written after⇒must match. A block marked```mdl-xis shown but not run -- transcripts of a terminal dialogue, code that needs a file or a program that is not here, and the manual's own examples that are being quoted rather than demonstrated. - The claims about MDL 55 are measured. Appendix E has what that means and which batteries exist.
- The appendices A, B and C are generated, by
tools/book_gen.py, from pymdl's own registry, type table and error oblist;--checkverifies that the committed files still match what the interpreter reports. - The working file behind the boxes is
docs/pymdl/harvest.md: 341 hits gathered from code comments and docstrings, 19CHANGES.mdsections and 59 commit messages, each tagged with the manual section it belongs to. It is raw material rather than prose, and it is where a claim's original wording and date live.
G.4. External material this project used but does not ship
These live outside the repository and are named here so that a reader can find them; none is required to run pymdl.
- The
mdl-1971-1987archive -- the MIT tapes and dumps that everything insrc/pymdl/mdl/came from, and the era binaries chapters 33 and 38 read. - The MDL 55 and MDL 54 source trees -- MIT's interpreter in MIDAS and
binary form.
mudsys/primit, cited in chapter 15 for the era's locative error banners, is in this material, and so is thearithmodule chapter 6'sRANDOMwas ported from. - apsim -- the PDP-10 simulator that runs the era images the oracle answers come from. Chapter 37 has how it is driven.
- The Zork/MDL game sources -- six dated trees, used as a corpus of real era
programs. The game material was removed from this repository in 2026-08-28;
tests/synth/carries a synthesised program in its place, so the test suite does not depend on material it does not ship.
G.5. Citation
If you cite this book, cite the manuals it reproduces first. The reproduction is faithful and the corrections are marked, but Galley, Pfister and Lebling wrote the text; this book adds the boxes, the measurements, and Parts I and IV.
G.6. Chapter sources
The source and implementation notes are collected here for provenance and technical review. They are not prerequisites for reading the chapters.
1. What pymdl is
1. What pymdl is is based on: the manuals' front matter (M0) and the Environment overview (E1); src/pymdl/__init__.py.
2. Running pymdl
2. Running pymdl is based on: src/pymdl/repl.py, src/pymdl/subrs/channels.py, demo/; the manual's 1.2 (typing at MDL) and 11.2 (file names).
3. Setting up
3. Setting up is based on: README.md, tools/build_mdllib.py, src/pymdl/__init__.py, tests/conftest.py.
4. Basic introduction
4. Basic introduction is based on: The MDL Programming Language, chapter 1, adapted; Part I of this book (chapters 1 to 3) for how the same things are done here.
5. Read, evaluate, and print
5. Read, evaluate, and print is based on: The MDL Programming Language, chapter 2, adapted; src/pymdl/reader.py, src/pymdl/eval.py, src/pymdl/printer.py; tests/test_reader_printer.py, tests/test_manual_examples.py, tests/test_validation.py.
6. Built-in functions
6. Built-in functions is based on: The MDL Programming Language, chapter 3, adapted; src/pymdl/subrs/ (the built-ins, one module per family), src/pymdl/subrs/arith.py, src/pymdl/subrs/registry.py, src/pymdl/subrs/argcheck.py; Appendix A of this book, which is the catalogue.
7. Values of atoms
7. Values of atoms is based on: The MDL Programming Language, chapter 4, adapted; src/pymdl/env.py (the value cells and the binding stack), src/pymdl/subrs/control.py; tests/test_control_bindings.py, tests/test_manual_examples.py.
8. Simple functions
8. Simple functions is based on: The MDL Programming Language, chapter 5, adapted; src/pymdl/types.py (the FUNCTION layout), src/pymdl/eval.py (binding and application), src/pymdl/subrs/control.py (DEFINE, FUNCTION); tests/test_manual_examples.py, tests/test_control_bindings.py.
9. Data types
9. Data types is based on: The MDL Programming Language, chapter 6, adapted; src/pymdl/types.py, src/pymdl/subrs/type_ops.py, src/pymdl/subrs/spec_subrs.py (the type census); Appendix B of this book, which is the manual's appendix 3; tests/test_manual_examples.py, tests/test_type_codes_era.py.
10. Structured objects
10. Structured objects is based on: The MDL Programming Language, chapter 7, adapted; src/pymdl/types.py (the five structured primitive types), src/pymdl/subrs/struc.py, src/pymdl/subrs/spec_subrs.py (SORT, SUBSTRUC), src/pymdl/printer.py; tests/test_manual_examples.py, tests/test_equal_predicates.py.
11. Truth
11. Truth is based on: The MDL Programming Language, chapter 8, adapted; src/pymdl/types.py (TYPE FALSE), src/pymdl/subrs/pred.py, src/pymdl/subrs/control.py (COND, AND, OR); tests/test_equal_predicates.py, tests/test_manual_examples.py.
12. Functions
12. Functions is based on: The MDL Programming Language, chapter 9, adapted; src/pymdl/eval.py (argument-LIST binding), src/pymdl/env.py (ENVIRONMENT, ACTIVATION, the control stack), src/pymdl/subrs/control.py (AGAIN, RETURN, APPLY, CLOSURE); tests/test_control_bindings.py, tests/test_manual_examples.py.
13. Looping
13. Looping is based on: The MDL Programming Language, chapter 10, adapted; src/pymdl/subrs/control.py (PROG, REPEAT, BIND, GO, TAG), src/pymdl/subrs/control.py (MAPF, MAPR and the MAP* escapes); tests/test_control_bindings.py, tests/test_manual_examples.py.
14. Input and output
14. Input and output is based on: The MDL Programming Language, chapter 11, adapted; src/pymdl/subrs/io.py (the conversion and imaged SUBRs), src/pymdl/subrs/channels.py (channel operations), src/pymdl/gcdump.py (GC-DUMP/GC-READ), src/pymdl/subrs/builtins2.py; tests/test_read_print.py, tests/test_manual_examples.py.
15. Locatives
15. Locatives is based on: The MDL Programming Language, chapter 12, adapted; src/pymdl/types.py (Locative and the seven locative TYPEs), src/pymdl/subrs/spec_subrs.py (LLOC, GLOC, AT, IN, SETLOC); tests/test_manual_examples.py.
16. Association (properties)
16. Association (properties) is based on: The MDL Programming Language, chapter 13, adapted; src/pymdl/types.py (TYPE ASOC and the association chain), src/pymdl/subrs/assoc.py (PUTPROP, GETPROP, ASSOCIATIONS and kin), src/pymdl/reader.py (the COMMENT association); tests/test_associations.py.
17. Data-type declarations
17. Data-type declarations is based on: The MDL Programming Language, chapter 14, adapted; src/pymdl/decl.py (the Pattern matcher), src/pymdl/subrs/oblist.py (GET-DECL, PUT-DECL), src/pymdl/subrs/control.py (checking on SET, SETG and function entry), src/pymdl/types.py (TYPE OFFSET); tests/test_decl.py.
18. Lexical blocking
18. Lexical blocking is based on: The MDL Programming Language, chapter 15, adapted; src/pymdl/types.py (MDL objects), src/pymdl/subrs/oblist.py (MOBLIST, LOOKUP, INSERT, REMOVE, BLOCK/ENDBLOCK), src/pymdl/reader.py and src/pymdl/printer.py (the !- trailer); tests/test_remove_makes_new_atom.py.
19. Errors, frames, etc.
19. Errors, frames, etc. is based on: The MDL Programming Language, chapter 16, adapted; src/pymdl/repl.py (the READ-EVAL-PRINT loop and its levels), src/pymdl/env.py (TYPE FRAME and the control stack), src/pymdl/subrs/errctl.py (ERRET, RETRY, UNWIND, OVERFLOW); tests/test_error_routing.py, tests/test_repl.py.
20. Macro-operations
20. Macro-operations is based on: The MDL Programming Language, chapter 17, adapted; src/pymdl/reader.py (%, %%, TYPE LINK, the read and parse tables), src/pymdl/subrs/control.py (DEFMAC, EXPAND, TYPE MACRO); tests/test_macros.py, tests/test_macros.py.
21. Machine words and bits
21. Machine words and bits is based on: The MDL Programming Language, chapter 18, adapted; src/pymdl/types.py (TYPE WORD and TYPE BITS), src/pymdl/subrs/builtins2.py (GETBITS, PUTBITS, the Boolean and shift SUBRs), src/pymdl/pdp10_word.py (the 36-bit word the emulator shares); tests/test_putbits_two_args.py.
22. Coroutines
22. Coroutines is based on: The MDL Programming Language, chapter 20, adapted; src/pymdl/types.py (TYPE PROCESS), src/pymdl/subrs/process.py (RESUME, STATE, BREAK-SEQ, 1STEP); tests/test_manual_examples.py.
23. Interrupts
23. Interrupts is based on: The MDL Programming Language, chapter 21, adapted; src/pymdl/subrs/interrupts.py (EVENT, HANDLER, ON, OFF, INTERRUPT, INT-LEVEL, the monitors), src/pymdl/types.py (TYPE IHEADER and TYPE HANDLER); tests/test_manual_examples.py.
24. Storage management
24. Storage management is based on: The MDL Programming Language, chapter 22, adapted; src/pymdl/subrs/storage.py (GC, BLOAT, BLOAT-STAT, GC-MON, PURIFY), src/pymdl/subrs/builtins2.py (FREEZE, SUBSTITUTE), src/pymdl/subrs/nlibdb.py (the pure/page space chapter 33 actually uses); tests/test_manual_examples.py.
25. MDL as a system process
25. MDL as a system process is based on: The MDL Programming Language, chapter 23, adapted; src/pymdl/subrs/system.py (TIME, the name SUBRs, and exits), src/pymdl/subrs/ipc.py (IPC); tests/test_manual_examples.py, tests/test_mudinq.py.
26. Efficiency and tastefulness
26. Efficiency and tastefulness is based on: The MDL Programming Language, chapter 24, adapted. This chapter is advice rather than machinery, so its "pymdl's own" boxes say which pieces of the advice still bind and which were about a PDP-10.
27. Overview
27. Overview is based on: The MDL Programming Environment, chapter 1, adapted; src/pymdl/mdl/ and src/pymdl/mudbug.py for what of it pymdl carries.
28. The package system
28. The package system is based on: The MDL Programming Environment, chapter 2, adapted; src/pymdl/mdl/libmud/npck.26 (the PKG package, MIT's own), src/pymdl/pkgsys.py (what pymdl puts around it: the scaffolding and the search), src/pymdl/subrs/oblist.py; the manual's chapter 15 (this book's chapter 18) for OBLISTs and BLOCK.
29. Program writing and debugging aids
29. Program writing and debugging aids is based on: The MDL Programming Environment, chapter 3, adapted (the scan's text layer restored against the page images where the transcription had failed, chiefly in the EDIT transcripts and the command summary); src/pymdl/mdl/mudbug/ (the tools themselves: pprint.mud, edit.mud, debugr.mud, trace.mud, monitr.mud, findatom.mud, pinfo.mud, dfl.mud, unlink.mud, critic.mud, grload.mud, env.mud, frmsp.mud, frand.mud, cursor.mud, emonit.mud, mend.mud), src/pymdl/mudbug.py (how they are loaded), tests/test_mudbug.py, tests/test_rdb.py.
30. The library system
30. The library system is based on: The MDL Programming Environment, chapter 4, adapted; src/pymdl/mdl/libmud/ (npck.26, the package system; nl.2, the L utilities; nlib.17 and nlibma.1, the library reader; nlup.72 and nlupcr.8, the librarian), src/pymdl/pkgsys.py, src/pymdl/subrs/nlibdb.py, tools/build_mdllib.py, src/pymdl/pymac/dbmain.py; tests/test_nlib.py, tests/test_library_system.py; tests/data/libmud-1976.nlib and .dat (MIT's 1976 library), tests/data/libmud-9006255.nlib and .dat (the 1983 one).
31. Making it run faster
31. Making it run faster is based on: The MDL Programming Environment, chapter 6, adapted (including its last page, which the vendored transcription had dropped); src/pymdl/mdl/mudbug/glue.mud (MIT's ELMER), pdump.mud, subrfy.mud, purity.mud, clean.mud, gluer.mud; src/pymdl/pymac/templt.py, temhlp.py, temhak.py; src/pymdl/ndem.py (the maintainer demon); tests/test_mudbug.py, tests/test_template.py.
32. Informational aids
32. Informational aids is based on: The MDL Programming Environment, chapter 8, adapted; src/pymdl/mdl/mat.mud (MAT, MIT's 1982 source), src/pymdl/mdl/matxgp.mud (pymdl's extension), src/pymdl/mdl/inquire.mud (the MDL side of MUDINQ, 1976); src/pymdl/mudcom.py, src/pymdl/mudinq.py; tests/test_mat.py, tests/test_mudcom.py, tests/test_mudinq.py.
33. Compiled programs and their files
33. Compiled programs and their files is based on: The MDL Programming Language, chapter 19, adapted; The MDL Programming Environment 5.3 and 7 for the file formats; subrs/rsubrs.py, eval.py (the RSUBR apply path), reader.py (_read_nbin_rsubr), its36.py, subrs/nlibdb.py, pdp10.py (apply_fixups, execute_rsubr, execute_pcode).
34. The compilers
34. The compilers is based on: The MDL Programming Environment, chapter 5, adapted; src/pymdl/pymac/compile.py (the COMPILE package), src/pymdl/pycomp.py (the native compiler), src/pymdl/subrs/embed.py (PYCODE, PYDEFINE, the PYCOMPILE family, the object-file sidecar), tools/era_compiler.py, tools/era_oracle.py, tools/era_selfhost.py, tools/era_refusals.py, src/pymdl/mdl/compil/ and its CHANGES.md.
35. The assembler
35. The assembler is based on: The MDL Programming Environment, chapter 7, adapted; src/pymdl/mdl/mudbug/coding.mud (the assembler, MIT's mprog/assem.undr88 of January 1979), mudbug/op.mud (the opcode table), mudbug/unassm.mud, mudbug/rdb.mud, src/pymdl/mudbug.py (how the tools are loaded), src/pymdl/subrs/squoze.py (SQUOZE, SQUOTA, MUDOBJ, the MUDREF reader and printer), src/pymdl/ddt.py (the superior DDT), src/pymdl/mdl/compil/ (atosq.ucr005, wofch.mud, popwr2.mud) and its CHANGES.md, tests/test_assembler_listener.py, tests/test_assembler_reconstructions.py, tests/test_rdb.py.
36. The PDP-10 inside
36. The PDP-10 inside is based on: src/pymdl/pdp10.py (the processor and the interpreter services), src/pymdl/pdp10_word.py (the word), src/pymdl/pdp10_its.py (the operating system underneath), src/pymdl/its36.py (the 36-bit file format), src/pymdl/ddt.py; tests/test_pdp10.py, tests/test_its_call.py, tests/test_its36_decode.py, tests/test_type_codes_era.py, tests/pdp10census.py; tools/emubench.py, tools/apsim_difftest.py, tools/kl10_difftest.py. No era manual describes this chapter's subject, because on the era it was the machine.
37. Asking the era
37. Asking the era is based on: tools/era_session.py, tools/era_oracle.py, tests/test_mdl55_oracle.py, tests/era_battery/ (its README and the five generators), tools/mdl55_errhandler.py, tools/mdl55_errors.py, tools/era_saves.py, tools/book_harvest.py; the Measured and Found along the way boxes throughout this book. No era manual has a chapter like this, because on the era the machine was in the next room.
38. Era artifacts
38. Era artifacts is based on: src/pymdl/mdl/MANIFEST.tsv and tools/mdl_manifest.py, tests/data/era/MANIFEST.tsv and tools/vendor_era_data.py, src/pymdl/mdlsave.py, src/pymdl/gcdump.py, src/pymdl/its36.py, src/pymdl/subrs/nlibdb.py, tools/era_tape_code.py, tools/era_tape_diff.py, tools/era_source_audit.py, tools/era_source_outliers.py, tools/era_source_ab.py; tests/test_mdlsave.py, tests/test_era_binaries.py, tests/test_its36_decode.py.
Reference material added in this review
Appendix H incorporates the language book's complete “A Look Inside” appendix, with its diagrams and an explicit distinction between historical memory layouts and pymdl's Python representation. Appendix I incorporates the language topic and name indexes and all 146 recoverable environment index terms; its destinations are chapters in this book. Appendix J retains the substantive front matter of both source books and the original language book's distribution record. Reconstructed title-page layout and duplicate tables of contents are replaced by publication details and this book's own contents. Appendices B and C now include the complete source tables of type classification and error explanations, generated from the vendored texts.