Recommending "Design concepts in programming languages"

Hi. To all those people who are in any sense interested in PL theory I'd like to recommend the book "Design concepts in programming languages", because I am extremely impressed with it and because I, surprisingly, have not heard much about it. So, the book is about various concepts encountered in various kinds of programming languages: denotational and operational (BOS/SOS) semantics, issues of state and control, type systems, modules, modeling effects and compilation. Every concept is introduced by defining the semantics of a language that has this concept and exploring the design dimensions and issues of this concept and language. Concepts are gradually accumulated, and by the time you reach the chapter on modules you've got a CBV language with records, mutable state, polymorphic algebraic data types, a System F type system with type inference and a hint of dependent types, abstract data types and first-class dynamically loadable modules. The tools used for description are of course the good old denotational and operational semantics and typing judgements and derivation trees; but each element of those is clearly and succintly described in text; it happens to me all the time that I am reading a type reconstruction algorithm and wondering, "why does this rule have that restriction?" and it immediately turns out that in the next paragraph, the authors focus attention on why this rule has that restriction; just like if they were reading my thoughts. That's why this book feels very comfortable to me: I am absolutely sure that I won't encounter a point where I am lost and buried under the notation; but there is also not a single boring moment. I've been interested in functional programming and PL theory for 2-3 years already, and here's a brief list of the *new* things that I have learned, at least: - What do SOS and BOS mean, and why one should care, and what properties a SOS might posess (confluence and normalization, for instance) - How many features of languages can be defined in terms of simply desugaring, and how in some cases they can't - How one might use monadic style in the semantics metalanguage to greatly simplify the semantic rules for monadic concepts like state, control and error handling (the authors mention the word "monad" only once, but they use return- and bind-like operators in their semantics) - How powerful records are, and of what use are operators like "conceal" - What use is subtyping outside of OOP - How does one define CPS-style semantics and how such a style allows to add state, control and errors with minimal changes - How small yet powerful an OOP language core can be - How algebraic datatypes can be very useful in a language without static typing - How pattern matching can be desugared into CPS-style deconstructors - How many caveats are there in defining typing rules, and how a small change in them can lead to very big changes in language expressiveness - How HM type inference actually works - Why purity is important for certain polymorphism issues - What let-polymorphism means - What effect systems are - How effect reconstruction works and how it is different from type reconstruction in nature - How effect inference can prove the external purity of certain internally impure programs That's where I finished my reading for now. The remaining looks even more intriguing; for example, I don't (yet) know how functional languages are compiled and how register allocation is done. I'm afraid to sound like a salesman, but this is absolutely the best-written technical book I have ever seen in my life, and probably the most influential one for me, excluding probably SICP. Here you can check out its table of contents: http://cs.wellesley.edu/~fturbak/pubs/6821/current/contents-nov22.pdf I was impressed with the TOC even before buying the book, but turned out that I was greatly under-estimating it. Well, that's it :) -- Eugene Kirpichov Web IR developer, market.yandex.ru

2009/4/30 Eugene Kirpichov
Hi.
To all those people who are in any sense interested in PL theory I'd like to recommend the book "Design concepts in programming languages", because I am extremely impressed with it and because I, surprisingly, have not heard much about it.
I concur, it is a wonderful book; a great resource. Bernie.

