Types and Programming Languages (2002)
mitpress.mit.edu
mitpress.mit.edu
What I like most about Pierce's book is that he introduces each concept with a formal, abstract definition, complete with proofs of correctness, but also follows that up with a concrete implementation in OCaml. The latter is very easy to follow if you've had some experience with the ML family of languages. I sometimes find myself skipping ahead to the OCaml version when I get lost in the math syntax, which for me is less familiar. I'm planning to come back to Harper's book later, but Pierce's book is the perfect fit for where I am now.
My only criticism is that some parts are very dated given it hasn't been updated in almost 20 years. In particular, the version of Java he discusses throughout the book (pre-generics, pre-type-inference) bears little resemblance to the modern one. And since 2002 we've seen affine types (e.g. Rust) start to have mainstream influence, among other things.
In case it's helpful, I'm compiling a list of resources as I learn type systems, logic, category theory, etc.:
https://gist.github.com/dicej/d1117e5d65155d750c16234e6eff16...
Some of the citations in that paper are also interesting.
I don't think there is a core calculus that specifically incorporates generics as in Java, but I could be wrong. In any case, much of Java's generics flow from theories of parametric polymorphism [2], specifically I believe bounded parametric polymorphism [3].
[1] https://www.researchgate.net/publication/220877645_Welterwei...
[2] https://www.cs.cmu.edu/~fp/courses/15814-f18/lectures/11-pol...
[1] https://www.cis.upenn.edu/~bcpierce/papers/fj-toplas.pdf
Definitely check out the website for the book, lots of materials there: https://www.cis.upenn.edu/~bcpierce/tapl/index.html
Benjamin Pierce is also the author of Software Foundations: https://softwarefoundations.cis.upenn.edu/
Software Foundations is a book in Coq, where you need to prove theorems to compile the next chapters and such.
https://github.com/blanchette/logical_verification_2020
This is a tipping point work making the case that type theory is like a musician reading sheet music. Sure, the Beatles couldn't, but... Anyone developing a new programming language should understand languages at the level of Lean, even if the common uses of their constructs aren't theorem proving. The analogies are mind-blowing. Monadic parsing is the same thing as meta-programming tactics? I'm still wrapping my head arond that one.
For the latter, I assume type theory would be essential if you’re trying to design a language like Haskell, but irrelevant if you’re trying to design a dynamically-typed language like JavaScript? Would it be useful for the designers of “in-between” languages, like Java or Go?
i think the first lesson on programming language design is to not design a language like javascript
You introduce types to try to describe the program state in a way that a static analyser is able to prove that the program will not reach erroneous states. You learn that types limit computing: the simply typed lambda calculus always halts. Note that a human reader is a type of static analyser.
You start introducing more advanced types to try to get back that unbounded possibility: to be a real programming language, you need the halting problem--a real server doesn't halt.
Anyways, after some chapters you learn that you may need a lot of rather advanced type theory to truly describe some of the complex things that some crazy people did in previously dynamically typed languages. That's why python type hints and typescript sometimes (but not usually) need some really crazy stuff: people were able to and did do all kinds of crazy things.
Arguably, there are easier ways to solve a problem than the way that requires advanced type theory to describe. The dynamic languages don't make it easier to write, verify and reason about such code other than the fact that many static languages prevent it outright.
The formalisms introduced in the book are absolutely applicable to dynamically typed languages (such as JavaScript) and "less strict" statically typed languages like Java and Go. The book teaches you that there is a logic framework which you can use to analyze any programming language you can think of. It's not something you use in everyday life but it is very interesting!
I found working my way through it tough going. I'm not a natural mathematician, and found the "formalisation first" approach quite difficult to deal with. I would definitely have found it easier if each type judgement (formula) had a natural language description to go with it: intuition to complement the formality. The code helped in that regard.
That's a comment I have with many mathematical / formal texts. I wish authors would write down, in natural language, what they 'hear' in their heads when they read an equation on the page. Some at least have a reference (e.g. "read an upside down 'A' as 'forall'"). (I know it's more nuanced than that: someone experienced with type judgements won't interpret them literally. But even still, they could 'read out' what they see on the page).
Having said all that: I did find the book helpful and insightful. Just quite difficult to parse and assimilate the formal content. It certainly gave me a much better appreciation of type systems.
After you do enough of these, you'll start to see the common pattern, and wish there was a way to abstract over them. Surprise: there is!
This is basically I assume monads were developed as well.
This was good background for me to have to be able to understand the development of evolving programming languages built on academic formalism, like Scala.