
This is cheating a bit, because the book is history of computer science rather than computer science, but I think anyone interested in programming should read it. We often think about history of computing (and what it teaches us) in a retrospective way (we see all the amazing totally revolutionary things that happened), but it turns out that if you look deeper, there is often a lot more continuity behind key ideas (and we just think it was a revolution, because we only know a little about the actual history). This book goes into detail for a number of major developments in (early) programming and it makes you think about possible alternatives. It was one of the books that inspired me to write this essay: http://tomasp.net/blog/2016/thinking-unthinkable/