
Rich Programmer Food (2007) - rspivak
http://steve-yegge.blogspot.com/2007/06/rich-programmer-food.html
======
paloaltokid
I'm a big Steve Yegge fan and I like most of his articles. I like this one
too. But, some of them, like this one, leave me feeling a bit disheartened.

Okay, compilers are important, I get it. I would love to learn more about how
they work. But - I never got a CS degree and I'm 10 years into my career. I've
learned a lot of valuable stuff but I'm not going to go back to school just to
make Steve happy.

So what do I do? What's the best resource out there for me to learn & grok
something about compilers without working through 3 textbooks and watching a
bunch of lectures? I like being able to learn something by applying it to my
current work.

That's how I learned about IP networking - I did sign up for a class, but I
was a Jr. DevOps person at the time and so everything I learned could be
immediately applied at work the next day or next week.

~~~
zenogais
It really depends on what you think qualifies as understanding a topic.

You can definitely write a basic compiler without much understanding. I've
seen a lot of programmers do this, and I think it's great. The unfortunate
reality though is that at some point you'll have to learn the foundational
mathematics of compilers to really build them. Without that foundation you'll
be manipulating symbols and using libraries with only a vague idea as to what
they really mean or do. This means when things go wrong, you'll often be quite
puzzled as to what's happening. It also means your workarounds are likely to
be flawed as they'll be based on only partial understanding of the problem
they're solving.

It's great to have a pragmatic attitude when learning things, but it can also
prevent you from gaining the deeper understanding only available through
protracted study and practice.

~~~
paloaltokid
I think my definition of understanding would be: I have understood this well
enough to write a non-trivial program that solved a problem at my day job.
This program should provably (and hopefully obviously) be the most correct,
maintainable, and performant solution for the job.

I make the day job part a requirement because for me to feel that I've
invested my time well, I need to be able to apply my knowledge in service of
some other task. Mind you, it only has to work and solve a problem once. If I
never use it again in my career, that's fine.

But it's that ability to say "well, I never thought I needed to learn
compilers until this one time..."

~~~
zenogais
You kind of get a chicken and egg problem here. If you don't sufficiently
understand something, how can you hope to identify situations in which you
could apply it?

I think the more pragmatic approach is to sample from a lot of different
topics. The more I read CS papers on random topics, the more I find
opportunities to improve my day-to-day work by applying them. There's no way
to get this payoff without expending some effort, unfortunately. Requiring
that the payout be obvious before the work is put in is, IMO liable to lead to
not learning and improving as fast as you otherwise could.

------
weinzierl
> If you don't know how compilers work, then you don't know how computers
> work.

This works both ways: If you don't know how your hardware works you will never
understand the compiler.

~~~
matthewmacleod
And if you don't understand how physics works, you will never understand how
your hardware works… ad infinitum.

It's a weak argument for me, if I'm honest. Learning how a compiler works is
interesting and provides useful insight into how other parts of the stack
work. But it seems like a falsehood to suggest that it's not possible to
understand one level of abstraction without knowing the full stack; isn't that
why we have abstractions in the first place?

~~~
khedoros
> But it seems like a falsehood to suggest that it's not possible to
> understand one level of abstraction without knowing the full stack; isn't
> that why we have abstractions in the first place?

Any non-trivial abstraction will have some leaks. You can memorize the problem
cases and usefully _use_ the abstraction without understanding the source of
the leaks. Partial understanding can be sufficient. Fully understanding an
abstraction probably requires you to understand all the levels of the stack.
Is it actually _useful_ to know the stack top-to-bottom like that? Not always.
As you note, that's why we cover up the details in the first place, so that we
don't always have to keep the underlying implementation in mind.

------
why-el
I got excited for a second because I thought Steve is back. :)

------
PaulHoule
I've come to the same conclusion, almost, except the way I see it is that
everybody who takes CS takes compiler construction, other people read the
literature about it, and it is still a technology that largely sits in the
box.

Lately there has been a lot of work towards languages that improve the state
of systems programming (Rust) but the deeper problems of better languages for
applications programming are largely ignored.

My belief is that the content of those courses and most of the literature on
compiler construction, as well as the tooling most generally available, is not
at all suited towards getting people to apply it in new ways.

~~~
qwertyuiop924
Yeah, and most of the tooling that isn't written in C (Lex, YACC, and MPC come
to mind) has documentation that assumes you already understand the API. I
mean, what?

