PLFA: An Agda Introduction to Programming Language Theory
An introduction to programming language theory in Agda
At a glance
- What is it?
- PLFA is an online book and Agda source repository for studying programming language theory through mechanized proofs. Its main constraint is version sensitivity: the documented setup fixes Agda 2.7.0, GHC and Cabal versions, and a bundled standard library.
- Who is it for?
- PLFA suits readers who want formal programming language definitions paired with Agda proofs and are willing to use its documented toolchain versions. It is a poor fit for readers seeking a version-tolerant IDE, a general Agda starter project, or a book that can be completed without configuring Haskell libraries.
- Can I use it commercially?
- Yes, with credit. CC-BY-4.0 allows commercial use as long as you credit the authors and indicate what you changed. It is written for creative content, so check how it applies to any code.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly Agda, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 21, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Why PLFA Couples Language Theory with Agda
PLFA addresses readers who want programming language theory represented as executable, checked material rather than only informal descriptions. Its subject is the connection between language definitions and Agda's type system: syntax, semantics, typing rules, and proofs can live in the same source tree. The online edition is useful for reading because it requires no local installation. Interacting with the formal content is a separate path that requires Git, GHC, Cabal, Agda, the Agda standard library, and PLFA's library configuration.
The repository supports that broader study environment rather than acting as a single executable tool. Its top-level entries include `book/`, `courses/`, `papers/`, `src/`, and `web/`, while `standard-library` is present as a submodule target. That layout indicates that published material, source modules, supporting references, and the website build are distinct concerns. A learner can therefore read the hosted book while still choosing whether to set up the source for exercises and interactive Agda editing.
PLFA is not an introductory Agda package in the narrow sense. The installation instructions explicitly select Agda 2.7.0 and warn that package managers may provide older releases. They also warn that development versions can introduce incompatible changes. This makes the repository more version-sensitive than a current generic Agda example, but it also gives readers a documented compatibility target instead of asking them to infer one.
PLFA Repository Layout and Build Data Flow
The website build is driven by the top-level `Makefile`. Its default target is `build`, which first creates `_cache/reports/`, updates Cabal's package index, and runs the repository's `builder` application. The builder receives parallel execution, linting, timing data, and an HTML profile path under `_cache/reports/build.html`. The output directory is `_site`.
The documented build sequence is:
make buildThis command invokes the documented Make target. The expected destination is `_site`, although the README excerpt does not describe every prerequisite for building the site. The repository's `cabal.project` and `plfa.cabal` entries indicate that Cabal participates in the build, while `package.json` defines development tools for browser serving, HTML validation, minification, and Sass processing.
The `Makefile` also defines `clean` and `clobber`, which run the builder with the corresponding cleanup action. A `watch` target uses `fswatch` to watch file changes and passes detected paths to `make build`. This is a source-based book project with a generated site pipeline, not merely a directory of Markdown files intended for manual editing.
Agda content has its own setup path. PLFA is cloned as a Git repository, its `standard-library` submodule is initialized, and files from `data/dotagda/` are copied into the user's Agda configuration directory. The configuration exposes `standard-library` and optionally `plfa` as Agda libraries. In other words, reading the generated website, checking Agda source, and watching local edits are related tasks, but the Makefile does not replace the separate Agda installation and library configuration.
Installing PLFA with the Documented Agda Toolchain
On macOS, the README recommends installing the Xcode Command Line Tools with the following command. macOS presents the command as an installation action rather than printing a complete setup transcript.
xcode-select --installGit can be checked with:
git --versionBecause Agda is written in Haskell, the setup also requires GHC and Cabal. The documented example installs GHC 9.4.8 and Cabal through `ghcup`:
ghcup install ghc 9.4.8
ghcup install cabal recommended
ghcup set ghc 9.4.8
ghcup set cabal recommendedThe README says PLFA should work with any GHC version at or above 8.10, but it is tested with versions 8.10 through 9.8. The example is therefore a concrete installation route, not a declaration that every compiler version behaves identically.
Install the Agda version selected by PLFA through Cabal:
cabal update
cabal install Agda-2.7.0The README warns that this step takes a long time and uses substantial memory. After it completes, clone PLFA into the home directory. The `--depth 1` option creates a shallow clone, which is appropriate to the exact command published by the project:
git clone --depth 1 https://github.com/plfa/plfa.github.io plfaPLFA ships with the required standard-library version as a Git submodule. Initialize it from the cloned directory:
git submodule update --initThis step is not optional decoration. Without it, the referenced standard-library content is not initialized, so the local Agda setup may not match the environment PLFA expects.
Registering PLFA Libraries in AGDA_DIR
Agda must be told where to find PLFA and its standard library. On macOS and Unix, the README gives a copy-based setup for users without existing configuration files that they want to preserve. After placing `plfa` in the home directory, run:
mkdir -p ~/.agda
cp ~/plfa/data/dotagda/* ~/.agdaThe copied files provide access to both the standard library and PLFA as Agda libraries. This shortcut should not be used blindly when existing `AGDA_DIR` configuration matters, because the README explicitly presents it as a path for users who do not have files they wish to preserve.
The manual model requires two plain-text files under `AGDA_DIR`. The `libraries` file must contain the absolute or otherwise usable path to `standard-library.agda-lib`, expressed relative to a `PLFA` path such as `~/plfa/standard-library/`. The `defaults` file must contain just `standard-library`.
To import modules from the book, the reader must also add the path to `PLFA/src/plfa.agda-lib` to `AGDA_DIR/libraries`, then add `plfa` on its own line in `AGDA_DIR/defaults`. On Unix and macOS, `AGDA_DIR` normally means `~/.agda`. On Windows, the README says it usually means `%AppData%\agda`, which commonly resolves below `C:\Users\USERNAME\AppData\Roaming`.
This is a concrete limitation for shared machines and existing Agda users. PLFA does not remain isolated from global library discovery. Its library registration edits files that Agda uses more generally, so preserving and merging those files is part of a careful setup.
Opening Agda Source with Emacs
The README identifies Emacs as the recommended Agda editor and points to GNU Emacs, Aquamacs, and platform-specific download pages. Once Agda is installed, its built-in editor support can be configured with these commands:
agda-mode setup
agda-mode compile`agda-mode setup` appends configuration to `.emacs`, while `agda-mode compile` compiles the configuration. These commands provide a first real interaction with the editor setup described by the project. Readers who already maintain a customized Emacs configuration should inspect what setup changes before preserving their existing file.
The README also discusses literate files with the `.lagda.md` extension. Since Emacs selects Markdown mode based on the `.md` suffix by default, the recommended configuration includes an `auto-mode-alist` adjustment so both `.agda` and `.lagda.md` files can load `agda-mode`. The shown configuration begins as follows:
(setq auto-mode-alist
(append
'(("\\.agda\\'" . agda2-m)The excerpt is truncated, so it should not be treated as a complete Emacs configuration. Its purpose is specific: associate Agda source extensions with the appropriate mode. This makes PLFA usable as a source-based proof project rather than only as a browser reading experience.
The README does not document a command for checking a particular PLFA exercise from a clean checkout. It links to Agda's own hello-world test as a way to confirm that Agda is installed, but the first PLFA-specific source operation documented here is editor configuration. Any further chapter-specific invocation would need to come from the relevant PLFA material.
Version Drift, Release History, and Upgrade Cost
PLFA's maintenance cost is tied closely to its Agda dependencies. The README says the project is tested against specific Agda and standard-library versions, and that changes in either can break PLFA. This warning is more important than a simple statement that the project is written in Agda: adopting the source means accepting a particular compatibility point.
The repository's recent release history includes `v22.08` from 2022-08-25, `v20.07` from 2020-07-14, and `v19.08` from 2020-07-15. Those labels and dates are repository facts, but they do not by themselves establish compatibility with a particular local environment. The installation instructions instead point readers to the tested versions represented by the repository configuration and badges.
The repository is not archived. Its last push was on 2026-10-12. That recency does not remove the documented dependency risk. In fact, the README's warning about rapid Agda and standard-library changes means that readers should interpret repository activity separately from compatibility of their installed toolchain.
Upgrading Agda is not presented as a simple package update. A different Agda version, a different standard library, or a development build may require changing the installation and library setup again. PLFA is distributed under `CC-BY-4.0` according to the repository metadata. The README excerpt does not provide legal guidance about particular reuse, so the relevant operational cost is clear while the licence interpretation is outside this review.
Editorial conclusion
PLFA suits readers who want formal programming language definitions paired with Agda proofs and are willing to use its documented toolchain versions. It is a poor fit for readers seeking a version-tolerant IDE, a general Agda starter project, or a book that can be completed without configuring Haskell libraries. Before adoption, check that Agda 2.7.0, the bundled standard library, the selected GHC version, and the local `AGDA_DIR` configuration match the lesson being used, because PLFA explicitly warns that toolchain changes can break the code.
Frequently asked questions
Do I need to install PLFA to read the book?
No. The README says PLFA can be read online without installing anything. Installation is required only when a reader wants to interact with the code or complete the exercises.
Which Agda version does PLFA use?
The README states that PLFA uses Agda 2.7.0. It also warns against older, newer, or development versions because changes in Agda and the standard library can break the code.
How do I make PLFA available as an Agda library?
Clone the repository, initialize the `standard-library` submodule, and add `PLFA/src/plfa.agda-lib` to the `AGDA_DIR/libraries` file. Add `plfa` to `AGDA_DIR/defaults`, using `PLFA` as the path to the repository root.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/plfa-plfa-github-io)