
In the early days of computer science, the interactions of hardware, software, compilers, and operating system were simple enough to allow students to see an overall picture of how computers worked. With the increasing complexity of computer technology and the resulting specialization of knowledge, such clarity is often lost. Unlike other texts that cover only one aspect of the field, The Elements of Computing Systems gives students an integrated and rigorous picture of applied computer science, as its comes to play in the construction of a simple yet powerful computer system. Indeed, the best way to understand how computers work is to build one from scratch, and this textbook leads students through twelve chapters and projects that gradually build a basic hardware platform and a modern software hierarchy from the ground up. In the process, the students gain hands-on knowledge of hardware architecture, operating systems, programming languages, compilers, data structures, algorithms, and software engineering. Using this constructive approach, the book exposes a significant body of computer science knowledge and demonstrates how theoretical and applied techniques taught in other courses fit into the overall picture. Designed to support one- or two-semester courses, the book is based on an abstraction-implementation paradigm; each chapter presents a key hardware or software abstraction, a proposed implementation that makes it concrete, and an actual project.
I advise the readers to check out not only Nand2Tetris but also Turing Complete game on Steam (and hopefully back on GOG at some point). The author came back to it and started posting updates a few months ago after almost 2 year silence. He rebuilt the engine with a huge performance boost and is now adding more and more features.
Not affiliated with him in any way, just think the game is great and his dedication to it deserves respect.
You can learn both of these quickly to a deep level with only 2 books. For the calculus of computation, read "Structure and Interpretation of Computer Programs" (SICP) by Abelman and Sussman. It is available for free.[0] If you understand all of this book, you understand all of the fundamentals of computer science. Every program you write from now on will be understandable to you, with enough persistence. But most importantly you will be able to think in computer programs by second nature, and communicate in this language. And when you talk to AIs in this language, they become exceedingly precise and powerful, because you lost the ambiguity in how you are conceptualizing the program.
For the engineering of computation, read "The Elements of Computing Systems" by Nisan and Schocken.[1] An abridged version of this book is available for free in the form of the Nand2Tetris course. In this course you will start with an imminently simple digital construct, and use it to build step by step a full working computer that can run Tetris. You could even write a Lisp from SICP on this computer, and pretty easily too as you'll see in SICP itself! Once you have completed both books you'll have met in the middle between abstract computer science and concrete computer science: coding.
Just like in your math class, you can see that one side of a right triangle is always longer than the others, but you cannot understand how or why or explain it or work with it until you can comprehend some simple theorems and functions, you cannot truly compose computer programs until you can speak the language of computer science. It used to be that you could make a career by copying code you saw online, patching bits and piece together to create basically working code. But that era is over. AI reads and writes and searches millions of times faster than you. But still only humans are capable of new compositions. But in order to create these new compositions you have to be able to speak a mutual language that you and the AI can understand. That language is computer science, and it hasn't changed since time began and it won't change in 10, 100 or 1,000 years from now when AI is capable of doing anything and everything better than we can. So if you want to stop struggling and start creating new and exciting things with computers, read these 2 books!
[0] https://mitp-content-server.mit.edu/books/content/sectbyfn/b...
I’d appreciate advice on learning in public and on whether the approach below makes sense.
I’m a 19-year-old programmer from Brazil. I’ve been working on systems for aerospace machining facilities since I was 17. As I’ve learned more about professional software development, I’ve also realized how messy my early code was—which I think is a normal part of learning.
I started a Computer Engineering degree at a state university when I was 18. So far, the experience has been far from what I expected. Many courses feel disconnected from real systems or hardware, with exercises that seem abstract and rarely connected to each other.
If calculus I, II, and III are essential to solving computer engineering problems, why do we mostly work with artificial examples? If concepts like frequency filters and statistics are foundational to real systems, why are they often taught without practical context?
Projects such as Nand2Tetris or Programming from the Ground Up seem to exist precisely to fill these gaps. This makes me wonder why this disconnect appears so frequently in university curricula.
Before university, I had a very different learning experience. At 14, I studied Machining Mechanics at SENAI, a Brazilian institution closely connected to industry and employers. We would learn the math behind a component in the morning and apply it the same day on real machines. We designed machining processes and built practical tools—things we could take home, use, and show to others.
Later, I participated in a CNC competition program aiming for WorldSkills qualification. That experience taught me discipline, performance, and continuous improvement.
This is the feeling I miss in my Computer Engineering education.
I’ve often been asked to teach—by friends, classmates, and even people online. I’ve helped peers and supported teachers informally for years. At some point, I realized I should stop only criticizing and try to build something that represents what I believe Computer Engineering education could look like.
I’ve always believed that engineers should be able to build their “something” from the ground up. Not as scientists, but as the people who make complex systems actually work.
For a project-based learning course, I decided to build a drone and a Ground Control Station (GCS) as the core project.
My idea is to use a top-down approach, working across multiple abstraction layers. We would start with design patterns, engineering thinking, and real-world development practices using C#. The system would begin as a modular monolith, then be decomposed into microservices. Over time, services would be reimplemented in C++, and later in C, to make trade-offs between abstraction, performance, and control explicit.
While access to electronics labs is limited, I still want to explain how the underlying physics and mathematics behind gyroscopes, GPS, and barometers are translated into real drone components by computer engineers.
The GCS would involve networking, authentication, security, and control systems, implemented as a web-accessible server, with a mobile app acting as the remote controller.
I fully expect to be corrected many times—and that’s part of the goal. This isn’t meant to be a simple DIY project, but an attempt to bring together everything I enjoy about engineering into a coherent, project-based learning experience.
My questions are:
Does this project make sense as a learning path for computer engineering?
Is this a reasonable scope for a student-led, project-based course?
Would you be willing to review the outline of a free book I’m writing based on this approach and share feedback?
I am a CompSci senior focusing on ML. My university does not have applied research in ML, so doing ML in school (classes/research) is pretty much a one-way ticket to the theory/algorithms side of academia.
Last year, I had the epiphany that I am good at (and enjoy) solving problems by connecting components in a system instead of finagling a problem into a form where we can apply some mathematical law. Specifically, I have greatly enjoyed working with artists/UI/UX/frontend/non-tech people as their back-end counterpart. I have built data pipelines for MLEs, back-end for UI/UX/frontend designers, machine learning pipeline for BME researchers and projection/imagery software for artists.
I am pretty generalist and tool-agnostic, with more breadth than depth. That feels like software engineering.
That said, I do like to have an understanding of how things work and I have a decent tolerance for reading math. This is a really nerdy thing to say but I enjoyed deriving stuff like the convergence of gradient descent and I enjoyed real analysis. I also really enjoyed Nand2Tetris (open source course teaching you to build a minimal computer from NAND gates + compiler from OOP language to binary). It's extremely elegant to me, seeing the great design choices people made in the past. I feel like these are underappreciated in software engineering.
Right now, I have an opportunity to work with my RL professor, who has an amazing track record publishing at top conferences. I am really on the fence because his research is in RL algorithms and I had a very bad experience in my last algorithm research project somewhere else (I had a vague idea of what we were doing but nowhere near enough to make contributions). I am concurrently applying to jobs and Master's and I am pretty sure I will never touch this topic again if I go into industry after graduation.
I have these two questions: 1) Do I sound like the software engineers you know? What other roles do you think I am a good fit for? 2) Should I take this opportunity simply for research exposure? Do you think this is necessary in helping me keep up with trends as an applied practitioner in ML?
P.S. This is my first time posting on HN and this seems a lot longer than the average Ask HN post. I don't know if that's appropriate. Please lmk if I should go to a subreddit instead.
Thanks in advance if you read all that!
You can get a rough idea of what you're getting into by going through the NAND2Tetris self-learning course ( https://www.nand2tetris.org/ ) and the associated textbook The Elements of Computing Systems: Building a Modern Computer from First Principles. But that's just scratching the bare surface of the depth you'd need to go to to get useful acceleration.
That doesn't even go into the eyewatering cost of the development tools and professional FPGA boards. There are free versions of the tools and small FPGA boards intended for student and hobbyist use but, assuming your code is non-trivial, they're unlikely to get you any significant speed up.
Regarding how computers work under the hood, i can recommend Nand2Tetris.