This past long weekend, I reread an old favourite of mine: "The Implementation of #Functional #Programming Languages", Jones (1987). I haven't touched this book in years; it jogged many a fond memory.
The subject matter of this book is implementing non-strict (lazy) FP languages on a graph reduction VM called the G-machine. Jones's customary no-nonsense presentation style cuts cleanly through the dense thicket of compiler theory. It is a great classic text for all #ComputerScience students studying compilers.
An advantage this book offers, especially to the undergraduate students, is its practice-oriented description of 𝜆-calculus, which is in stark contrast to most other textbooks on this theory. Since Jones's compilers target 𝜆-calculus as the intermediate language, his presentation is necessarily pragmatic. This enables the students to grasp not only the denotational semantics, but also the operational semantics, of executable 𝜆-calculus—a rare gem amongst the countless texts on this theoretical subject.
The best bit is that Jones made his book public domain on Microsoft Research site.
https://www.microsoft.com/en-us/research/wp-content/uploads/1987/01/slpj-book-1987-small.pdf
Similarly accessible—but less practice-focused—introductions to 𝜆-calculus can be found in these textbooks:
• "An Introduction to Functional Programming through 𝜆-Calculus", Michaelson (1989)
• "Functional Programming: Practice and Theory", MacLennan (1990)
The students should read at least one (preferably all) of these introductory texts, before reaching for "The 𝜆-Calculus, its Syntax, and Semantics", Barendregt (1981) or "Computational 𝜆-Calculus and Monads", Moggi (1989).