{"slug": "textbooks-that-run", "title": "Textbooks that run", "summary": "Anil Madhavapeddy's NPTEL course \"Functional Programming with OCaml\" has enrolled 1,227 students in its first run, using a browser-based textbook that lets students edit and execute OCaml examples with nothing to install. The author said the coding agent performed well at building the platform, but producing learnable material took far more work, and he cited prior hands-on workshops where roughly a third of session time went to environment setup. The course addresses learners spread across India with differing operating systems, shared computers and unreliable internet by offering in-page execution and an offline option.", "body_md": "This is a written version of my talk at IndiaFOSS 6.0 in Bengaluru\non 26 September 2026. The slides are available as\n[a PDF](https://kcsrk.info/slides/OCaml_NPTEL_IndiaFOSS_2026.pdf) and\n[a Keynote file](https://kcsrk.info/slides/OCaml_NPTEL_IndiaFOSS_2026.key).\n\nI want to tell you the story of the book I wrote for my NPTEL course,\n*Functional Programming with OCaml*. The first run is underway, with\n1,227 students enrolled. The [book](https://fplaunchpad.org/ocaml_nptel/)\nruns in the browser: students can change the examples and execute them\nright in the page, with nothing to install.\n\nBuilding it also taught me something about working with coding agents. The agent did well at building the platform. Writing material that a student could learn from took much more work.\n\nFor those unfamiliar with [NPTEL](https://nptel.ac.in/), it is a\nplatform for online courses, primarily from the IITs and IISc. The\nlecture videos are freely available, including on YouTube. Students\ncan also take a proctored examination for certification, and many\ncolleges and universities recognise NPTEL course credits.\n\nI think NPTEL is one of the greatest collective achievements of Indian academia. There are courses by excellent teachers on foundational subjects. Earlier this year, I noticed that it did not have an OCaml course and decided to teach one.\n\nProgramming languages are learnt by poking at them. You change a program, run it, and see what happens. How was I going to give 1,227 students a working OCaml environment?\n\nThese students are spread across India. Some may share a computer; some may not have one of their own. They use different operating systems, have different levels of familiarity with their machines, and may have unreliable internet. There are also the learners who will watch the videos long after this run of the course has ended.\n\nRecording an NPTEL lecture means sitting in a small studio, speaking into a camera. I have two very good teaching assistants, but I do not get to interact with students as I would in a classroom. We cannot provide individual setup help to everyone.\n\nEven at IIT Madras, students arrive in my third-year course without much experience using a terminal. Installing OCaml asks them to use tools they are still learning how to operate. The OCaml Platform has made progress on installation, but there are still gaps.\n\nIn the hands-on OCaml workshops I have helped run, we have often spent about a third of the session getting the environment working on people’s machines. In a room, I can walk over and help. A remote learner who gets stuck at the first step may simply leave. I may never hear from them.\n\nI had tried to address this in earlier courses.\n\nFor CS3100, *Paradigms of Programming*, I taught OCaml and Prolog\nusing Jupyter notebooks in a Docker container.\n[RISE](https://rise.readthedocs.io/) turned the notebooks into\nreveal.js slides, and [nbgrader](https://nbgrader.readthedocs.io/)\nhelped with assignment evaluation. We used this setup for several\ncourse offerings, and my colleague continues to use it.\n\nBut the student still needed Docker, and the image was about 3 GB. The notebook editor did not have the language support we had come to expect from OCaml editors: types on hover, live errors, and code completion. The notebooks were also lecture material. They did not read as a standalone book.\n\nFor NPTEL, I wanted students to start immediately. Open a page and run some OCaml. I also wanted a way to use the material offline, so that a learning session would not depend on a reliable connection.\n\nThe editor should help them as they work: show types, report errors, and offer completions. Quizzes should give immediate feedback, in the same page as the explanation.\n\nOn the authoring side, I wanted one source for the textbook and the executable lecture slides. It should produce readable Git diffs, and the build should type-check and test the code examples.\n\nThe easiest way to see what this means is to\n[open the course introduction](https://fplaunchpad.org/ocaml_nptel/M01-L01-course-intro.html#run-code-right-in-this-page)\nand run an example. Change it and run it again. Hover over an\nexpression to see its type. The lecture can also be presented as\nslides, with the code still runnable.\n\nThe same approach extends to OxCaml, a performance-oriented extension of OCaml. For the systems material, there is a Linux VM in the page. Students can compile C programs and explore buffer overflows, use-after-free, and double-free errors in that environment.\n\nAnd programs can interact with the page itself. The\n[Joy examples from our IndiaFOSS workshop](https://fplaunchpad.org/indiafoss-2026-ocaml-workshop/06-joy.html#higher-order-transformations)\nshow another use for this: change a program and see its effect on a\npicture.\n\nMuch of this rests on [js_of_ocaml](https://github.com/ocsigen/js_of_ocaml),\na compiler from OCaml bytecode to JavaScript. The OCaml compiler is\nitself written in OCaml. So are [Merlin](https://github.com/ocaml/merlin),\nwhich provides editor intelligence, and\n[ocamlformat](https://github.com/ocaml-ppx/ocamlformat).\nWe can compile those tools to JavaScript too.\n\n[Arthur Wendling’s x-ocaml](https://github.com/art-w/x-ocaml) brings\nthese pieces together as a Web Component. Adding an HTML tag gives a\npage an executable OCaml cell with editor support. The compiler and\ntools run in the student’s browser.\n\nThe Linux environment uses [v86](https://github.com/copy/v86), which\ncompiles x86 instructions to WebAssembly as it runs. I build an Alpine\nLinux image with OCaml, dune, and the course projects preinstalled.\nThe student does not need Docker; it is part of how I prepare the\nimage.\n\nGetting to a shell takes about 12 MB of downloads. This is possible because the VM resumes a compressed snapshot instead of performing a cold boot, and fetches filesystem chunks as they are needed. That 12 MB is the initial shell, not the entire course environment. The VM executes locally, with no server running the student’s programs.\n\nThe book has both multiple-choice questions and programming puzzles.\nA student can test their understanding while reading, and get\nfeedback immediately. For example, the\n[tail-recursion lecture](https://fplaunchpad.org/ocaml_nptel/M03-L04-tail-recursion.html#a-small-code-challenge)\nincludes a small code challenge with tests.\n\nAnonymous quiz results also feed a\n[public dashboard](https://fplaunchpad.org/ocaml_nptel/dashboard.html).\nThe reader gets feedback about their understanding; I get evidence\nabout where my explanations may need work. I plan to use those results\nto revise the book.\n\nThis follows Will Crichton and Shriram Krishnamurthi’s work on the\n[Rust book](https://rust-book.cs.brown.edu/), where embedded quizzes\nhelped identify misconceptions and guide changes to the material.\nTheir study was at a much larger scale. My course is still in its\nfirst run.\n\nEach lecture is a Markdown file, with Pandoc-style fenced divs to mark slides and other elements. The same file contains the fuller textbook explanation and the material that appears on screen during a lecture.\n\nQuizzes are written alongside the prose, with their code, tests, and solutions. The test suite checks them too. It is a relief to be able to change a chapter and have the build check its executable content.\n\n[ocaml-mdx](https://github.com/realworldocaml/mdx) compiles and runs the\ncode examples. Other checks catch overflowing slides and broken\ncross-references. The source stays readable in Git, which helps when\nreviewing changes across lectures.\n\nThose checks are useful, but they leave another kind of review to do: does the explanation make sense to someone who is learning this for the first time?\n\nI started writing the book one day before the first recording session. I already had recordings of my CS3100 lectures from teaching during Covid, which gave me material to work from.\n\nI used ffmpeg to detect scene changes and identify slides in those recordings. A local Whisper model transcribed the audio, and a small script aligned each slide with what I had said about it. The agent could then see both the slide and its explanation. That became the basis for the book.\n\nThe first draft grew quickly: around 30,000 lines of Markdown on the first day. The book reached roughly 60,000 lines over a month. I primarily used Claude Opus 4.7 during that initial period. The platform was almost entirely built through agentic programming: roughly 9,000 lines of OCaml, JavaScript, shell, and other code.\n\nI have written more about the development and token usage in\n[An O(x)Caml book that runs](https://kcsrk.info/ocaml/oxcaml/teaching/nptel/llm/2026/06/13/an-oxcaml-book-that-runs/).\nHere I want to focus on how differently the platform work and the\nteaching material went.\n\nThe platform work went mostly well. I had little experience with\nfrontend development or building dashboards, and the agent helped me\nbuild those parts. It also helped with narrow compiler problems,\nincluding the work to\n[shrink an OxCaml library bundle from 285 MB to 4 MB](https://kcsrk.info/ocaml/oxcaml/modes/2026/05/10/shrinking-the-oxcaml-bundle/).\nThat required getting dead-code elimination across library boundaries\nwired up correctly.\n\nThe content writing went much less well.\n\nThe agent assumed too much about what the learner already knew. It used concepts before introducing them, jumped between ideas, and presented definitions without first explaining why someone would want them. It could answer my OCaml questions, but that did not make its explanations suitable for a beginner. It was a great oracle and a bad teacher.\n\nThis felt familiar. When I first moved from researching a specialised topic to teaching undergraduates, I had to learn to notice all the background knowledge I was assuming. The agent kept making similar mistakes.\n\nThe distinction is familiar in education too. Lee Shulman’s account\nof [pedagogical content knowledge](https://www.wcu.edu/webfiles/pdfs/shulman.pdf)\ndescribes the knowledge involved in making a subject understandable\nto others, including useful examples and an understanding of what\nlearners find difficult. Knowing the subject is only part of the job.\n\nI ended up writing down a set of instructions for the agent, refined through reviewing the chapters.\n\n**Use what is in the reader’s toolbox.** An explanation can use only\nconcepts the reader has already encountered. A fact being true does\nnot make it appropriate at this point in the course.\n\n**Motivate the idea before generalising it.** Start with a small\nexample that gives the learner a reason to care. Avoid jumping to an\nabstraction before they have seen the problem it addresses.\n\n**Make the slides carry the narrative.** Because the book and slides\nwere written together, the agent often assumed that someone watching\na slide had read the surrounding chapter. I expect many students to\nwatch the videos without reading the book first. The slides must\nmake sense in that setting too.\n\n**Give the student a fresh activity.** The agent sometimes turned a\nworked example into a quiz by asking the student to reproduce the\nsame code. The exercise needs to give them something new to do with\nwhat they have learnt.\n\n**Review with a fresh context.** It helped to have a fresh agent read\nthe preceding material, assume only the stated basics, and then\nreview a chapter. That reduced the influence of all the extra context\naccumulated while writing it.\n\nThese instructions helped, but I still had to review the material. The tests could check an example’s behaviour. I had to check the assumptions an explanation made about its reader.\n\nAI helped me build the platform and turn existing lectures into a book that students can use on their own. It also made the gaps in the teaching process very visible. Closing those gaps required decisions about examples, prerequisites, and what a student should do next.\n\nThe course seems to be going well so far. The examinations are due\nin October, and I plan to write a retrospective after the first run.\nFor now, you can [open the book](https://fplaunchpad.org/ocaml_nptel/)\nand try it. The course material is available under CC BY-NC-SA, and\nthe [source is on GitHub](https://github.com/fplaunchpad/ocaml_nptel).\nIf you teach, you are welcome to adapt it under those terms.\n\nI also closed the talk with a call for applicants to\n[FP Launchpad](https://fplaunchpad.org/). We have announced the second\ncohort of our post-baccalaureate fellowship. If functional programming\nand formal verification interest you, take a look.", "url": "https://wpnews.pro/news/textbooks-that-run", "canonical_source": "https://kcsrk.info/ocaml/teaching/nptel/llm/2026/09/26/textbooks-that-run/", "published_at": "2026-09-26 09:29:16.379974+00:00", "updated_at": "2026-09-26 09:29:18.319664+00:00", "lang": "en", "topics": ["artificial-intelligence", "ai-agents", "developer-tools"], "entities": ["NPTEL", "OCaml", "Anil Madhavapeddy", "IIT Madras", "IndiaFOSS 6.0", "Jupyter", "Docker", "RISE"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/textbooks-that-run", "markdown": "https://wpnews.pro/news/textbooks-that-run.md", "text": "https://wpnews.pro/news/textbooks-that-run.txt", "jsonld": "https://wpnews.pro/news/textbooks-that-run.jsonld"}}