~~~
PaulHoule
On top of that there are a lot of other practical problems with those tools.
It's hard to learn to use them to do simple things, and even harder to use
them to do moderately hard things.

For instance in a lot of cases what you really want is to convert a grammar to
some reasonable abstract syntax tree and I've found often you have to write a
lot of code into those frameworks to do that, whereas you ought to be able to
write something declarative that generates the AST objects and the translation
code.

Another problem is a lack of composability. Particularly in DSL creation it
would be desirable to "cut and paste" grammars into each other; it's very
possible to embed SQL into a language like C, Java, or such -- you ought to be
able to embed one parser in another but generally it is not easy.

Also there is the problem of error message generation, which is bad enough
when you do are doing things that are "easy with yacc" but when you are doing
hardcore transpilation of some kind, the error messages are often completely
incomprehensible. This is a big factor in any kind of "rules engine" built
around an existing language; error handling is disastrously bad in Drools, for
instance -- you might think homoiconicity would improve matters with Clara in
Clojure but it really doesn't.

~~~
sklogic
If you want this kind of composability, use PEG-based tools.

Same for the error messages and error recovery.

~~~
qwertyuiop924
Wait a sec. Since MPC is a Parser Combinator library, wouldn't it have the
composability?

~~~
sklogic
Yes, you're right - did not even notice MPC in the list, was commenting on
Yacc and alike.

~~~
qwertyuiop924
Yeah. I wasn't commenting on specifically YACC and Lex, just compiler toolkits
with good documentations. And MPC has some of the best documentation out
there. Also, Build Your Own Lisp is amazing.

------
falsedan
Executive summary:

    
    
      If you don't know how compilers work, then you don't know
      how computers work. If you're not 100% sure whether you
      know how compilers work, then you don't know how they work.
    

Why does he say that? I don't have the time to read 5495 myself to find out.

~~~
xigency
Well, it's not actually true.

Imagine a world where all software were written in assembly language, or even
better, machine code. There would be no use for compilers. 'Portable code'
would be machine code that was frantically re-written (by hand) from one
platform to another platform. And we wouldn't have a number of JIT
technologies and other languages (by definition) as well. Here, without
compilers, there would be many people who understand computers.

The fact is in the world we live in, code is on a higher plane than hardware
instructions, and it's something that impacts software engineers' lives
proportionally. Practical computers work with machine instructions, but
idealized computers operate on programs which can be abstracted as code in
another language. The practical constraint is that program code must be
transformed to be used, so the compiler becomes an essential tool.

The fact that compilers as we know them are so complex leads to the assertion
that "if you're not 100% sure you know how they work, then you don't know how
they work." Because face it, if you're working on a monolithic, complex piece
of software that automates a large volume of menial work, and there is no
certainty that it performs as expected or does the right task, then it won't
function at all.

You don't need to know how computers work (in this semantic argument) to be a
computer programmer, but you absolutely must know how computers work to be a
compiler writer. And like the transition from machine instructions to programs
written in high level languages, the journey from programmer to compiler
writer is a quantum leap, but one that gives someone advantages as a
programmer.

~~~
falsedan

      > you absolutely must know how computers work to be a compiler writer
    

Ah, OK.

------
gh-lfneu28
This post is from 2007. Yegge is not back :( OP or mods, add (2007) to the
title svp.

------
fish2000
Wow this takes me back – 2007, those were the days. Back before so many
flagship projects had frankensteined libLLVM into their innards; before every
single JavaScript framework was required by law to include at least one CLT
whose executable name ended in 'c'; back when GCC on Apple was just a matter
of /usr/bin, and not a parade of endless Homebrew formulae PRs… srsly dogg
this is an excellent article, a product of its time but a bonafide bulwark,
presciently on the precipice of paradigm. I +1'ed.

------
phamilton
I highly recommend Make-a-lisp for anyone interested in a superficial
understanding of writing a compiler. It's a very guided tour, but touches on a
lot of very interesting parts of parsing, code generation, and optimization.

[https://github.com/kanaka/mal/blob/master/process/guide.md](https://github.com/kanaka/mal/blob/master/process/guide.md)

------
JaRail
I haven't laughed this hard in weeks. This is a top-shelf article!

------
krallja
(2007)

------
sklogic
Compilers matter because of DSLs. The rest is of a marginal importance.

