Taking the compiler course changed my career from day 1.
In my first job, back in the late 90s, I was working for a company that, having taken their biggest customer yet, had to split a very large C monolith into chunks that could run on separate servers. The architecture team of the company found all the places where the system should be cut, but that let them with hundreds of functions that had to be replaced with asynchronous calls relying on a queuing system. I was hired into the team that had to stub those hundreds of functions, type up serialization and deserialization for all the hundreds of data structures involved, and gluing it all together. So they had budgeted for 6 months of typing from a team of relatively new developers.
As you might expect, that's not how anyone wants their career to go, but I had taken the compiler class. So I knew I could parse all the header files for the functions we needed to replace, parse the data structures along with it, and just generate all the boilerplate away. My dev lead thought there's no way we could do this, but his manager decided that, at works, giving me two weeks to try it would be a great opportunity to teach the new hire the limit of his knowledge. But as anyone that has taken the compiler course knows, parsing boring C structs and header files isn't magic. So two weeks later, the project was done, and it was working.
As you might imagine, the dev lead, in his 40s, couldn't handle the results all that well, and left quickly. So I went from being stuck writing boilerplate from month to a quick promotion to team lead in under a quarter, all thanks to the compiler course.
Thanks for the causal ageism from someone who is in their 40s or more now... The dev lead did not know something very useful for the project, this could be some one in their 20s, 30s, 40s or 50s... knowledge or lack of knowledge does not differentiate...
> "knowledge or lack of knowledge does not differentiate..."
I agree wholeheartedly. Knowledge, or even intelligence, shouldn't be the most highly valued skill in a team lead.
But there are many people extremely confident in their confirmation bias that seem to be unwilling to consider anything that might challenge their ideas. Our industry has a problem with celebrating the intelligent arsehole. Not only is humility not incentivized, it seems to be actively counterproductive.
I wonder how we can foster the kind of culture that values experience, encourages innovation, and is also able to get things done without chasing geese?
I am also approaching my 40s, but really, it is true that when one ages, so many uncommon things failed spectacularly, after that, one assumes everything behaves like that. But I try to keep a fresh mind and kind of brainwash myself to think positively first. Played out very well until now. (Because a lot of young developers fresh out of uni are taking with them the conservatism of the professors or mediocre student teams.)
I think you're misinterpreting here. GP didn't make any generalizations about people in their 40's. They were providing additional context about a specific individual. Moreover, the context they were trying to convey was more about the delta in years of experience than a particular age bracket.
Also, thanks for the casual sarcasm, casual assumption of ill-will, casual tone policing of others according to your personal whims, casual accuse-first-rather-than-clarify and embarass-in-public-rather-than-confront-in-private approach. Really brightens the mood in here!
I have been in the situation where you can see even fresh to the workforce that everyone is doing something inefficiently. So you come up with an idea.
In my case it was more prosaic than compilers: they were assigning “pages” to devs to rewrite in .net, but clearly the pages had similarities and it made no sense for different people to be building the same thing in parallel their own way. I was simply suggesting to do some design worm upfront!
But it is hard to be listened to when either young or new to a company. Glad they have you a chance. Lesson for companies: give anyone passionate a chance to experiment!
I've found that to a lot of developers, the tools that they use are magic, and replacing those tools or building new ones yourself is something that is beyond their imagination.
You'd think this is something more common with juniors than seniors, but in my experience it's been the opposite. Probably something about being distanced from the fundamentals made them forget how it's possible to build anything from scratch.
When I was 12 years old our class got punished for something childish. The teacher gave us an assignment to write I will not chew gum in class 100 times. Everybody was pissed. I did:
10 set i=1
20 i=i+1
20 print i, ". I will not chew gum in class"
30 if i<100 goto 20
40 exit
I don't know what GP did, but you don't need to write a complete parser. You can write a subset that can find the patterns you're interested in, which is much easier.
For many languages there are mature parsers out there that can be reused (e.g. Google's Closure compiler or babel for JavaScript, or the Soot framework for Java that also simplifies more advanced code analysis). In the worst case, it's sometimes possible to interface with the standard compiler for the language directly (for example, the TypeScript compiler provides TypeScript APIs for its parser/type checker/etc.). I believe for C++ for example, a Clang plugin (https://clang.llvm.org/docs/ClangPlugins.html) would have been a plausible way to implement something like this.
Heck, I have never take a compilers course, but in my first year of my first job I did similar code generation for Java just using sublime text replace-all with regex and/or python and templatizing strings. It was pretty “naive” and required more manual glue steps than yours I’m sure but it worked well for boilerplate and redundant code.
I'm a self-taught programmer, starting in the mid-70s, and learned how to write compilers in a way that probably wouldn't work nowadays, but was great fun back then.
The first thing I'd usually do when starting on a new architecture was write a disassembler. In the late 70s, I was mostly programming in 6809 assembly, usually in Microware's OS-9 operating system. Microware released a Pascal compiler, so I ran my disassembler over that. Turns out the compiler was self-hosting, written in Pascal, and the compiler output was almost completely unoptimized. So I decompiled the compiler back to Pascal by hand, just to see how it worked. I obviously had waaaaay more free-time back then.
I eventually read the green Dragon book (Aho & Ullman, Principles of Compiler Design), and ended up at Microsoft on the C/C++ team in 1991. Over the years, I've written several domain-specific languages (DSLs), small languages for some limited purpose. That early exposure to lexing, parsing, and error detection was invaluable.
Don't suppose you have any links to any useful resource/tools for disassembling an old CD-i game that would have been written in C for the 68000 on Microware OS-9? I've got so far with ghidra but the OS-9 plugins available are either outdated or don't fully handle the instruction set for OS-9.
I also wrote a source-generating disassembler for a 8-bit i8080-based Soviet-designed computer, RADIO-86RK — because I wanted to improve software published in the magazine. And explore stuff.
I was in grad school, 77-83. The first year was part time at NYU, and then I went back full time elsewhere, for a PhD.
In that one year at NYU, I took two compiler courses, from RBK Dewar, of Spitbol and Ada fame. My specialty is not languages or compilers, but those courses were incredibly fascinating, and the exposure to the topics I learned has been useful throughout my career.
- I learned about lexing and parsing. I no longer remember the details of LALR, for example. But I understand the basic ideas well enough to construct lexing/parsing software whenever I need it, often using parser generator tools, but also rolling my own on occasion.
- I learned about code optimization, which is a fascinating topic. At the time, Dewar was working on SETL, a set-oriented language. And I remember the power of having sets as a builtin type, and how powerful that was for expressing flow analysis, for example. Those ideas combined nicely with what I later learned about relational algebra, and query optimization. (Codd's paper on the relational model was only seven years old when I started grad school!)
- Exposure to the ideas of interpreters and code generators, and even more fundamentally, the idea of code as a thing that can be manipulated programatically, has been useful throughout my career.
My unexpected side benefit: some compiler error messages became comprehensible.
Oh, an lvalue is required? Since I now actually know WTF that means, I can deal with it.
It also cleared up a situation that had always confused the hell out of me: sometimes I'd compile and get 1 or 2 errors, so I'd make corrections and try compiling again, but then I'd get 8 or 10 errors! Seeing that whatever I did made everything much worse, I'd conclude those most not be the right corrections, and I'd feel lost and maybe even get stuck.
After taking compilers, I finally understood why: compilers have phases, and my corrections allowed the parsing phase to complete, which meant the semantic analysis phase could happen and give me errors. So for example, if I finally fix enough syntax errors that the compiler can tell I've written a function with some variables in it, then it can start giving me errors that they're not the right types.
Yes and no. That specifically is a C & C++ thing but the general concept you'll learn in a compilers course. If you intimately understand how a compiler works (even just generally), you pick up a really concise understanding of how the errors come about and how they tie back to the language.
Understanding the lexer and the parser explains a lot of common errors (missing/ semicolon or curly bracket) and why they often point to errors in otherwise perfectly correct & unrelated code instead of their source location.
Understanding the compiler itself and how it operates over an AST means that if you get an error regarding a particular set of semantics, you can quickly learn what the implications are and how that maps to your code.
A good example (other than the GP's) is the massive, ugly template or overloading errors. They make sense and explain to you everything the compiler tried to do and how it failed each time it tried. The compiler doesn't know what is wrong and therefore doesn't have a more concise error to give you so it just tells you everything "it knows". From that you can work back and see where what you intended the code to do diverged from what the compiler thought the code did.
So it is a language thing but you build the intuition to pick up those language skills by learning/understanding compilers in general.
The big value I got from taking compilers as an undergrad was that it brought everything together. It's basically where computer architecture, theoretical CS, and software engineering (and a hint of systems security) collide in a very practical manner. Compilers make it very clear how all those seemingly disparate topics apply in real non-trivial systems.
Compilers was the first (and, perhaps, only) course where having playid a lot worth computers before didn't matter. At. All.
At the same time, you learned some theory you didn't know (couldn't even have predicted) - that actually had direct practical application!
It was amazing and a microcosmos of CS - in that you first get a general understanding of the problem and desires outcome, learn theory that you couldn't have predicted but is amazingly apt for this, and end up making stuff work thanks to all of this.
It's an amazing experience that everyone with an interest in CS deserves to have.
These are precisely the type of "ahas" I hope to experience, too, when I begin studying computer science. I've been taking introductory college math courses at my community college to fulfill some prerequisites, and a way for me to stay disciplined in my studies is knowing that concepts like the ones you mentioned are coming. Thank you for sharing!
You'll have many of these moments! One of the best and worst thing about computer science is how many layers of abstraction there are.
On one hand, they help you get things done. On the other, it can be _so_ hard to understand how things really work. Most programmers don't peel back too many layers, but that's okay.
> Compilers make it very clear how all those seemingly disparate topics apply in real non-trivial systems.
Combined with a proper OS class, it's the first time a student can truly understand all the levels of abstraction from the language to the logic gate.
And it also helps to recognize and solve parsing problems. How many programs end-up containing a parser, even if rudimentary, to read non-trivial input of perform validation? No, you can't use regex for that...
We use gcc/javac/etc almost daily and having some understanding of what your toolchain is likely to be very beneficial. Here are a few things I've done with my compiler knowledge:
1. Wrote a simulator of sorts for a 68xx CPU. User passed in assembly files and I simulated the execution and spat out cycle counts. The real-time application had a fixed time window it could not exceed. I did this in my first year out of college with compilers fresh on my mind.
2. Wrote an automated test tool for a proprietary protocol. The protocol had the usual opcodes but they could only be played in a certain order (cannot send B before C or can send B any number of times and have it be idempotent). The QA engineers were doing this by hand. I asked them if they could automated the test case generation and they looked at me as though I was an idiot. I developed a tool with its own simplified grammar that they could use to build test cases which exercised all combinations/permutations of the opcodes. Saved us a ton of time and made the developers more productive.
3. My hackiest project was an SGML parser that was used to generate hypertext documents. Tech writer wrote docs in FrameMaker. My hacky parser found the places where the TOC and the Index could be linked and inserted hypertext links. Net result is we had a document that could be printed and viewed online. Think 1993/1994.
I've sat with a number of engineers who thought the compiler was wrong and sat down and looked at the assembly with them and mapped it back to C only for them to realize the bug was in their code.
Compilers are fun. You should take a compiler course just for that!
Compiler construction is a part of practical computer science that includes
- formal languages, Chomsky hiearchy and automata (DFAs, NFAs)
- algorithms & data structures (syntax trees, symbol tables & hashing)
- parsing algorithms
- asymptotic complexity (of automata recognition/acceptance and parsing algorithms)
- software architecture (single pass versus multi-pass, abstractions)
- operations research (graph coloring based register allocation)
- assembler & automatic code generation
- virtual machines & interpreters
It is a field where theory and practice come together beautifully (and works like the Aho et al. ¨Dragon Book¨ or Wirths ¨Compilers¨ are masterpieces that lucidly lay things out so after reading Chapter 2 of the former, or all of the latter short volume (barely 100 pages), a compiler is basically demystified to any undergrad).
Its too focused on the mathematical approach to parsing but almost no mathematical rigour or intuition for the actually interesting parts of compiler IIRC.
These books really only help you for the first five minutes of each part of a compiler e.g. "Here's how to write a register allocator, go find the calling convention yourself and my office hours are never"
While one may not be interested in writing compilers, the techniques are applicable elsewhere.
For example, I once wrote a date/time "compiler" that could read dates and times in various human formats and construct a time_t from it. It's a giant mess if you approach it in an ad-hoc fashion. But if you approach it from a lexing then parsing standpoint, things work a lot better.
I see too many attempts at reading a textual data format that are done ad-hoc. Even worse are the attempts to design a data format where the designer clearly had no awareness of lexing and parsing - the format is just one ad-hoc kludge after another.
Uni CS lecturer here. One of my mentors in grad school was the compiler professor, and I learned a lot from him. I also got a chance to actually teach compilers for the fist time last year and it was one of the most difficult courses I have ever taught. Used the dragon book and had my students create their own lexer/parser based on an invented language that I came up with.
Compilers is one of the few topics that none of my colleagues seem care about, but IMHO it's so very important to learn how to do. In my Uni, the course only gets taught once every few years (it didn't help that our last department chair didn't care for the course at all and never scheduled it).
I count the day that I finished my LL(1) parser and lexer for my own compiler course as a student as the day I "earned" my chops.
I'm curious, why focus entirely on parsing? I only read parts of the Dragon Book, but it didn't go in much detail about other topics, such as types, either. Couldn't you just use a very simple syntax such as S-expressions or even start from an AST directly?
people hyperfocus on parsing because it's far and away the easiest part of a compiler - type inference, optimization, target codegen are infinitely harder and deeper wells to plumb.
A few reasons, although you are only seeing part of the picture with the project. The lectures were all theory-based (more along what you would find in the book).
1. I had a whopping three weeks to prepare this course from scratch (welcome to Uni teaching) and it was what I could scrape together in that time.
2. Parsing is highly useful, and I felt my students could benefit from it.
3. It was what I did in undergrad.
4. It was not too difficult to accomplish, and a project like this can easily get out of hand for a semester project.
I agree with you that parsing, for most people, or even most software engineering people, are much more useful then the other stages. Code generation is also interesting and could be useful too but that's pretty much the two of them. All the "interesting" stuffs people spoke about (e.g. optimization) actually has very few use cases unless you are working on it directly.
Most never "earn their chops" in a traditional sense. These days, it would seem earning your chops is done by running create react app, cobbling together several dozen random javascript libraries and putting out a laughably designed website in a few days.
The Georgia Tech cs2130 class, languages and translation, the third required cs class for the major, was notorious as being a weeder course around 1999. The professor made it clear that there would be no partial credit for code that could be core dumped by the teaching assistants. If you weren't good at the class you should probably look forward to writing business applications for IBM, allegedly. So some people used to be hardcore on this subject.
Always glad to see someone else who remembers that era at GT!
CS1311 - Data structures in pseudocode (or Scheme if you had the "X" class)
CS1312 - Build the game "Risk" in Java
CS2130 - Die a painful death at the hands of Jim Greenlee's compiler class.
I actually think the class needs a book or at least an extended article written about the end of the "shaft" era. I've never seen a professor brag about a student offering a bribe in order to pass.
It was interesting to see so many classmates panic in the class over how seemingly arbitrary the zeroes were given over minor mistakes. I, for example, was given a zero for a lab because I forgot to sign in. The grade for this lab was entirely based on signing in though because it was written incorrectly. The class just had tons of "life isn't fair, you should have paid attention" anecdotes.
We have a similar course too which focuses specifically on language design without the compiler part (they do get a bit of compiler theory) which satisfies that "requirement" for graduation. It is much more popular than the compiler course which is perceived as "harder" (it probably is when I teach it). ;)
IIRC (may be wrong, read as a kid), those ladies used to signal which aristocrats should be chopped vs. not, by signalling with their knitting needles, or a nod or shake of the head, or some such - while sitting in the front row before the guillotine.
Ghoulish. Of course, as a kid, you (I) lap up and relish that stuff, like breakfast cereal.
Once for a templating engine for SQL (taking values from the environment and using them queries). This was really nice for productivity and an intern could churn out dozens of reports a day. That was written with javacc.
Another time by using a parser (written with Antlr) to extract bits of PLSQL packages (procedures, functions) and move them from one environment to another without having to send the whole package.
Although this type of job is rare, it can be really useful when it shows up.
If you are interested in modern compiler infrastructure that subsumes a lot of recent PhD level research topics, I can highly recommend MLIR.
It's under the LLVM Foundation umbrella.
If you just want to deal with lexing, parsing, and interpretation (from scratch) for a reasonably complex class-based language, I recommend doing the (free) online book Crafting Interpreters.
The second half of that book re-implements the same language in C with garbage collection and a fast byte code interpreter.
IMO compilers are a bit like kernel development in that the real learning was the friends you made along the way, rather than actually being able to understand how a compiler works, which is a nice side effect. For example, when you write an OS you learn a lot about how code interfaces with hardware. A compiler is many people's first and only introduction to soundness and formal analysis. Being able to put on the hat of a compiler author can be useful in many fields that have nothing to with compiler development, and that's even if you go beyond "I just want to see what my code is being transformed into".
If you're interested in compilers and language implementation, it may not be obvious, but one needn't be a university student or devote a semester to the topic.
Taking a four-day compiler course[1] (now five days) whetted my appetite for implementing languages and learning new ones, and led to a number of toy language projects. Also mentioned here, the book Crafting Interpreters is wonderful.
The world may not need many more programming languages, but making your own is a heck of a lot of fun. I find it especially satisfying when tests written in the new language start to surprise me by already passing, because enough of the language is working.
I did not take a compilers class when I was in college. Many years later, feeling the lack, I bought the Dragon book. I didn't make it past Chapter 4 because I was inspired to write a new library and tool, which then brought me a modicum of career success.
Regehr is right on the money here: parsers and interpreters are everywhere. Once you learn how approachable and applicable they are, you can solve problems faster and better.
I now always recommend to college interns that they take their CS department's compilers course their senior year (along with their English department's Shakespeare course).
I did not have a compiler course at university but I talked on r/programminglanguages discord and eatonphil's discord and I learned how to create a simple expression compiler in Python.
Compilers also show an application of pipelines which can be used architecturally at all levels.
I’m a happy coder if I can translate my problem to a pipeline problem. Each pipeline step can be modelled as a pure function. Each artifact between each step can be inspected and cached. Pipeline failures can be resumed at the last valid artifact
Despite the fact that my algorithms course was ostensibly about learning how to come up with efficient solutions to various problems, the two courses I took that have helped me the most with writing performant code in my career were my compilers course and my architecture course. The compilers course gave me a much stronger understanding of what actually happens when running a line of code I wrote and helped me understand better what types of optimizations could potentially be performed based on the way I write an algorithm, and the architecture course taught me about how a modern CPU actually works with regards to caching, out-of-order processing, branch prediction, etc.
On the other hand, the types of things we discussed in my algorithms course felt very hit-or-miss with regards to whether they actually felt useful or not. I'm not just talking about high-level abstractions that can miss important details in the real world like "memory can be accessed in constant time" either, but solving problems that were so contrived to the point of being almost implausible. The example I always remember is that in one of our problems sets, we were asked to write an algorithm that sorted an array of size N with each element within K indices of the correct sorted position in O(n*log(k)) time. I can't think of any situation where I'd have data so large with a small enough strict upper bound on K that such an algorithm would be necessary, but even if I did find myself in that situation, that's the exact type of input that the naive quicksort implementation would perform more efficiently on!
Maybe someday we'll have powerful enough tools that we can generate code that's performant without needing to do it ourselves, but at least for now, writing code that a computer executes efficiently is much easier when you actually understand what's being run on the computer and how it runs it, and a compilers course is a great way to start learning about the first half of that.
> Despite the fact that my algorithms course was ostensibly about learning how to come up with efficient solutions to various problems
The usual advanced undergraduate / graduate level algorithms class is not supposed to teach you that. It's an introductory class to various techniques used in algorithm design and analysis, beyond those included in the undergraduate algorithms and data structures class.
Core algorithms classes then assume familiarity with those techniques. One of those core classes may be algorithm engineering, if your CS department has someone interested in the topic. And if the department assumes that there are enough students interested in it – the overlap between people interested in algorithms and software is often surprisingly small.
> It's an introductory class to various techniques used in algorithm design and analysis
I feel like you're being a bit too pedantic here, because I don't really see how "learning various techniques used in algorithm design and analysis" doesn't somehow fall under the umbrella of "learning how to come up with efficient solutions to various problems"; an algorithm is certainly a solution to a certain type of problem, and efficiency is certainly a property that would be investigated as part of "algorithm analysis". Every single problem on our numerous homework sets and every question on every exam we had required us to design and then analyze our own algorithm for solving a problem presented to us, so it seems kind of silly to claim that we weren't supposed to be learning how to solve those problems, given that it's literally what they graded us on.
My best guess is that you objected to my characterization because you read it as a "why" rather than a "what". Whether the course was intended to teach us real-world skills or just try to teach the prerequisites needed for a career in algorithmic research doesn't really change the point I was trying to make, which was a potential answer to the question posed by the article, "Why take a compiler course?".
The introductory algorithms class is much like introductory programming: it teaches you the basic tools, but it's not very practical on its own. If you are not interested in studying algorithms further, the class may be interesting and educational but probably not very useful.
Some CS departments make the matter worse by calling the class Advanced Algorithms, which gives students a wrong impression. Students may believe that they are going to learn algorithms instead of tools for working with algorithms. I prefer the approach our mathematics department had when I was a student: they gave classes at the same level names like "Elements of Set Theory" and "Introduction to Elementary Number Theory".
Additionally, the example you used was actually pretty good. There is a parameter k that determines how easy or hard the specific instance is. The class used sorting as an example, because it's a non-trivial problem with many algorithms students are already familiar with. And the optimization target was asymptotic complexity, because it's easy to deal with without turning the assignment into a semester-long project.
If your job is designing practical algorithms (as mine is), you'll often end up in similar situations. Maybe you get the parameter k as a guarantee that allows you to use an algorithm that is faster with easy instances than the general-purpose algorithm. Or maybe you design an algorithm with its resource usage depending on k, regardless of the value. Or maybe the algorithm you already have is often faster than expected, and you want to find the parameters that determine how easy or hard an instance is. Or maybe you already have the algorithm and know the parameters, and you want to determine and log the values of the parameters in case a user reports worse than expected performance in some situations.
I really enjoy low level development... things like OS and compiler design. Emulation, simulation, etc. It's sad there's very little place for these "hobbies" anymore, other than that, a hobby.
And just like child rearing and homemaking, another line of work fundamental to the well being of society goes unrecognized, underpaid and expected to be done out of love while other profit from it.
I have done my share of compilers work a long time ago, my masters thesis was on this topic.
The article mentioned a very important but not well known aspect right at the end which is compilers is not a homogeneous topic but has a fairly independent parts. Front end, optimizers, and target code generation. I dabbled little bit in optimizers and a lot in target code generation. It was quite fun to figure out how to produce optimal machine instructions, or use as few registers as possible etc. Along the way I also got to learn a bit about the OS because one has to know an executable file’s layout, how to utilize heap, make sure not to over run stack etc.
And some fun algorithms too, such as a smart way to traverse tree by pointer reversal to avoid recursion as one can’t use recursion (extra space) while garbage collection.
I think it’s completely insane that you can get a computer science degree without both a compilers course and a computer architecture course. It’s entirely normal for a developer to start their career without really knowing how code becomes assembly or how a computer processes assembly. That’s wack.
My two answers - based also on personal experience - would be:
1. If you are ever concerned with code performance, you need to know what the compiler (/interpreter) is doing with your code. With a compiler course, you'll get a basic understanding - enough to later actually look at what the compiler is doing with your real-life code.
2. If you write a software system which can handle computation tasks that are not fully known at compile-time - such as user queries in some domain-specific language - then you are likely to end up implementing a compiler in your software system. If you haven't learned about compilers, you'll (a.) may fail to realize that and (b.) are likely to do it more poorly than if you have.
---
My beef with compiler courses, though, is the excessive focus on parsing. Text parsing, look-ahead grammars etc may be interesting in themselves, but IMHO they're mostly self-contained and not what you will be concerned with in the life-scenarios I've described above. I would have liked, in hindsight, to have more time devoted to optimization selection, passes and what goes in each of them, optimization work on the AST vs work on the IR etc.
>why the hell should I take an electromagnetism course as a physics undergrad? I want to work in fluid dynamics dammit!
unfortunately there are too many people who think a CS curriculum should be an advanced coding bootcamp instead of a place where you actually explore how your software works
I took the compiler class at Harvard extension school, after being a developer for a long time. I learned so freaking much. It’s such a hard course since you write a C compiler basically from scratch but it was without a doubt the best learning investment I ever made.
Compilers are like puzzles to be solved. They are so deeply coupled internally and so grounded in pure logic that in many cases, features of the languages implement themselves as the logical consequence of the way the compiler it's constructed.
Learning them also teaches some skills on how to subdivide the solution to a really complex class of problems into comprehensible chunks.
Heck, there are many seemingly unrelated problem domains that can borrow solution strategies from compiler design and implementation.
It definitely is a nice tool to have in your tool belt.
In lieu of this, Nand2Tetris [1] is an absolutely great online, free course where one can go through all of a computer's abstractions - logic gates to an assembler to a bytecode compiler to a stack based virtual machine with an interpreter and an operating system with display, I/O, etc, building everything along the way yourself.
The hardware stuff is in a simulator of course, but that doesn't take away from the gold mine of revelations one gains from going through this course.
The community is great as well, so many people did amazing things like build entire ray tracers in their own computer. Although I stopped at a sudoku game, seeing all of that is so good.
As a Mathematics undergraduate I am not allowed by my university to officially take (and receive credit for taking) most non-beginner Computer Science courses, including Compilers. At least I'm allowed to attend the lectures and cram it in alongside my other pure math classes!
When I was a math grad student, I technically could have gone through the process to get 1 or 2 CS courses approved to give credit toward my degree, but I never actually cared about the "credit" part, anyway. So, I did my regular course in the math department, taught for the math department, then hung out half the day in the CS department. I ended up auditing, and thoroughly half-assing, Algorithms 1, 2, and 3, Programming Languages, and Automata Theory. Still learned a lot, in spite of the half-assery.
Did your timetable/coursework schedule allow you to audit a meaningful number of external courses? I find that I can only allow myself to attend one additional course per semester.
I STUPIDLY started going to lectures on Computer Systems this year without doing my research first (I couldn't find the timetable for Compilers, and relied on being able to take it officially next year). Turns out I don't have enough (or any) background in C, and so I couldn't make sense of a lot of the lecture material. Oh well, at least now I'm learning C, and I still have the lecture recordings.
In terms of cost/benefit, I think it makes way more sense to learn to think in terms of "algebras", and how to create both internal and external DSLs in a host language. I've found it incredibly helpful to have an algebra-first approach as I model a (complex) domain and service interactions. Being able to write business logic as the composition of algebraic actions in several lower-level services, along with interpreters just feels great.
Of course this overlaps strongly with particular aspects of compilers, but I find that external DSLs, which is where the overlap is greatest, are the tool that I reach for least often and that elicit the greatest resistance from fellow engineers.
I have noticed that the best developers I have ever worked with knows how to write a compiler. And the not-so-great developers don’t. It might just be a random correlation of course. But perhaps not?
I’m currently in a part time masters program for fun and taking the compilers course. I’m sure John’s experience is different than mine, but it seems the question should be put to universities. The professor of my course, by his own admission, hasn’t studied compilers other than his undergrad decades ago and as far as I can tell was assigned the course to teach. As a result the syllabus is relatively dates. I think I’m 8 weeks in and we’ve only discussed parsing theory. As far as I can tell there won’t be time for detailed study of code gen, optimizations, type checking, etc.
As part of my degree, I took linguistics as a humanities elective. I guess at my university, they don't have many CompSci/SoftEng students take a linguistics course. My professor asked me specifically why I took her a class. I told her that I knew Noam Chomsky, a god in linguistics, helped shaped quiet a few things in Computer Science. Really surprised her that I knew that and thought it was awesome.
Also for anyone. If you get a chance to take a linguistics course, take it. It really is a fascinating topic. The implications on computer languages, but just in general it is just interesting.
I think there is a more general argument to be made than the one about predicting compiler optimisations. Being familiar with how a compiler typically works allows me to use one more fluently in various ways. For example, predicting and fixing compile errors, because I know roughly what the compiler will be looking for.
Anyone has suggestions for taking such course (books, websites etc.)? During my studies there was no compiler course on my university (which is saddening). I would also like to find some reputable OS internals course or book...
just make a compiler. same result, less time, more learning.
yes you should be able to "just do it" nothing involved is hard, everything i needed i had by age 14 in the 1990s without the internet. this means you have it too.
I'm interested in this topic, because I want to participate in TinyC compiler's development; I use it quite often to run C demos of mine and its execution is instant.
The least I can do is to either fix bugs or extend it to support more C99, C11, C17 features, and why not even C23 as soon as it gets approved?
All I need is to gain the necessary knowledge and experience to jump right in and start fixing things.
In my first job, back in the late 90s, I was working for a company that, having taken their biggest customer yet, had to split a very large C monolith into chunks that could run on separate servers. The architecture team of the company found all the places where the system should be cut, but that let them with hundreds of functions that had to be replaced with asynchronous calls relying on a queuing system. I was hired into the team that had to stub those hundreds of functions, type up serialization and deserialization for all the hundreds of data structures involved, and gluing it all together. So they had budgeted for 6 months of typing from a team of relatively new developers.
As you might expect, that's not how anyone wants their career to go, but I had taken the compiler class. So I knew I could parse all the header files for the functions we needed to replace, parse the data structures along with it, and just generate all the boilerplate away. My dev lead thought there's no way we could do this, but his manager decided that, at works, giving me two weeks to try it would be a great opportunity to teach the new hire the limit of his knowledge. But as anyone that has taken the compiler course knows, parsing boring C structs and header files isn't magic. So two weeks later, the project was done, and it was working.
As you might imagine, the dev lead, in his 40s, couldn't handle the results all that well, and left quickly. So I went from being stuck writing boilerplate from month to a quick promotion to team lead in under a quarter, all thanks to the compiler course.