jkff wrote:
To all those people who are in any sense interested in PL theory I'd like to recommend the book "Design concepts in programming languages" [...]
I ordered the book because of your description, and I agree completely. Besides the core points you already mentioned, it's also interesting to note what the book does not do (on purpose, for clearer exposition) * concepts are defined mathematically, and for each, a "mini" language is given that contains the concept (and not much else). and, there's lots of exercises (relating to these languages). - the book is *not* a review of how the design concepts are realized in different "real" programming languages. (There's other books that do this.) * the book avoids discussions on concrete syntax and parsing theory. Of the > 1200 pages, about 26 are on syntax, and it's just S-expressions. Again, very reasonable choice. * what they call "Pragmatics" contains a nice 100 pages on code generation that could be used in a compiler construction course. The approach is transformational: source, intermediate, and target languages are actually different subsets of one common language. The advantage is that you can discuss many small-step transformations, and still need only one semantics definition (and for implementation exercises, you could use one and the same interpreter for each). nit-pickingly, though: * Section 17.6.1 (in the "Compilation" part) tries to explain why the intermediate language is not explicitly typed. Using phrases like "explicit type information is often larger than the code it describes", "specifying each compiler stage becomes more complicated" etc. Well, this sounds like the typical "practicioner's complaint" that type systems may be nice, but only get in the way if you're doing real work. * in the Appendix on notation, he defines composition of functions the "wrong way around" (i.e., the Haskell way, (f.g)(x) = f(g(x)). This is of course very awkward, especially considering that functions are relations, and an element of a relation is a directed edge, and there's a very obvious meaning of how edges are composed to give a path. Well, the book's "solution" is to avoid to define composition of relations! (p. 1155, they only define the n-fold composition of a relation with itself, and there the problem does not show.) PS: I was shocked to find recently that Bourbaki (!) also defines functional composition "wrongly" (at least in the English edition of Elements of Math./Theory of Sets, II.3.7) but at least they are consistent and define composition of relations ("graphs") accordingly. They are very honest about this, e.g. "Let G1, G2, G3 be graphs. Then (G3 * G2) * G1 = G3 * (G2 * G1)." (note the order of the variables) -- View this message in context: http://www.nabble.com/Recommending-%22Design-concepts-in-programming-languag... Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

Am Donnerstag 07 Mai 2009 10:23:41 schrieb j.waldmann:
* in the Appendix on notation, he defines composition of functions the "wrong way around" (i.e., the Haskell way, (f.g)(x) = f(g(x)). This is of course very awkward, especially considering that functions are relations, and an element of a relation is a directed edge, and there's a very obvious meaning of how edges are composed to give a path. Well, the book's "solution" is to avoid to define composition of relations! (p. 1155, they only define the n-fold composition of a relation with itself, and there the problem does not show.)
PS: I was shocked to find recently that Bourbaki (!) also defines functional composition "wrongly" (at least in the English edition of Elements of Math./Theory of Sets, II.3.7) but at least they are consistent and define composition of relations ("graphs") accordingly. They are very honest about this, e.g. "Let G1, G2, G3 be graphs. Then (G3 * G2) * G1 = G3 * (G2 * G1)." (note the order of the variables)
That's the way composition of functions (and more generally relations) has been done for ages in mathematics. And since one writes f(x) and not x.f, it's the consistent way to define the composition. Of course, if centuries ago people had decided to write the argument before the function, composition would've been defined the other way round. They haven't.

Am Donnerstag, 7. Mai 2009 14:42 schrieb Daniel Fischer:
Of course, if centuries ago people had decided to write the argument before the function, composition would've been defined the other way round. They haven't.
Algebraists used to write x f instead of f(x) at least in the 1980s. I think, also category theorists often wrote (write?) composition with the first morphism on the left, i.e., “the other way round”. Best wishes, Wolfgang

Am Freitag 08 Mai 2009 13:23:09 schrieb Wolfgang Jeltsch:
Am Donnerstag, 7. Mai 2009 14:42 schrieb Daniel Fischer:
Of course, if centuries ago people had decided to write the argument before the function, composition would've been defined the other way round. They haven't.
Algebraists used to write x f instead of f(x) at least in the 1980s.
I think that should read *some* algebraists... Though I had no contact with algebraists in the 1980s, if that practice had been ubiquitous among them, I would have expected it to show up in the textbooks. I've never seen it in an algebra book, nor was it used in any algebra lecture I attended in the 1990s, so I doubt it was very widespread. Don't get me wrong, that notation does make sense and has some advantages over the conventional one, I wouldn't oppose a change, though it would take some time to get used to it. All I'm saying is that the overwhelming majority of mathematicians doesn't use it.
I think, also category theorists often wrote (write?) composition with the first morphism on the left, i.e., “the other way round”.
Yeah, I heard that, too. It's a field where the advantages of postfix notation show clearly and a young one, so for them it was relatively easy to switch. You'd have a hard time persuading the statisticians and analysts, though.
Best wishes, Wolfgang
Cheers, Daniel

Wow. This is really a bikeshed discussion. My post contained praise for the book, a critique of one of its design decisions (intermediate language not explicitely typed), and a syntactical remark. Guess what the discussion is about. (This is also known as http://www.haskell.org/haskellwiki/Wadlers_Law) If you're advocating (f.g) = \ x -> f(g(x)), then: 1. Define composition of relations. 2. Is a function a special case of a relation? -- View this message in context: http://www.nabble.com/Recommending-%22Design-concepts-in-programming-languag... Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

j.waldmann wrote on 08.05.2009 17:39:
Wow. This is really a bikeshed discussion. My post contained praise for the book, a critique of one of its design decisions (intermediate language not explicitely typed), and a syntactical remark. Guess what the discussion is about. (This is also known as http://www.haskell.org/haskellwiki/Wadlers_Law)
If you're advocating (f.g) = \ x -> f(g(x)), then:
1. Define composition of relations.
R1 . R2 = {(x, y) | \exists z : (x, z) \in R2 & (z, y) \in R1} That's the definition I've usually seen. (If I'm not mistaken).
2. Is a function a special case of a relation?
Depends on the definition (i.e., some books define a relation on (A,B) as a subset in A\times B, and a function A -> B as a triple (A, B, G), where G is a subset in A\times B), but, generally speaking, yes.

Am Freitag 08 Mai 2009 15:51:28 schrieb Miguel Mitrofanov:
j.waldmann wrote on 08.05.2009 17:39:
Wow. This is really a bikeshed discussion. My post contained praise for the book, a critique of one of its design decisions (intermediate language not explicitely typed), and a syntactical remark. Guess what the discussion is about. (This is also known as http://www.haskell.org/haskellwiki/Wadlers_Law)
If you're advocating (f.g) = \ x -> f(g(x)), then:
I'm not advocating it, just objecting to you calling it wrong, because that's the common definition.
1. Define composition of relations.
R1 . R2 = {(x, y) | \exists z : (x, z) \in R2 & (z, y) \in R1}
That's the definition I've usually seen. (If I'm not mistaken).
Same here, I can't remember having seen any other definition. But I won't deny that it would flow more easily if it were the other way round.
2. Is a function a special case of a relation?
In set theory, a function is usually *defined* as a relation R where R[{a}] has at most one element, so yes.

Am Freitag, 8. Mai 2009 14:31 schrieb Daniel Fischer:
Though I had no contact with algebraists in the 1980s,
I also hadn’t. However, nowadays I have contact with someone who was an algebraist in the 1980s. It’s my boss (professor), by the way. :-)
I think, also category theorists often wrote (write?) composition with the first morphism on the left, i.e., “the other way round”.
Yeah, I heard that, too. It's a field where the advantages of postfix notation show clearly and a young one, so for them it was relatively easy to switch.
However, I fear that all those other mathematicians who define f . g = \x -> f(g(x), have made the category theorists switch to this suboptimal notation (first morphism on the right). At least, I cannot remember seeing the other notation (first morphism on the left) in category theory literature so far. It’s just that my above-mentioned professor told me that category theorists would use the first-morphism-on-the-left notation. Best wishes, Wolfgang

On Tue, May 12, 2009 at 1:41 PM, Wolfgang Jeltsch
At least, I cannot remember seeing the other notation (first morphism on the left) in category theory literature so far. It’s just that my above-mentioned professor told me that category theorists would use the first-morphism-on-the-left notation.
I've seen the notation f;g for g.f somewhere (and Wikipedia mentions it). I think it's less ambiguous than just fg (which I've seen for f.g too), but in Haskell we have the option of >>>. A flipped application might be nice to go with it. How about >$> ? --Max

On Tue, May 12, 2009 at 1:04 PM, Max Rabkin
On Tue, May 12, 2009 at 1:41 PM, Wolfgang Jeltsch
wrote: At least, I cannot remember seeing the other notation (first morphism on the left) in category theory literature so far. It’s just that my above-mentioned professor told me that category theorists would use the first-morphism-on-the-left notation.
I've seen the notation f;g for g.f somewhere (and Wikipedia mentions it). I think it's less ambiguous than just fg (which I've seen for f.g too), but in Haskell we have the option of >>>. A flipped application might be nice to go with it. How about >$> ?
FYI: Unicode U+2A3E Zed notation relational composition (small circle over a 9) Examples at http://staff.washington.edu/jon/z/toolkit.html#pair3
participants (8)
-
Bernie Pope
-
Daniel Fischer
-
Eugene Kirpichov
-
Gregg Reynolds
-
j.waldmann
-
Max Rabkin
-
Miguel Mitrofanov
-
Wolfgang Jeltsch