Ask HN: What book to read to get a footing in CS theory?

306 points by bjackman ↗ HN
A friend of mine has just taught herself the basics of JavaScript then done a code boot camp. She's pretty comfortable writing code now, but hasn't had a chance to get to grips with stuff like complexity analysis yet.

It seems to me like she's a member of a large and growing target audience for a book that gets you started with all the stuff you would learn in a computer science degree, with the assumption that you already know how to express an algorithm as code.

Can anyone recommend such a book?

92 comments

[ 4.0 ms ] story [ 152 ms ] thread
See what some (reputable) universities in your country use for their data structures and algorithms class, and then use that.

Avoid books with a programming language in the title, because those will try to teach both basic programming and the interesting material.

(comment deleted)
(comment deleted)
Well this is superb. I've traditionally given my own piecemeal answer to the teach-myself-cs question, but I'll be handing this link out in future.
Just want to highlight this with an additional comment - as someone who went through a CS degree and was heavily interested in CS pedagogy and compared many a CS curriculum, this is a great compilation of great resources.
Skiena's Algorithm Design Manual:

https://www.amazon.com/Algorithm-Design-Manual-Steven-Skiena...

Far more readable than the usual text (Cormen), the first half is a guide on how to select and design algorithms for the problems you encounter, and the second half is a whistle-stop tour of hundreds of well-known algorithms. The tour helped me a lot with X->Y esque issues where I was building bad solutions because I didn't know anything better could exist.

Incidentally, there's a lot more to CS theory than algorithms and data structures, but if you're asking on HN for a generic CS theory book, I reckon it's most likely an algorithms and data structures book that you're after.

I'm going to disagree slightly with your choice (which was also my choice at first). While A.D.M. has all the topics you would be interested in, I think the book assumes that you have already groked the fundamentals behind, say, why a linked list is different from an array. For an absolute beginner, I would suggest the type of book that forces you to go through every step of deleting an item from a list, which is something Skiena's book (luckily) doesn't do. The book is great for learning new ways to think about problems, but IMHO a beginner should learn the basic ways first.

"Introduction to Algorithms" by CLRS seems to be the default choice, and it seems to me to be a step in the right direction (based on the TOC).

I would also like to second your point that CS is more than algorithms and data structures. I feel Dijkstra would not approve of thinking about CS as "that thing you do after learning a programming language".

This is really helpful, thanks. It's been... a few years since I read Skiena, and I came to it from a maths background. I'll add the disclaimer in future that Cormen's easier to start with.
I found "Introduction to Algorithms" to be _waaay_ too dry to deal with in beginning, though I'd welcome something else to get through the detail.

Personally I'd use Cormen as "dictionary" to get into detail of stuff I first read in A.D.M.

Aho/Ullman Foundations of CS http://infolab.stanford.edu/~ullman/focs.html

O'Halloran/Bryant CSPP https://csapp.cs.cmu.edu/

David Money Harris Digital Design... https://booksite.elsevier.com/9780128000564/

Comprehensive and Worthy suggestions.

The first one was new to me. Looks quite good.

The classic "Foundations of CS" was referred to in my youth as simply "Aho and Ullmann". As I recall, it contained a particularly comprehensive explanation of the construction of parsers, compilers, interpreters and translators.
You are thinking of a different book by "Aho and Ullman". The text listed above deals more with "Discrete Maths" and "Computer Science".
I would highly recommend Imposter's Handbook[1] by Rob Conery

Then there is also excellent BaseCS Podcast [2]

[1] https://bigmachine.io/products/the-imposters-handbook [2] https://www.codenewbie.org/basecs

I would find it very difficult to recommend this book - I think parts of it are simply factually mistaken, unfortunately, and I worry someone using knowledge from it would make themselves look like more of an imposter, not less.

https://github.com/imposters-handbook/feedback/issues/50

The book itself is a good idea and the author seems to have good intentions even if they didn't take advice in this case, though.

I would recommend the Dasgupta and Vazirani book on algorithms. It has a balance between theory and practice. Plus it has a lots and lots of exercises which I found very helpful for practising.
I already addressed your question in another comment, but I would like to write a second point: a book seems to me the wrong way to go.

Unless your friend is a natural born comp. scientist, she'll need someone to point out what's important, what's not, which exercises she must solve before moving on and which topics she can take in parallel if she needs a break.

Of course, a course takes time. But if someone doesn't find the time to take an online course, where will they find the time to (properly) read the book?

I suppose a book could be written more as a course than a comprehensive reference manual?
Probably a little more advanced than what you are looking for but I would like to recommend The Nature of Computation by Cristopher Moore and Stephan Mertens as a next step. It is such a fun book to read, with a lot of problems and exercises.

http://nature-of-computation.org/

I strongly advise the following:

- The Computational Beauty Of Nature, by William Gary Flake

- The Impostor’s Handbook, by Rob Conery

- The Elements Of Computing Systems, by Noam Nisan & Shimon Schocken

