> The Dragon Book covers everything you need to know to write a compiler.
No it doesn't because it only covers techniques you can use in implementing and optimizing old-school static languages.
But today a language is more than just the compiler, with modern VMs coming into play, and runtime optimizations aren't covered ... for instance if you want to implement a tracing JIT compiler, your only hope is to read the source-code of some available VM. Or if you want a precise garbage collector ... well, good luck with that.
That's one reason the implementations of dynamic languages are so shitty ... the effective techniques for doing it are yet to be explored / documented.
My problem with the Dragon Book is more fundamental: having once made a real effort to read it, almost cover to cover, I came away with a few hours less of my life remaining and some ideas about lexers and parsers and the like, but I still had absolutely no idea how to sit down and write a compiler. I don't understand why anyone thinks this is a good book.
There are introductory texts that might not cover the same amount of theory, but at least get you from nowhere to being able to write a basic compiler from start to finish. If you do want some serious theory, particularly on optimizations, then Muchnick blows the Dragon Book away. If you want to work with different kinds of programming language, notably functional programming with a lambda calculus foundation, then these ideas barely appear in the Dragon Book and again there are specialised texts that would serve you much better. What is the target audience for the Dragon Book actually meant to be?
I found Appel's _Modern Compiler Implementation in ML_ to be better-suited to self study, and more modern. I've used OCaml but not SML, and didn't have any problem following it.
Well, when I wrote a compiler (on a team of 3) the dragon book (first edition) was very helpful, from lexers, parsers, to code generation. So we read it cover to cover (except for Jeanne, who got her PhD from Ullman and who wrote the LALR parser) and used it profusely.
As noted elsewhere in this thread, I think that, in contrast to the OPs article, everyone should read it or Hollub's excellent work that followed the Dragon book by a number of years.
So I would disagree with your opinion about this being a good book, but then I may have the advantage of having spent substantially more time with it.
Jack Crenshaw's book Let's Build a Compilerhttp://compilers.iecc.com/crenshaw/ is probably too far to the pragmatic end; it essentially walks you through the process of writing a recursive-descent compiler in Pascal for a Pascal-like language that generates code for the m68k. No separate parser and lexer as such, but he does teach you how to turn those kinds of ideas (regexes and EBNF equations) into code more-or-less directly in your head. In short, it was just about perfect for someone who wanted to whip up a nice little compiler for a foogol on a late-1980s DOS box without paying for or finding any tools beyond Turbo Pascal.
It's entirely possible to use the techniques in the book to, say, whip up a compiler in Ruby that turns an inconvenient data format into JSON. The real utility of doing this by hand in 2010 is, however, debatable.
I think a lot of dynamic language implementations suck because their authors haven't bothered to study Lisp implementations. The widely used implementations of Common Lisp and Scheme don't suck at all[0]. Of course, some implementors of other dynamic languages do seem to have studied Lisp implementations and it shows in the results. Lua doesn't suck at all.
[0] Ok, the multi-platform support of some of the CL implementations could be better.
I'd say they suck because the authors cared about specific issues other than making the implementation not suck (which I guess means fast performance performance?).
But how does lua bears lisp inheritance in its implementation?
IIRC lua does not use pointer tagging which is a typical lispism, uses tables for everything, has no lists, and uses a different approach for implementing closures.
Lua's designers have acknowledged a lot of Scheme influence, especially from 4.0 onward, but I think it's more about the semantics than the implementation.
Lua uses a type tag + union rather than tagged pointers because it's not strictly portable, and they've placed a high priority on strict ANSI C compliance (with the sole exception of dynamic library loading). Also, Lua tables recognize when they're being used as arrays and use an array internally.
FWIW, a large chunk of the dragon book is about lexers and parsers, but from an automata theory perspective, where rather than creating a compiler, you're creating a compiler compiler, like lex for DFAs creating token streams from character streams, and yacc for PDAs creating trees from token streams.
But such detailed info isn't necessary even to write a compiler front end. It's good that the treatment exists, and that it's in the dragon book, but it's not what you need, even for parsing.
Perhaps you are implying the Dragon Book is not needed for people who will use tools like lex and yacc to generate it.
While that is true, the Dragon Book gives real insight into how a compiler really works and how to code one from scratch. If someone is only interested in getting a very basic compiler up and running quickly and not interested in understanding how to really make one, a simple tutorial for yacc should suffice.
If you're really making a compiler, it's unlikely you'll use a parser generator. Most production compilers use hand-written parsers for a variety of reasons: speed (e.g. folding more logical passes over the AST into the AST construction in the parser), semantic resolution of grammatical ambiguities, flexibility for compatibility (e.g. toggling different syntax rules dynamically), etc.
My comment wasn't about the article's point (which I thought it is valid), but about one idea that keeps getting rehashed ... i.e. if you want to learn about real compilers, you should read the Dragon Book.
> If modern languages are more than a compiler, that does not denies the ability of the book to cover how to write a compiler.
True, but the best way IMHO to learn about compilers is to start more lightly and then to read lots of source-code.
I notice that Language Implementation Patterns was written by the Author of ANTLR. I've had terrible experiences trying to use ANTLR in practice, which kind of puts me off buying the book. Do examples in the book use ANTLR? Also, is there much point in getting the book if I already know about lexer and parser generators?
Yes. The book is "saturated" with ANTLR. I wouldn't buy it if you don't like ANTLR. Also, (purely imho) it spends too much time on the front end (lexing/parsing) and not enough on the rest. I have yet to see good books (other than DCPL or L.I.S.P) which uses a simple concrete syntax (s-expressions say) and focuses on the rest of compiler building.
> I've had terrible experiences trying to use ANTLR in practice, which kind of puts me off buying the book.
Yes, but it explains the parsing techniques used by ANTLR, and for learning stuff it's quite OK. It uses ANTLR as a teaching tool, but you don't have to keep using it afterwards.
For writing simple parsers you don't even need to read a book ... just use a parser combinator based on PEGs, like http://wiki.github.com/sirthias/parboiled/ and you'll be fine.
If you want a general purpose language however, even if you use a tool like Parboiled, you'll need to know how its guts work. It is also a good idea for a compiler to be self-hosting, because it's more portable that way and the compiler's code itself is a good test for your language ... so you'll need to know how to implement a parser by hand.
Of course, after the parser is done you'll need to have an AST, and maybe you'll want to optimize it ... this book is thin on such details, but it's better to start somewhere and books like the Red Dragon are quite heavy and can put you off the target before writing a single line of code.
"It's a common belief that garbage collection means inferior performance, because everyone who has gotten into programming in the last decade regards manual storage management as a fact of life, and totally discounts the effort and performance impact of doing everything by hand.
In a large application, a good garbage collector is more efficient than malloc/free. "
No it doesn't because it only covers techniques you can use in implementing and optimizing old-school static languages.
But today a language is more than just the compiler, with modern VMs coming into play, and runtime optimizations aren't covered ... for instance if you want to implement a tracing JIT compiler, your only hope is to read the source-code of some available VM. Or if you want a precise garbage collector ... well, good luck with that.
That's one reason the implementations of dynamic languages are so shitty ... the effective techniques for doing it are yet to be explored / documented.
So if you want a book on implementing compilers, I recommend this one ... http://pragprog.com/titles/tpdsl/language-implementation-pat...