My favorite classes at UMD
It's Thanksgiving break, so I'd like to give thanks to the great experience that college has to offer. There's a few classes (and professors) that have stood out to me as exceptional during my time at UMD as a student, and I'm writing about them here.
If you're a student at UMD and are looking for some classes to take, I highly recommend these, or really any class taught by these professors.
CMSC430 with David Van Horn
CMSC430 is a class where the primary goal is to construct a self-hosted compiler for a programming language. In this class the base language is Racket, which is used to slowly build compiler constructs for various language features (data types, control flow, functions, etc). The class notes provide a comprehensive overview of building such a compiler from scratch, and are detailed enough where the notes can be used in place of a traditional textbook.
The grading was done through projects and take-home exams, which are open-note and can be done at your own pace. I found projects to very useful, since for each assignment, there are many different ways to accomplish the end goal, and each has its own advantages. Take-home exams were similar to projects, with the only difference being a 24-hour time limit between exam release and submission deadline.
The class also had a Squid Game project mid-semester, where previous compiler submissions were loaded onto a server, and as students, our goal was to find programs that exhibit bugs in these compilers where the program's behavior does not match the reference implementation. I found this to be interesting as well, since there was one specific program construct that broke almost every compiler due to a limitation in the compiler design (if you're taking this class, try to find it yourself!).
CMSC420 with Justin Wyss-Gallifent
CMSC420 provides a high-level overview of a variety of data structures, and dives deep into seeing exactly why and how these data structures are the way they are. The most memorable data structure (at least for me) is the B-tree, since it extends the idea of storing data in tree form into a more general method with guaranteed worst-case performance that won't become degraded in degenerate cases.
Similar to CMSC430, a main portion of grading is done through projects, where we write implementations for some of these data structures. The language used was Python, which I preferred over Java, and the requirements were very straightforward. One unique part of this class was instead of having pre-written test cases, new data is generated on-demand for each test run. This made it easier to debug and find issues in situations where a bug wouldn't come up except in very peculiar situations.
Another part of grading came from exams which weren't completely open-note, but we were allowed to bring in up to a page of notes, which made it more fair since we weren't expected to memorize any specific facts. I wrote a haiku on the front page of the first exam for extra credit:
Segmentation fault!
Tried to access children of
leaves in a B-tree
Justin's lectures were intuitive and easy to follow, and explains not just how a data structure works, but also why certain decisions were made, and what would be different if these reasons were changed. He also stayed after lectures and answered any questions we had after class, which helped to clear up any lapses in understanding.
PHIL470 with Eric Pacuit
PHIL470 isn't a typical CS course — it covered the foundation of formal mathematics in first-order logic. The course covered how mathematical statements could be turned into logical sentences interpretable by a computer, and how these statements can be verified by proofs checked by a computer. It then covered Godel's incompleteness theorems, where no matter how complicated a proof system is made (as long as it can be checked by a computer), there will always be mathematical statements that cannot be proved nor disproven within the system.
The course also revealed a deep connection between math and computer science and the theory of computation — every computer program can be encoded as natural numbers and can be "executed" using only addition and multiplication, and conversely, every formal mathematical proof can be expressed and verified as a computer program.
Nearing the end of the semester, the course concluded with a deep philosophical question (Godel's Disjunction) which, in a highly simplified form, goes like this:
We know that the halting problem is undecidable — that is, any computer program that tries to solve the problem will either have no answer or return the wrong answer for some inputs. What does this mean for the human mind? Suppose that computers become advanced enough that they can fully simulate any person's thought process. But this means that there are some problems in math that nobody can ever solve — otherwise the computer can decide the halting problem, a contradiction. The other option is that no computer can fully reach the human level of intelligence.
With the recent advancements in AI and machine learning, this represents an important question that may soon be put to the test.
Overall, this course let me realize what mathematics really is and contemplate what makes a mathematical statement "true"; perhaps that question can and will never be answered.