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 ATOM T, "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 ```mdl block in docs/pymdl/*.md is executed against a fresh interpreter by tests/test_book_examples.py, and an answer written after must match. A block marked ```mdl-x is 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; --check verifies 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, 19 CHANGES.md sections 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-1987 archive -- the MIT tapes and dumps that everything in src/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 the arith module chapter 6's RANDOM was 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.