For a gentle introduction to algorithms and Big O, "Grokking Algorithms" is easy to read and fun. For more in depth and systematic study, Sedgwick's "Algorithms" is a very clear and beautiful book.

For computer architecture, Petzold's "Code" is wonderful.

"Most of the code you write is run by an operating system, so you should know how those interact."

All of the code you write is run by one or more CPUs; operating systems provide supporting software, they don't "run" programs (although they may schedule them for execution, which isn't the same).

</pedant-mode>

It’s not that clear cut. Virtual Memory for example is not just hardware.
Go ahead and get your free copy of Avi Wigderson's Mathematics and Computation https://www.math.ias.edu/avi/book.

Broadly speaking there are two types of "CS Theory":

1. "What is computation and what can be computed?" That's what Wigderson's book is about. Complexity theory.

2. "What's the best way to compute something?" covered by "Introduction to Algorithms" and the like -- sth people ask on interview questions. In addition to the references here, http://people.cs.uchicago.edu/~laci/17discrete/ gives some good puzzles to work through.

Perfect answer, I second this.
A related reference, cited by this book, and a bit shorter and simpler is Garey & Johnson Computers and Intractability.

It's a really good classic little textbook.

(comment deleted)
3. "What's the best way to specify computation?" covered by programming language and compiler books.
>Go ahead and get your free copy of Avi Wigderson's Mathematics and Computation https://www.math.ias.edu/avi/book.

i've seen some ridiculous virtue signaling recommendations on hn before but this takes the cake. have you actually read the book? wigderson is an IAS professor (for those that don't know, einstein and godel were IAS professors) and this book is a research survey (most of the theorems have refs to papers). i've read both sipser and hopcroft ullman and i'm still pretty far away from being able to easily read it. and you're recommending this to someone that learned js from a bootcamp. you think maybe she's not the target audience?

so that i'm not labeled as just a critic: the standard formal languages book is sipser

https://www.amazon.com/Introduction-Theory-Computation-Micha...

it's colloquial and has a lot of diagrams and "intuition". people really like it but i actually think hopcruft ullman is better because it's more structured

https://www.amazon.com/Introduction-Automata-Theory-Language...

I can't speak to the parent's motivations, but having had a glance at this, it's clearly an entirely absurd suggestion. Section 1.4 outlines its intended audience. It (rightly) doesn't include programmers wanting to 'get started' in CS.
Hey sorry, point taken. I have read chapters and was excited about it, but I see your point. Thanks for the suggestions. I found the book more readable than hopcroft ullman from the perspective of understanding what happens in "theoretical computer science" -- I encountered it decades after grappling with hopcroft ullman (so-called "Cinderella book".)

I always find that the best books technically have been those that I take a bite from, think through an idea, maybe check out the references, find a problem to work through, then come back. Here's a quote from the intro that resonated:

"Many parts of the book require hardly any specific prior knowledge and rely mostly on the mathematical maturity needed to take in the definitions and notions introduced. Hopefully, the story telling makes the reading even easier. However, the book (like the field itself) is conceptually dense, and in some parts the concentration of concepts and ideas requires, I believe, slowing down, rereading, and possibly looking at a relevant reference to clarify and solidify the material and its meaning in your mind."

> wigderson is an IAS professor

True, but I think he does a good job of explaining things. This lecture on incompleteness seemed accessible to me https://www.youtube.com/watch?v=0Zmfv3jsiQ0&t=1788s

There's also Sanjeev Arora's book "Computational Complexity: A Modern Approach" https://theory.cs.princeton.edu/complexity/book.pdf

You should start reading The Art of Computer Programming by Donald Knuth, and solve all exercises (including ones having difficulty level 50). If you catch up finishing all currently existing volumes before Knuth finishes, with all the exercises answered thoroughly; you can consider yourself a self-taught algorithms expert.
I already addressed your question in another comment, but I would like to write a second point: a book seems to me the wrong way to go. Unless your friend is a natural born comp. scientist, she'll need someone to point out what's important, what's not, which exercises she must solve before moving on and which topics she can take in parallel if she needs a break.

Of course, a course takes time. But if someone doesn't find the time to take an online course, where will they find the time to (properly) read the book?

Most of these answers seem to be books about algorithms.

Computer science is much broader than that; it includes databases, AI (not the same as algorithms!), computer architecture, topics such as hardware interfacing, history of computing, and some overlap with areas in philosophy.

I didn't ever formally study CS, but I did read several books on algorithms. Especially notable is the seven-volume work "The Art of Computer Programming" by Donald Knuth; in particular the volumes "Fundamental Algorithms", "Sorting and Searching", and "Seminumerical Algorithms" are timeless masterpieces, entertaining and witty, and they totally nail their subject-matter. If you think CS is equivalent to "algorithms", then read these books.

N.B. I understand that some of these books have been re-written to use a revised version of Knuth's MIX machine language, to allow the examples to embody modern developments such as pipelines, caches, and parallelism. I haven't read these updated editions; no doubt they are even better than the originals.

But I think CS is a much broader field than algorithms.

