Open-source project
hmemcpy/milewski-ctfp-pdf avatar
hmemcpy/milewski-ctfp-pdf

Category Theory for Programmers as a Buildable PDF: Inside hmemcpy/milewski-ctfp-pdf

Bartosz Milewski's 'Category Theory for Programmers' unofficial PDF and LaTeX source

11,693 stars643 forksTeXNOASSERTION

At a glance

What is it?
This repository turns Bartosz Milewski's blog series into LaTeX source and prebuilt PDFs in Haskell, Scala, OCaml and Reason editions. It is a book project with a Nix build, not a library you import.
Who is it for?
Adopt it if you want the book as a local PDF, a specific language edition, or editable LaTeX you can patch and rebuild with nix build .#ctfp-scala. Do not adopt it expecting an actively versioned release stream: the newest listed release is v36-98b71ac from 2023-01-30, so pin a tag or a commit rather than tracking master.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 82 days ago.
What is it written in?
Mainly TeX, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What the CTFP PDF repository actually contains

Bartosz Milewski's Category Theory for Programmers began as a blog series. This repository converts that series, with the author's permission, into a typeset book: LaTeX sources under src/, figures under src/fig, and a build system that produces PDFs. The README calls it an unofficial PDF version, which is the honest framing. The content is Milewski's; the typesetting and tooling came from Andres Raba's earlier work, adapted here.

The audience is narrow and specific. You are a programmer who wants category theory explained through code in Haskell, Scala, OCaml or Reason, and you want the text as a file you control rather than a web page. The repository also serves a second group: people who want to fix a typo, adjust a figure, or keep a local copy of the source. The README invites pull requests, and errata files such as errata-1.3.0.md and errata-scala.md track changes against the printed editions.

It is not a library, a package, or a service. Nothing here is imported into your program. The deliverable is a document.

How the LaTeX sources become four editions

The repository keeps one body of content and several entry points. The Makefile defines separate targets, each pointing latexmk at a different root .tex file in src: ctfp-reader.tex for the Haskell original, ctfp-reader-scala.tex for Scala, ctfp-reader-ocaml.tex for OCaml, plus print variants such as ctfp-print.tex and ctfp-print-scala. That is the whole data flow. Shared chapters live under src/content; the per-edition root file selects and includes them, so a code sample that differs between languages is a different file rather than a conditional inside one file.

The toolchain is XeLaTeX, not pdfLaTeX. LATEXMK_ARGS in the Makefile sets -pdflatex="xelatex %O %S" and -pdfxe, along with -shell-escape, -halt-on-error and -interaction=nonstopmode. The -shell-escape flag matters if you build outside the provided environment: it lets LaTeX run external programs, which is exactly the kind of thing you should only do with source you trust. The Nix flake exists to make that environment reproducible, so the TeX packages and fonts match what the maintainers tested.

Editions are not translations of each other in the machine sense. They are parallel renderings of the same chapters with different code, which is why the print editions of the regular and Scala books were built from the same release tag, v1.3.0.

Installing Nix and building the Scala edition

The README is explicit that the build workflow requires Nix. Install it from the Nix download page, then enable the flake feature, which the README says must be enabled manually at the time of writing. The repository ships flake.nix and flake.lock, so the dependency set is pinned.

Once flakes are enabled, the README's first step is to list what the flake exposes. Run this in the repository root:

bash
nix flake show

You should see the available book editions listed as flake outputs. Pick one and build it. The README gives the Scala edition as its example:

bash
nix build .#ctfp-scala

For the Haskell original, the README uses nix build .#ctfp. On success, the README states the PDF is placed in the result directory, which is the standard Nix symlink to the build output. That PDF is the finished book; open it with any viewer.

If you would rather drive the build yourself, nix develop gives you a shell containing the dependencies, and the Makefile targets then work directly. The README names make ctfp-scala as the equivalent manual command:

bash
nix develop
make ctfp-scala

The Makefile also defines a lint target that runs latexindent over every .tex file it finds, which is what you would run after editing a chapter.

Where the build is likely to bite you

The build depends on Nix and on flakes being enabled, and the README describes flake support as hidden behind a feature flag that has to be turned on by hand. If your Nix installation predates that or the flag is off, nix flake show and nix build will not work, and the README does not document a fallback path for that case. The Makefile is the fallback in practice, but it assumes a TeX Live environment with XeLaTeX and every package the book uses, which is precisely the setup the flake was written to avoid assembling by hand.

Second, the Makefile's latexmk invocation passes -shell-escape. That is normal for documents with generated figures, and it is also a reason to build only from source you trust, including pull requests you have not read.

