I was a TA for a programming languages course taught using this book, and it was one of the most enlightening experiences I've had: Implementing interpreters in Scheme to learn about recursion, environments, closures, objects, continuations. I think of it kind of as the dual of a course on developing a compiler for a static languages.
Studying programming languages has the same side effects as studying AI. You have to learn some broadly applicable programming tricks to get your programs running. I see closures everywhere after writing my own programming language. Someone might use backtracking in a new domain after studying AI.
It's hard to explain but it was a feeling I got. It felt like the language fell into place on it's own when you added stuff and not in a way other code projects do. Parsing with flex/bison "naturally" converged syntax towards other languages because other languages are made so they are easy to write grammar for etc. Whether an "if(exp)" introduces a scope of is own is just down to where you happen to put the push_scope() call, and so on.
I wonder how much of C that was just "that is how it happened to turn out".
People add language features because they're easy to do in the implementation they already have, not because they're well-principled.
Concrete example from personal experience:
All objects in Ruby have a unique ID. The standard implementation of Ruby added a function to go from the ID to the object. This was easy on the standard implementation of Ruby, because the ID is just the pointer, so you can just cast it. It's a nightmare on more sophisticated implementations of Ruby where an object may not have a single canonical address that you can use as an ID, and you need to store a huge separate mapping.
Yeah, once you introduce moving garbage collectors that happens. I'm sure ruby isn't the first language to have made that mistake (I believe some implementations of SQL actually have similar, a reference to the row on disk, and it turned out to be a short-term gain and a long-term mistake).
My (tiny) CS department has a pretty nice compilers course, I thought. You work on a single, ~10k LoC file [0] that is written in a subset of C, compiles that subset to RISC-V, and also has a small VM and even a hypervisor for running the code it generates. The only thing is, the video lectures are 8 years old [1]. Though last semester, all lectures were online and anyone could join. Might be the same next spring/summer. You’d have to check the professor’s Twitter account.
Maybe check this bibliography [1] of "Resources for Amateur Compiler Writers"... although I'm not sure what's the "Amateur" part of it... it lists several text books and papers that would take anyone a few years to work through :-/
https://thorstenball.com/books/ seems like a good star, and if you don't know Go it shouldn't take too long to get acquainted with it.
Dr.Racket has a `#lang eopl` to support the second/third editions: https://docs.racket-lang.org/eopl/index.html
The first edition seems to build a tower of abstractions gradually, than directly jumping into the deep end of the pool. But getting code from first edition to run on Dr.Racket is quite a trouble. Can someone well versed with Racket macros, please write `define-record` to work with `#lang eopl`? I can figure out the macros with some effort, but cant quite figure out how to extend an existing lang.
Just tested and `(require foo)` works fine in `#lang eopl`.
That is, if you define `define-macro` and put it in package, say, `eopl1`, then you can use
Thank you for that pointer. I have been trying a few approaches but hit a serious wall. I have a write up on what I tried so far. Could you please take a look and give me some pointers/feedback? Thanks in advance! https://gist.github.com/kesava/ec1518495387928d35ec9fc5a764d...
I read EOPL independently in high school, and I thoroughly enjoyed it because it had a good balance between theory and practice. I would consider Types and Programming Languages to be theory-based, EOPL in the middle and SICP to be practice-based. (My personal order was SICP -> EOPL -> TAPL)
It's a great exercise to implement[0] the languages from EOPL. I think it fits a lot better in a statically typed language like Haskell (the parsing can be done with parser combinators), since they essentially have to re-create ADTs with macros in Scheme, when they could be easily embedded into the host language. The effectful interpreters could have their effects encapsulated in a monad transformer stack.
I would also suggest "Concepts, Techniques, and Models of Computer Programming", "How to Design Programs" (second edition: https://htdp.org/2020-8-1/Book/index.html), and the books in "The little X" series (such as The little schemer).
The MIT Press site implies there might be a Kindle edition for this, but the Amazon store page doesn't mention one. It also offers etextbook rental, but the link goes to a page with no options for that afaict. I see where there are epubs offered online for prior editions, but they look sketchy. Is this textbook legitimately available in any ebook format?
between this book and Programming Language Pragmatics ( Michael Scott ), which is the better book ? (the are both very expensive, I can only afford one, if there is another less expensive and just as good or better option, please recommend)
A used first edition of EOPL is way cheaper and far better in developing the subject matter than the latter versions. There is even a chapter on Type checking and interference: ftp://ftp.cs.indiana.edu/pub/techreports/TR491.pdf
The way I'd put it is that later editions are more focused on classroom use, while the first edition felt closer to my interests as a hacker. The later editions do have many improvements like a nicer development of the CPS transformation, but they also dropped the chapter on compiling by transforming an interpreter, and so on.
This is curious to me. Because I first bought the 3rd and latest edition of this book, as you do, but then I read reviews that the 2nd edition was superior. So I picked up the 2nd edition since I saw it for a cheap price used. Now, here I am reading that the 1st edition is better. Haha.
What would you recommend for someone to start with regarding this particular book? (I haven't gone through the book yet.) Is there a technical reason why material was changed so drastically, or is it more along the lines of streamlining things for a university course? Are the things left out in the subsequent editions interesting but not useful or are they interesting and useful but not conducive to fitting into a one or two semester course sequence?
Really I don't feel up-to-date enough to give great guidance. I worked through most of the problems in the first edition back when it came out, and it significantly influenced my approach to programming. With the later editions I gave them a pretty superficial read. There are other newer textbooks like Shriram Krishnamurthi's which I haven't read at all.
I don't think the first is 'better', but as examples of how it was more fun there's the compiler chapter and an OOP chapter with a small OO language organized around metaclasses instead of what I remember as a more tedious development of Java-style OO in a later edition. I'd still expect the latest edition has the most to learn from if you're picking just one.
Thanks! It sounds like a good approach would be to work diligently through the 3rd and then circle back on the 1st and 2nd to pick up the little spots that didn't make it. The metaclasses thing seems pretty interesting.
This book has been waiting on me to go through it. It's on the list with finishing SICP and also PLAI.
Programming Language Pragmatics is much more a reference book, to dip into for a not-too-theoretical discussion of a broad range of PL topics. EOPL is all about understanding fundamentals by implementing interpreters, with code that builds through the book. I use both, but I would choose EOPL as the book for a "proper" course in programming languages.
Apart from Coursera's course "programming languages", are there any other courses which teach interesting concepts from different programming languages instead of zeroing on 1 language.