[edit] Harrumph. Wikipedia says that only three-and-a-bit volumes have yet been published. Seven volumes was the original plan. Smacks a little of George R. R. Martin?

What!!!

Is this some sort of a joke? Do not troll here.

> Harrumph. Wikipedia says that only three-and-a-bit volumes have yet been published. Seven volumes was the original plan. Smacks a little of George R. R. Martin?

My favourite poke at this is Charlie Stross' book the Atrocity Archives (a kind of Lovecraftian, CS nerd horror / humour novel where advanced mathematics is dangerous), wherein Knuth did in fact finish the 4th edition, but it contained secrets that immediately got it shut down by various governments.

(comment deleted)
> have been re-written

There’s a plan in place to do so, but as of now, the current editions of the first three books are still written using MIX (the 60’s-style assembler language that he invented for the original editions). The later volumes do use the more modern MMIX.

(comment deleted)
Maybe it would be possible to give a somewhat useful first answer just as a post here; I'll try.

Going way back in computing, often an important issue was, how fast will a program run? That study is now sometimes called computational time complexity.

This study was important because, for some common work, some ways of programming the work ran many times faster than some other ways -- i.e., the study of computational time complexity got some big results.

Usually in practice an issue of a little less concern than running time was how much of the computer main memory would a program need, and this study was computational space complexity.

The first big case of big gains was running time for sorting. So, for some positive integer n, we are given n numbers (or alphabetic names, etc.) and want to sort them into ascending order. So, an obvious first approach is to look at all n numbers one at a time and find the smallest. Then look at the remaining n - 1 numbers and again find the smallest. Then with a little algebra, the running time grows proportional to n^2 (n times n, n squared). So we say (I'm omitting some fine points) that the running time is "big O n^2" written

O(n^2).

Now for some big stuff: (1) There is a way (method, technique, algorithm) called heap sort with running time (computational time complexity)

O(n log(n) )

both on average for random numbers and also for the worst case of the order of the given n numbers. (2) Heap sort works by comparing numbers two at a time (so did our

O(n^2)

algorithm above), and there is a cute counting result from A. Gleason, long a math prof at Harvard, that shows that for sorting by comparing numbers two at a time

O(n log(n) )

is the fastest possible. (3) Heap sort is also in-place which means that the storage used, except for a constant independent of n, is just what is needed for the n numbers being sorted.

After sorting, there was interest in working with trees. Likely the tree most people are most familiar with is the hierarchical file system. A tree can be good for keeping a set of numbers in order while adding numbers to the set or removing numbers from the set. To get good guaranteed fast running time, we want the tree balanced, that is, all the paths in the tree from the root to the leaves are about the same length. So, keeping the tree balanced while making the changes and doing so with relatively fast worst case running time was a challenge. One solution was AVL trees (see D. Knuth's The Art of Computer Programming: Sorting and Searching or more recent books listed in this thread) and, mostly for data stored on disk, B-trees. Actually there are several important, that is, relatively fast, algorithms for manipulating trees.

Early on in computing there were more problems with algorithms that improved running time, e.g., string searching.

There is a general technique, dynamic programming, that is the basis of several important, relatively fast algorithms. Here the programming is in the sense of the English project planning, that is, from the field of optimization in operations research.

Generally, given a program, it can be difficult to do algebraic manipulations, say, assuming either random or worst case inputs, to find the "Big O" running time. Knuth's book starts with a lot of algebraic techniques that can help finding Big O running times. That work can be as challenging as we please.

There is some work that early on was not really in computer science but very much needs computers and where running time was and is a huge issue. An important source of such work was optimization in operations research. The first work of concern was the simplex algorithm of linear programming. Next was the closely related integer linear programming, i.e., combinatorial optimization. There were too many cases of problems starting with n numbers and running in

O(2^n)

which is exponential

Errata: O(n^k) is a polynomial in n.
Errata: Should revise

"there is a cute counting result from A. Gleason, long a math prof at Harvard, that shows that for sorting by comparing numbers two at a time

O(n log(n) )

is the fastest possible."

by adding at the end "for worst case performance".

Should revise

"Then look at the remaining n - 1 numbers and again find the smallest."

by adding at the end "etc.".

Generally computer science computational complexity ignores long lists of ways to write code that runs faster, e.g., for a result needed more than once, compute it just once and store the result and don't repeat the calculation.

Instead, the emphasis is on some larger aspects, e.g., just counting comparisons. Broadly that emphasis is usually appropriate since as n grows quite soon some crude code of a O( n log(n) ) algorithm will run many times faster than careful code of an O( n^2 ) algorithm.

Errata: adding at the end "for average case performance".
A really good overview of the field of CS is _Great Principles of Computing_ by Peter Denning and Craig Martell, 2015. It's a good book for CS students who want overviews of less familiar areas of computer science, and for anyone (in other areas) who want to know more about computation.

Another is Subrata Dasgupta's _Computer Science: A Very Short Introduction_, a 2016 addition to Oxford's Very Short Introduction series. It has over five pages of further references to more detailed and specialized works.