Ask HN: What are the most fundamental books on computer science?
What are those books for CS?
What are those books for CS?
Also, I'd add, at least:
Introduction to Algorithms / Cormen, Leiserson & Rivest (and recently also Stein)
Agreed. It's very much like "Feynman's Lectures" in this way.
There are much better resources for philosophy and Christianity, fundamental \neq best
On the other hand, Knuth has an incredible capacity to read, interpret, understand, and especially apply and expand the contents of research papers -- far beyond the capacity of nearly anyone else.
So if you want to spend a lot of time reading through ACM and IEEE journals, have fun. But you'll understand the research and be able to apply it far better when helped by Knuth.
By the way - the same goes for Graham-Knuth-Patashnik's Concrete Mathematics.
Retrieving data is a lot different now than what it was back in the 70s and 80s.
The "searching" section of TAoCP is about search algorithms [0]. Some of these (finding by keys, hashing, etc.) are part of what makes a search engine.
Some parts of what make up a search engine aren't related to searching at all, though. PageRank, for example, is about ranking.
I now own the second and latest edition of this volume, but it is now over 20 years old. I recommend all of Knuth's publications.
Is Search and Sorting dated? Well, it is quite old. The fold out chart of tape merging patterns for different tape based sorting algorithms doesn't really come up very often anymore. It's been over 40 years since I've had to write programs that worked with mainframe tape drives.
Although AVL trees are covered well, there is no coverage of red-black trees or splay-trees.
Hashing is covered extensively, but there is no discussion of more modern hash table methods (like Cuckoo Hashing or Robin Hood Hashing or the power of choice results).
Furthermore, the basic hardware model used by Knuth in volume 3 assumes uniform costs for memory access. Cache sensitive algorithms aren't considered in volume 3 but are very important today.
Even quicksort, which I learned by studying Volume 3, now has what I consider to be a more modern treatment in Sedgewick and Wayne's Algorithms, 4th Ed.
I found Operating Systems: Three Easy Pieces to be better.
For instance, there is a whole subset devoted to turing machines, the halting problem, finite state machines, provability, incompleteness, the set of all sets, diagonalization proofs etc
There is a whole subset devoted to programming languages: computational complexity, reducing the time spent in loops, and so on.
Then there is a whole bunch spent on best practices: git and other version control, review, commenting style.
Then there is this actual thing called programming: learning different languages, arguing when functional is better than object oriented, please build a web server in prolog as an exercise, and so on.
Then there is a bunch about operating systems, and where the hardware meets the software, and garbage collection, and parsing and all that stuff.
Then databases are their own thing: boyce-codd normal form, ACID properties, is the web a database? how do you prove the ACID properties? Distributed databases, and B-trees time for storage and retrieval.
These are just various sort of "verticals".
I myself like to think of it in terms of specializations: data science/machine learning is one, web apps are another, mobile apps are another and so on. Each specialization depends on what useful thing you are trying to achieve.
Sort of like how Set theory and Category theory make up the fundamental basis of all math, the fundamentals of computer science are encoded within your first example:
>For instance, there is a whole subset devoted to turing machines, the halting problem, finite state machines, provability, incompleteness, the set of all sets, diagonalization proofs etc
So the closest parallels are original research papers like Turing's and Shannon's; but you're probably better off reading more recent textbooks.
That said, to balance out the heavy emphasis on programming and engineering books here, some recommendations:
- Sipser. Introduction to the Theory of Computation.
- Russell, Norvig. AI: A Modern Approach.
- For algorithms I don't have a preference. There is Dasgupta-Papadimitriou-Vazirani; Cormen-Leisersen-Rivest-Stein; Kleinberg-Tardos; and more.
A bit farther from core CS, I also like:
- Cover, Thomas. Elements of Information Theory.
- Li, Vitanyi. An Introduction to Kolmogorov Complexity and Its Applications
See: https://webcourse.cs.technion.ac.il/236343/Spring2004/book.h...
- Computers and Intractability: A Guide to the Theory of Np-Completeness
- Computational Complexity (your page has the one by Papadimitriou, but putting it on my Goodreads list led to two others of the same name by Goldreich and Arora/Barak I didn't know of)
Computers and Intractability is a class, it's from 1979. It's most famous for having "the list" of NP complete problems. Obviously not an exhaustive list, but it still merits the definite article :-)
Nowadays this is maintained on-line of course:
You need to know numbers and simple algebra to tackle trig, you need to know all that to tackle calculus or linear algebra, you need to know those to tackle differential equations.
I would argue CS is closer to philosophy.
Sure you have programming building blocks like variables, loops, conditionals, objects blah blah.
But you quickly head into patterns and conventions that started out as someones opinion on how things should be set up, rather than some fundamental principle.
Mathematics has a linear progression... up until the point at which it branches out into the various subfields.
It very often happens that the shortest, simplest derivation is discovered a century after the original discovery.
E.g. if you define exp(x) as \sum_0^\inf \frac{x^n}{n!}, a crazy amount of things that (historically) took a lot of effort to derive, become exceptionally simple and straightforward.
Now, historically, it didn't make sense to define it that way (especially because limits and infinite sums were only rigourously defined much later). But complexity wise, it is much simpler to first define limits and only then the exponent as an infinite sum.
> But you quickly head into patterns and conventions that started out as someones opinion on how things should be set up, rather than some fundamental principle.
That's not computer science. That is indeed philosophy, specifically software engineering philosophu. Science, it is not.
"The acceleration of the curriculum has had its cost: there has been an accompanying trend to prune away side topics. When I was in high school, for instance, it was standard to study solid geometry and spherical geometry along with plane geometry. These topics have long been abandoned. The shape of the mathematics education of a typical student is tall and spindly. It reaches a certain height above which its base can support no more growth, and there it halts or fails."
source: William Thurston - Mathematical Education https://arxiv.org/pdf/math/0503081.pdf
Computer Systems: A Programmer's Perspective has a lot of good explanations of hardware/os subsystems that can be hard to find detailed explanations of elsewhere. I especially like the sections on virtual memory.
I never took the original 6.001, so my comparison point is actually a stripped-down reincarnation of the original course which is taught by alumni volunteers during the January IAP term. http://web.mit.edu/benmv/6.001/6.184/website/
I think it's more accurate to say that they didn't see a reason to require engineers to learn CS. The class is now completely different. Why python? Not because it's a good programming language, but because there was a library the students could call to control a robot, which was the new goal of the class, not programming.
Here's the quote:
You have to do basic science on your libraries to see how they work, trying out different inputs and seeing how the code reacts. This is a fundamentally different job, and it needed a different course.
So the good thing about the new 6.001 was that it was robot-centered — you had to program a little robot to move around. And robots are not like resistors, behaving according to ideal functions. Wheels slip, the environment changes, etc — you have to build in robustness to the system, in a different way than the one SICP discusses.
And why Python, then? Well, said Sussman, it probably just had a library already implemented for the robotics interface, that was all.
https://www.wisdomandwonder.com/link/2110/why-mit-switched-f...
This one's for you if you want to learn or just recap principles of computers (and read on evolution as well). I just started reading it and found it suprisingly easy to follow. It's perfect if you like things explained step-by-step and in a simple way.
Definitely would recommend!
However, I bought this book in 2013 and was disappointed. I kept the book in the hopes that my high school and college aged kids might get something out of it. This is a book appropriate for someone new to programming. I don't consider this a book for computer scientists that already have a university degree, since it provides only a very basic introduction to Boolean algebra, logic gates, computer arithmetic. If you know what a NAND gate is and what a XOR instruction does you don't need this book.
For the practicing professional or a serious CS student interested in bits and bytes I might recommend Hackers Delight, Second Edition by Hennry S. Warren Jr.
It's an extensive and well-rounded look at various fundamental system administration topics with examples included from multiple different *nix distributions (topics like work management, logging, networking, security, the kernel, systemd, permissions, etc.). If you're at all interested in Linux, this is a great book to have on your shelf.
I dispute this idea. For some disciplines, this may be so. For other, such as physics, biology, chemistry, mathematics, civil engineering, poetry...actually, for most disciplines they aren't based on fundamental books. They're based on a living community of practice.
In these disciplines a book is important only insofar as it can be used to increase your abilities. No one goes and studies the textual details of Landau & Lifshitz as a guide to anything, any more than they do so with TAOCP.
Rather than worry about fundamental books, worry about opening up black boxes at a steady rate.
The question as posed does not strike me as one of worry, but of curiosity: what ARE the seminal works that the different fields point to as being the "bibles" of their discipline? Comp. Sci. has Knuth, Russel and Norvig, etc. Other fields most certainly have their own, and knowing which those are is interesting and worth getting an answer to.
https://en.wikipedia.org/wiki/Artificial_Intelligence:_A_Mod...
The one thing that I've found with some of these "fundamental" books is that there are gems of information that can be very helpful for specific problems.
For instance, Landau and Lifshitz's statistical mechanics book has first-rate description of entropy and multiplicity. And TAOCP has an incredibly thorough discussion of combinatorics that I found invaluable.
I'd say: every discipline has it's most fundamental memes
They are usually hugely influential in their times but have been refined or made easier to digest since. If you care deeply about your field you should read them at some point to see how ideas evolved historically.
English: Shakespeare
Biology: Darwin's Origin of Species
Math: Euclid's Elements
For OP's topic, I'd say Shannon's "A Mathematical Theory of Communication" is up there for computer science.
1. Historically foundational: books that brought important ideas, introduced a new branch, progressed the maths significantly. You can read them these days, but their content, proofs, language, etc. is not up to date. Examples: Elements by Euclid, Philosophiae Naturalis Principia Mathematica by Newton, Disquisitiones Arithmeticae by Gauss.
2. Modern foundational books: The ones that can be used for studying now. Books that are clearly written, popular, cover their subject well. Examples: Visual Complex Analysis, Spivak’s Calculus, Linear Algebra Done Right, Hardy’s An Introduction to the Theory of Numbers.
Then I studied a matrix of math books, along with other CS books regarding compilers, operating systems etc. My aim was to get good enough understanding to comfortably digest the famous research papers.
I am yet to find definitive books that teach a way of thinking on their own merit as a single book. Cs like others is a matrix of knowledge that clicks as a whole 'chunk' of understanding, changing the way you have thought about things like programming in general. I'm having a hard time explaining this.
If you're not a CS graduate, I highly suggest simply going through academics of places teaching theoretical CS.
If I had to say one text that is the fundamental one, I would go with a paper: “On Computable Numbers, with an Application to the Entscheidungsproblem” [1], by Alan Turing.
---
But if you just started your course in Computer Science, then I will give you some “bookshelf advice" based on my experience. I had the pleasure to study all the books I am going to recommend you, and most of them I was able to read cover-to-cover during the university years. And they are also in my bookshelf for reference.
The book order does not represent rank of importance.
* “Introduction to the Theory of Computation”, by Michael Sipser.
* I also recommend the “Elements of the Theory of Computation”, by Christos Papadimitriou.
* Another good complement is “Introduction to Automata Theory, Languages and Computation”, by Hopcroft and Ullman. (Thanks, @reacweb, for the reminder.)
* “Graph Theory”, by Reinhard Diestel. * If you feel you want to go deeper, and like a book which you cannot skip a single word, I strongly recommend “Modern Graph Theory”, by Béla Bollobás: it is one of my favorite textbooks ever!
* “The Algorithm Design Manual”, by Steven Skiena. * While a lot of people seems to praise either the Cormen et al. or the Sedgewick books, I have the feeling that “Algorithms” by Dasgupta, Papadimitriou and Vazirani is my choice for “fundamental” book. But I decided to
* “Computer Architecture: a Quantitative Approach”, by Hennessy and Patterson.* “Modern Operating Systems”, by Andrew Tanenbaum.
* “Artificial Intelligence: a Modern Approach”, by Russel and Norvig.
* “Modern Compiler Implementation (in ML)”, by Andrew Appel.
I would like to also recommend “Concrete Mathematics”, by Graham, Knuth and Patashnik, but I remember to not feel it the most pedagogical book on the subject.
Good luck!
---
[1]: https://www.cs.virginia.edu/~robins/Turing_Paper_1936.pdf
Certainly that one, but I would add a couple of others:
"https://en.wikipedia.org/wiki/The_Laws_of_Thought" (George Boole) - lays out boolean algebra; fundamental to everything in computing
"https://en.wikipedia.org/wiki/A_Symbolic_Analysis_of_Relay_a... (Claude E. Shannon) - basically lays out the equivalence of switching circuits to boolean algebra, fundamental to electronic computing
Note in fact many of Shannon's works and research could be considered "fundamental"...
Its contents have had continued relevance as computer scientists study the properties and capabilities of non-deterministic computers.
The Annotated Turing: A Guided Tour Through Alan Turing's Historic Paper on Computability and the Turing Machine
Structure and Interpretation of Computer Programs
Purely Functional Data Structures
Programming in the 1990s
A Logical Approach to Discrete Math
I'm guessing like most people who bought it, it sits collecting dust on the shelf.
Youthful naivety is the only reason I bought it. Completely impenetrable but look, "I'm a real™ software engineer now"
I do least take solace in the fact that the contents of TAOCP are a lot less likely to get stale than the majority of tech books.
I think even Knuth himself would agree here - but it’s also worth going through the implementation yourself once or twice (even if you just throw it away) until you really understand what it’s doing, so that you know what’s most useful when.
I tend to agree, but I'm not completely sure where I'd draw the line between things you have to implement to 'really understand' and things you can just use. ie: I've written hash tables over the years, but I've never written a persistent (think Clojure) style hash table. Maybe I should write one to really understand it? It sounds like fun, and I'd probably learn a lot, but I'm also not at all convinced it would help my effectiveness. The argument becomes even less convincing at larger scales and lower layers. (I don't need to implement a language runtime or SQL database to understand how to use one effectively. Even if, again, both of those sound like a lot of fun and a good way to learn some thing.)
If I had to come up with a general guideline, it would be to encourage developers to be mindful of what's around their layer of the stack and be prepared in the (very unlikely) event to work in one of those layers. But even that's kind of handwavey.
The books are a collection of algorithms and commentary on them. That is not that different from a collection of algorithms in a library.
It's not a page turner where you'll read it from start to finish. It's a resource. As you encounter subjects in computer science and math you can be sure there's a section on it in TAOCP with a deep dive into it.
I pull mine out from time to time when doing research mostly. I've mostly been interested in automated theorem proving, logical databases, etc. Proof search and deductive queries have a lot of moving parts, need to be fast in order to be interactive, and while the book on combinatorics isn't finished yet... the faciles have been amazing.
Yes they do mostly sit there for the most part. But then again so do most of my books. TAOCP is thoroughly researched and hands-down the best resource for a precise treatment of its subjects.
I’ve seen other people suggest that, and I always find it surprising. I did read all of them (well, the first three, anyway) cover to cover, and I can’t imagine trying to jump into the middle without having absorbed all of the preceding material first. The book is so full of back references that even having read everything in order I still found myself turning back to re-read sections that were referred to later. I’m genuinely curious, which sections were you able to make sense of “standalone”?
I don't remember exactly but I've found chapters in the first book on fundamental structures such as trees and sorting algorithms tend to stand well alone.
More recently I've been diving into Book 4, Facile 6 on SAT solvers, combinatorics. I tend to already have some familiarity with the material so it seems to me to stand well on its own.
I really enjoy Knuth's writing style however and appreciate his scrupulousness. The references and indices are top-notch so that if you aren't familiar with the prerequisites they are easily found!
Don't give me too much credit - it took me a little over three years to get through all three of them.
Then I read a Knuth book that really interested me and... there I've got my cheque. Didn't have to read much either, the first word in the first sentence on page Roman One was incorrect. :-)
However I'm now buying & progressing through volume 4 which Knuth is gradually releasing, and it's _way_ more readable, more novel for me (I already learnt my quicksort from more approachable sources, but this contains recent advanced stuff) as well as fun, if you're mathematically inclined.
Knuth still formats algorithms pretty badly IMHO, with little indentation, one-liner loops, "return to step 2" jumps, single-letter names etc. But at least they're not in assembly any longer :-)
This puzzles me from a man who pays tremendous attention to presentation and readability, literally wrote the book on typesetting algorithms & system he devised _for writing this book_, and introduced the idea of literate programming. Surely this is not oversight but very deliberate style, I just don't enjoy it much, but I'd love to learn why he chose it...
[0]https://www.nand2tetris.org/book [1]https://www.nand2tetris.org/
It's a book that explores hardware from the ground up. It's one of the most insightful books I've found for getting a real intuition for hardware.
- Theoretical CS: - Compilers: Principles, Techniques, and Tools (The Dragon Book) - Introduction to the Theory of Computation, Sipser
- Programming: - Java Concurrency In Practice, Brian Goetz - Generics in the Java Programming Language, Gilad Bracha - Professor Frisby's Mostly Adequate Guide to Functional Programming - Unix for Poets - Modern C++
- Discrete Mathematics And Its Applications, Kenneth H. Rosen (this is more foundational, but it's definitely targeted at a CS audience and touches on things like automata theory)
- Types and Programming Languages, Benjamin C. Pierce
- Semantics of Programming Languages, Carl Gunter
Data Structures and their relationship with each other to be a great technical programmer. These books (just highlight not everything) I would think -> Algorithms Sedgewick, Lisp Programmers Manual, Designing Distributed Systems. .To be a great collaborative programmer (in a work enviornment) -> Pragmattic Programmer, Code Complete, Mythical Man Month, A Philsophy of Software Design by Ousterhout. For philsophy of programming itself -> The Soul of a Machine
Edit: Programming is very broad and operates in many context from the technical, social, to the ideas behind it. I would say it is almost to early to have those definitive fundamental books
2. "Programming Pearls" by Jon L. Bentley IMO this is the most concise yet accessible gateway to the inner Mysteries of Computer Programming. Read between the lines, the prime thesis is implied not explicit.
3. "Thinking Forth" by Leo Brodie (Available as a PDF here: http://thinking-forth.sourceforge.net/ ) Most software is grossly too large. This book shows how to grok and extract the essence of your problem into minimal code. (Chuck Moore had a 3D wireframe CAD program he used to carry around as a deck of punch cards in his shirt pocket.)
The actual science in computer science? Weyuker, Sigal & Davis - Complexity, Computability and Languages; CLRS - Introduction to Algorithms. Harel - Algorithmics, the spirit of computing; And nand to tetris, in whatever format you find it.
Feynman Lectures on Computation: https://www.amazon.com/Feynman-Lectures-Computation-Frontier...
In pure Feynman style he builds up a the theory of computation from first principles. YMMV but it really helped me put many of the ideas and concepts from my CS MS into context and find new ways in which they relate with each other.
It is however in other respects a fantastic example of great technical writing and a great text book.
But as I understand it it's today mostly an extraordinarily great book on inflicting legwounds on yourself.
The book does not try to forewarn you of the myriad pitfalls inherent in C code. Nor does it delve into the language's extended API available via a plethora of internal and external libraries.
What the book does do in only 228 pages is get you up and operational in C as quickly as possible. Then caveat coder.
Personally, I'd like to see more minimalist CS books. I'm tired of having to surf through introductory tomes that often exceed 1000 pages. I'd rather an intro book introduce me to its concepts in as few pages as possible and put the programming advice and copious reference materials elsewhere, like online.
So: Yes, it's more an engineering book. Is that what michalu actually wanted, but didn't know to ask for by the right name?
If you want to learn how a computer does what it does at the absolute lowest levels, it's a great starting point. It's all written in laymans terms so it's good as a conceptual overview or for people without a strong math background. If you're interested in diving super deep into that kind of stuff I imagine it would be a great high level overview to anchor yourself.
(1) "Understanding Computation" by Tom Stuart. Not "fundamental" as a deep textbook, but very approachable for programmers intro into a big chunk of CS, explaining deep ideas about languages using rigorous working clean code (in Ruby, no prior knowledge needed). I especially loved the first few chapters about what it means to define a programming languange and various kinds of formal semantics.
(2) Designing Data-Intensive Applications, Martin Kleppmann. This gives you a phenomenally good survey of concepts and practice of distributed systems. This is more software engineering than pure CS, but in my view you can't approach the field of distributed systems without blending both anyway.
(3) POODR — Practical Object-Oriented Design, in Ruby, by Sandi Metz. This is 100% software engineering, where there is no single definition of "foundational", but many people who read this swear by it. It's remarkably thin but lucid distillation of ideas that were "in the air" but Sandi nailed them down. An important thesis is that good code is not an aesthetic judgement of how it _now_ looks, but objective question how easy it will be to _change in the future_. Not Ruby-specific at all, but it teaches the original Smalltalk "message-passing" view of OOP, that for people that only learnt statically-typed Java, C++ etc view of OOP is a fundamental idea they're missing on.
Finally, not a book, but "the morning paper" https://blog.acolyer.org/ is excellent "return on your time" if you want to sample academic papers, both classic foundational ones, as well as cutting edge.
Chapters: Introduction to Computers, Computer Organization, The Theory of Computation, Coding and Information Theory, Reversible Computation and the Thermodynamics of Computing, Quantum Mechanical Computers, and Physical Aspects of Computation.
First comment is I did get the Knuth books but I never got the college courses and problem solving work to use them. As Professor Marc Nicolet said: You have got to do the problems to master the subject (referring to his Caltech area of physics).
The second comment is computing is all binary. Go beyond that and learn about fractals, chaos, topology and knot theory. For instance, in Kaufman's Knot Theory, there are obviously true but rigorously unproven theorems in the first chapters of the book.
The third comment is after Turing's paper and Godel's uncertainty arguments, all real world computer programs, no matter how carefully they employ something from a fundamental book, must be tested.
There are much better books to learn algorithms from. Even Elements of Programming Interviews is better.
It is worth coming back to if you want to read proofs to understand things in depth. But it is terrible as a fundamental instructive text.
I'm not saying that design patterns isn't right for you, but the fact that me and many other programmers avoid it shows that it's not fundamental at all.
> Alan Kay has famously described Lisp as the “Maxwell’s equations of software”.
Maxwell's equations could be considered fundamental axioms in electromagnetism and physics. Lisp, likewise, expresses the heart of computer science at its core. I'm still working on grokking it myself, but believe that studying Lisp could be precisely what you're looking for (even if you also mean writing software in addition to strict computer science).
Paul Graham's essays could prove interesting as well.
The last time I did any kind of math that was more complex then simple operations was a long time ago and math was never my strong subject.
I have pretty much forgotten any kind of algebra, calculus etc I learnt. So assuming I know very little math, what is the best way/book/method to learn algebra/calculus etc to tackle SICP ? I would like to do that before I begin my SICP journey.
Any suggestions appreciated!!
And, it gets better, IIRC from chapter 2 there is much less math.
What happens in the first chapter, is that SICP is exploring various control structures (and abstractions over them) before teaching any compound data structures at all. So all it has to work with is numbers. But as number theory teaches us, numbers actually have a rich internal structure, and SICP uses that to make "interesting" examples!
(This aspect of SICP is one of the big critiques in the paper http://cs.brown.edu/~sk/Publications/Papers/Published/fffk-h... which explains the motivations beyond HtDP textbook. In particular, HtDP shows compound data structures first, and uses those to start with explicit methodology for data-directed design of code. These are smart programmers and smart educators, and I trust they made a better intro course. I won't recommend SICP for people who don't know any programming at all. But I feel SICP has a magical voice about the art of programming that HtDP didn't replicate — though I haven't read HtDP, only leafed through it a bit.)
So I don't recommend to to cram algebra/calculus before you begin SICP journey! Just start on SICP, and look up math stuff if/as you want.
At the beginning, IIRC you'll encounter: prime vs composite integers; base-2 representation of integers; some calculus but it's enough to understand derivative = slope. There is some symbolic algebra stuff later that's maybe trickier, but I think (hope?) SICP is actually a great book to demystify that.
---
If you do want to learn math relevant to CS, but mainly for the purpose of learning math:
- If you're comfortable with code more than math: A Programmer’s Introduction to Mathematics by Jeremy Kun.
- "Concrete Math" by Knuth/Oren/Patashnik is wonderful. Don't feel you have to finish it! I stopped ~60%.
I realize that for practically any topic covered by this book that there are more heavily optimized solutions available in the best numerical libraries, but this book nicely rounds out my reference books with clear and easy to understand coverage of subjects I don't know. (e.g. Savitzky-Golay Smoothing Filters).
I enjoy reading this book.
It's detailed enough to use when trying to understand how a shell works or how to write a signal handler, but the writing couldn't be clearer.
I don't have a concrete recommendation off-hand - but certainly something by Codd on databases/normalization should be on such a list?
A lack of understanding data normalization can hurt even "simple" code that uses structs and procedures.
Somewhat related, this interview with Date on the relational model:
https://www.red-gate.com/simple-talk/opinion/opinion-pieces/...
> A related piece of advice is: Learn the relational model first, SQL second (doing it the other way around is hard). Finally, read either or both of Ted Codd’s first two papers every year. (Those papers are “Derivability, Redundancy, and Consistency of Relations Stored in Large Data Banks”, IBM Research Report RJ599, August 19th, 1969, reprinted in ACM SIGMOD Record 38, No. 1 (March 2009), and “A Relational Model of Data for Large Shared Data Banks”, CACM 13, No. 6, June 1970, which you can find online.)
Ed:
DERIVABILITY, REDUNDANCY CONSISTENCY OF RELATIONS STORED IN LARGE DATA BANKS E. F. Codd:
http://domino.research.ibm.com/library/cyberdig.nsf/papers/B...
A relational model of data for large shared data banks:
Software should be written mostly with humans (code readers) in mind, and not machines. The soft sciences are much harder to study; it's expensive to use trial and error on real projects in order to compare outcomes. Equations on a blackboard or chips in a lab are probably not where most real IT revelations will come from.
There are pet theories that focus on overly-narrow factors. For example, those who focus on linguistic parsonomy (less code) may conclude that functional programming is "better" because it usually can be made the most compact. However, a good many coders have a hard time working well with functional programming. Some take a Darwinian view and say "fire them all and hire elite functional coders". But so far that has rarely paid off in the market-place, barring a few grow-fast-at-all-costs startups. Short code is not always legible code to the majority of coders.
The closest thing are books with specific examples that explain the trade-offs made and try to find general rules and apply them to the examples. But I find such to be either mostly opinions, or too vague to apply in practice. At best they exercise your brain in terms of questions to ask in exploring the different design options, but they don't give clear-cut rules for the final choice that stand up to scrutiny.
They can tell you about the kinds of beasts you'll encounter in the dark forest, and give suggestions for defeating the beasts, but the recipes for success are either subjective or nebulus, yet to be subjected to real testable science. They could be if some research institution spent big bucks on it, but so far nobody has.
Our field has a "science gap" which results in a book gap. The blunt truth is that IT is more about people than machines or math.
Code Complete by McConnell
I still have my first programming book that I bought in the 60s. Now, my library includes most of the books mentioned here. I've skimmed every one of them and read portions of many over and over. I've found that in the long run, they've really helped me in my career. Notice however that I've had half a century to do this reading so just give yourself time.
This isn't a criticism of Effective C++, just the opposite. Better than anyone, Scott Meyers makes many of the very technical intricacies of C++ understandable and I think every professional C++ programmer could benefit from understanding the issues he explains. Nevertheless, I find the book more of a chore to get through than most of the books mentioned here.
You might find a random CS subject really interesting and get motivated to read up on it. I done this over and over.
Personal projects are a good way to get interested. In the past personal projects have caused me to do independent study of cryptography, hash tables, compilers, operating systems, machine learning, AI, etc. I've never been interested in game development or GUI programming, but recently I decided I would write a simple chess playing program just for fun. I'm currently stuck building the GUI for it, but it's caused me to study game engines and GUI frameworks.
[0] https://news.ycombinator.com/item?id=20729252 (What book to read to get a footing in CS theory?)
Based on your comments, you seem like an interesting guy. How do I get in touch about potential opportunities?
Patterns of Enterprise Application Architecture by Martin Fowler.
Domain Driven Design by Eric Evans.
Growing Object-Oriented Software, guided by tests by Steve Freeman and Nat Pryce.
Take civil engineers. Yes they will do some physics but usually only basic stuff in first year. After that they focus more on the higher level systems they will be working with because most working civil engineers will never need anything more advanced than first year physics.
So if the person who posted this Ask HN is not going to do CS research (or the like) then Domain Driven Design might be as fundamental to their education as structural engineering is to a civil engineer. The fact is that nearly all systems that we work with are composed of services/models of some kind. DDD deals with these but more importantly deals with the domain where you can make the most impact as a working engineer (as opposed to a scientist who is like a force multiplier but we need a lot less of them).
"Domain work is messy and demands a lot of complicated new knowledge that doesn’t seem to add to a computer scientist’s capabilities. Instead, the technical talent goes to work on elaborate frameworks, trying to solve domain problems with technology. Learning about and modeling the domain is left to others. Complexity in the heart of software has to be tackled head-on. To do otherwise is to risk irrelevance" - Eric Evans
I find it funny 'Structure and Interpretation of Computer Programs' is considered fundamental when it's basically an MIT textbook. Presumably it's a very good textbook, but it's not fundamental because the rest of the world doesn't really study it. The world does study Aristotle.
CS is also a wide field (and I presume you said this on purpose to separate the software engineering books?). Something by Chomsky for formal grammars comes to mind.
If anything, that suggests to me that it is not. "Philosophy for Dummies" far outsells Plato.
There are only five patterns that matter in real world software development.
Observable
Singleton
Composition
MVC
Inversion of Control
And the last one isn't even covered by GOF. The book is an out of date relic of 90s programming. Let it die already.
don knuth's art of computer programming [if you like some rigor][it is a bit time consuming to read the whole thing , but be sure to atleast try reading the first volume]
2. Like I said elsewhere - TAoCP is an impressive book, but it's certainly not fundamental. It's not used as the "fundament" or foundation of people's CS knowledge.
Software Engineering? no clue
And I am surprised no one mentioned Operating System Concepts (the dinosaur book).
It was the most useful CS text I read in college. I see a lot of SICP love; I never had it for a college course, but it looks good as well.
Doesn't 'fundamental' often span a wide range, from bottom-up to top-down? Surely CS fundamentals lie not only at the bottom (e.g. assembly language or discrete math or algorithms), but also at the top (e.g. programming concepts or software design and engineering)? Where would an education in CS be without at least an introduction to high-level concepts like object orientation or computational complexity?
And yes, I think Shakespeare is fundamental to the study of English. If the omission of any set of works would have the degree of cultural impact and leave so great a void as overlooking his would, then it qualifies as essential canon, and thereby fundamental.
It's not like classical art or architecture where the principles closer to all commanding or 'figured out'. Your everyday work is like swimming through code solving problems as you go. Pushing blocks into permanent place never works, they find a way of getting crufty, old and replaced to fit new requirements. I imagine any field that deals with flowing quantities of objects, or fluid-like systems would have structural overlaps with programming. Fields like plumbing, finance, the energy sector, ect.
I would describe programming to be at it's very base to be ascribing meaning to quantities of meaningless numbers and building a structure to pipe those numbers around to a qualitative result.
Measuring principles in depth here is not that useful, the river of valuable information runs left to right in code. You'll likely restrict how deep and how abstract you go and instead focus on churning out a high quantity of solved problems. It's just not that useful to be thinking in machine code when you're programming in C++, but knowing all the functions of C++ and where it should be ending up is very important.