Third, this is a book, not software with a compatibility contract. The newest release listed in the repository is v36-98b71ac from 2023-01-30. The last push to the default branch was on 2026-07-10, so the repository is not archived and work continues, but the release tags lag well behind that. If you need a stable artifact, download a release PDF or pin a tag rather than building master, because a commit between releases can leave the book mid-edit.

Finally, if what you want is an epub or a mobi, this is the wrong project. The build produces PDFs from LaTeX. There is no epub target in the Makefile.

Category Theory for Programmers versus other free category theory texts

The obvious comparison is with other freely available category theory books, and the difference is the intended reader. Milewski's text is written for programmers and carries code in Haskell, Scala, OCaml and Reason. A mathematics-first text assumes you are comfortable with proofs and notation before you see a line of code, and its examples are not tied to a programming language at all.

The second difference is the delivery. This repository gives you LaTeX and a reproducible build, so you can change the wording of a paragraph, correct a figure, or produce a version with your own annotations. A PDF-only download gives you none of that. That is the real reason to clone the repository instead of grabbing the release asset: you are choosing the source over the artifact.

The trade-off is that you take on a Nix and TeX toolchain. If you only want to read the book, the release PDF is the shorter path, and the repository README itself points readers to the printed editions on Blurb, one in full-color hardcover and one Scala edition in paperback, both published on 12 August 2019 and based on tag v1.3.0.

Licence terms for the text and the scripts

The repository splits licensing by file type, and the split matters if you plan to redistribute anything. According to the README, the PDF book, the .tex files, and the associated images and figures in src/fig and src/content are under Creative Commons Attribution-ShareAlike 4.0 International. The script files, with scraper.py named as an example, are under GNU General Public License version 3.

ShareAlike is the part to notice. If you publish a modified version of the book, the licence expects attribution and that derivative works carry the same terms. The repository's LICENSE file is the authoritative text, and the GitHub metadata reports the licence as NOASSERTION, which means the platform's classifier did not map it to a single SPDX identifier. Read LICENSE rather than trusting the badge. This is a description of what the files say, not legal advice; if you are republishing commercially, get your own answer.

Maintenance and the cost of tracking upstream

The last push to master was on 2026-07-10, and the repository is not archived, so the source is still being touched. The release cadence is a different story. The three most recent releases listed are v36-98b71ac on 2023-01-30, v35-d175452 on 2023-01-02 and v34-a325ca2 on 2022-09-19. That gap between ongoing commits and the newest tag is the upgrade cost in one line: if you depend on a tagged artifact, you are on a 2023 snapshot even though the branch has moved.

For most readers this costs nothing. You download a PDF and read it. The cost appears when you fork the LaTeX for your own edition. Then you are maintaining a patch against files that change, and the lint target plus the Makefile targets are your only documented checks. There is no documented rollback procedure and no migration guide between versions; the errata files describe corrections relative to the printed editions, not upgrade steps for a fork.

A practical approach is to pin the commit you built from and rebase your edits deliberately, rather than pulling master and rebuilding on a whim.

Editorial conclusion

Adopt it if you want the book as a local PDF, a specific language edition, or editable LaTeX you can patch and rebuild with nix build .#ctfp-scala. Do not adopt it expecting an actively versioned release stream: the newest listed release is v36-98b71ac from 2023-01-30, so pin a tag or a commit rather than tracking master. Before you build, verify that flakes are enabled in your Nix install and that your checkout contains src/ctfp-reader-scala.tex, because the Makefile targets fail without that file present.

Frequently asked questions

Is the milewski-ctfp-pdf download free?

Yes. The repository publishes the PDF and the LaTeX source, and the README states the book, .tex files and figures are licensed under Creative Commons Attribution-ShareAlike 4.0 International. Printed editions are sold separately on Blurb.

Which editions of Category Theory for Programmers can I build from this repository?

The README lists Scala, OCaml, Reason and their printed versions, with Haskell as the original. The flake exposes them as outputs, so nix flake show lists what is available before you pick one to build.

Do I need Nix to build the Category Theory for Programmers PDF?

The README states the building workflow requires Nix and that the flake feature must be enabled manually. The Makefile targets are an alternative, but they assume a TeX Live environment with XeLaTeX and the packages the book needs.

Official sources

  1. hmemcpy/milewski-ctfp-pdf on GitHub
  2. Issues
  3. Project website
  4. README
  5. Releases
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/hmemcpy-milewski-ctfp-pdf.svg)](https://hysenlabs.com/projects/hmemcpy-milewski-ctfp-pdf)