The Reading List

by Zoran Horvat
Sep 19, 2017

People often ask me what books do I read, thinking about programming books. Then I have a hard time explaining that I read whatever I can get hands on. It is not only what I read, however. It's also about the way I read any technical paper or a book.

In this text I plan to present my reading habits, and then to list the books I recently completed reading. That would be the complete answer to any question made up of words "I'd like to know what books you read." And when I say reading habits, I do mean habits, not rules. I'm not keen to follow rules even if I myself made them up. While reading, for example, I developed habits that are doing good to me, and explanations that follow will be sufficient for you to understand why I have settled down with these habits.

Hence, the first list - the reading habits:

  • Read cover to cover - Never skip content in a book. People are sometimes reluctant to read an entire book, especially if they planned to improve knowledge in one narrow field, covered by a chapter or two. But think about that from a different perspective. All chapters in a book are related in a way - they wouldn't make up a single book otherwise, I presume. If you are satisfied with what you find in one chapter, then my guess is that other chapters will not leave you disgruntled, to say the least. Maybe you're highly proficient in topics covered by other chapters, making it a waste of time to read them. Still, you might be surprised to learn that the author had a different, often better view on the content than you did. And one more note. Authors sometimes suggest that the book is conceived to support out-of-order reading, and even skipping entire chapters. Don't trust them - authors' motives are none of your own.
  • Read references - Authors will usually refer to literature they used. Make a shortlist of references as you read. Some of them will repeat - pay greater attention to them. In the end, if you wish to learn more after completing a book, then this shortlist of references will probably contain at least one book to read next.
  • Develop a sense of incompetence - Every once in a while you will figure that you don't quite understand what you're reading. Develop a separate sense for those moments. Don't just let the feeling pass unnoticed. It might come from a theory you don't understand, or a thinking method you can't follow. Just skipping over will keep you in blissful ignorance of whatever that was. That is not the problem in itself, especially if you find only a little interrest in that single section of the book. The problem may, however, be wider than that. It could be the new area of research for you, which would bring revenues if only you learned it. Anyway, payout is not always guaranteed. To cope better with this problem, I am using a simple rule of thumb - do nothing. Catch yourself desperately lost in a piece of text, but still do nothing other than remembering the moment. In some other book, you might feel the same, and then you will notice that it has to do with the same mysterious content you didn't understand the previous time. Now that is already suspicious, you see. If you repeatedly encounter references to the same background knowledge you keep lacking, then that will be the signal for you to add books on that topic to your future reading list.
  • Be a critic - Don't accept anything books tell for granted. Books are written by humans. Authors with long history are notorious of contesting their own designs from the past. Why would you not contest their designs then, too? This doesn't mean to walk around and talk the book down. My advice to you is to keep the critic to yourself. Try to figure what motives lie behind a design from the book. Could it be made better in some respect? How can that turn bad? Or what are the situations in which that design will really shine, compared to all the others you could remember or construct instead. Note that nothing written in books is correct per se, unless it comes bundled together with a formal proof.
  • Apply what you learn - Learning is not a goal itself. You learn because you wanted to apply new knowledge. I know of people who learned touch typing but still type with only a couple of fingers at work. The reason, as I could see it, is that they are still typing faster with four fingers, and they fear that switching over to all the fingers they had would hurt their performance. My advice was: Make a decision and start using what you have learned right away. It will be hard, it will cost you, but when you become proficient, it will pay dividends you wouldn't acquire the other way. If you have invested in crunching technical knowledge, in reaching higher background understanding, then invest a little more and make that part of your everyday work.
  • Shuffle it - Don't stay for too long within one area of research. You might come to, say 80% of your potential after reading a book or two. You could bring that to 90% after another five books or so. And you could be the best in the town twenty years later. You see the problem, don't you? I rarely read two books in a row from the same area. My intention is to raise competence a bit by reading one book from one area, and then move to a different topic where reading additional book would have more impact.
  • Keep a TOREAD list - If you are already keeping a TODO list, list of tasks that are awaiting you, then you will understand the TOREAD concept right away. In my case, that is the list of books I'd like to read in the future. It doesn't matter when, and in what particular order. It doesn't even mean that I will really read them. That's what makes it different from TODO lists. I keep a note on my smartphone, titled "future reading," with about twenty books right now. And that changes quite often. While reading one book, I might add a couple of new titles to the list. When the time comes to pick the next book to read, most often I choose one from the list. The list is not sorted by any criterion. I might put stronger candidates first, but that still doesn't put them in a better position.
  • Read everywhere - I don't mind reading anywhere I happen to be. I'm reading paper books at home, but most of my technical books are e-books. I'm subscribed to an online platform where I have access to many books from tablet and smartphone (and PC, but I don't like the idea of having to sit by the computer to read). When I walk, wait in a line, drive in a bus - I steal every moment to read. As the matter of fact, if you ever came across me in the street, I will most likely hold a smartphone and read a technical book from it. That is what makes it possible for me to read at least 10 pages per day, and often more than that. That adds up to thousands of pages every year, averaging one book cover to cover completed every month.
  • Keep notes - While I read, I copy important sentences, explanations, definitions, etc. and keep them aside. From time to time, I refer back to these quotes. This practice has roots in writing notes down on paper. That was my method of remembering things better in the years of paper. Today, writing things down from a book boils down to a copy and paste operation in an editor, which doesn't improve my chances of remembering anything. Yet, I still take notes because that makes it possible to do a quick search on them later. That has saved me in more than one situation when I was in urgent need of memory refresh.

And now the reading list. Below is the list of books I have read in recent couple of years, in reverse chronological order.

  • Alan Page et al., How We Test Software at Microsoft View
  • Scott Bain, Emergent Design: The Evolutionary Nature of Professional Software Development View
  • Scott Wlaschin, Domain Modeling Made Functional View
  • Vaughn Vernon, Reactive Messaging Patterns with the Actor Model View
  • Joost Visser et al., Building Maintainable Software, C# Edition View
  • Neal Ford et al., Building Evolutionary Architectures: Support Constant Change View
  • Christian Horsdal, Microservices in .NET Core: with examples in Nancy View
  • Vaughn Vernon, Domain-Driven Design Distilled View
  • John C. Mitchell, Concepts in Programming Languages View
  • Martin Fowler, Domain-Specific Languages View
  • William Mougayar, Vitalik Buterin, The Business Blockchain View
  • Mathias Brandewinder, Machine Learning Projects for .NET Developers View
  • Neal Ford, Functional Thinking View
  • Steve McConnell, Code Complete View
  • Christian Nagel, Professional C# 6 and .NET Core 1.0 View
  • Code Contracts User Manual View
  • Mark Michaelis, Eric Lippert, Essential C# 6.0 View
  • Jim Webber et al., REST in Practice View
  • Sam Newman, Building Microservices View
  • Cuno Pfister, Getting Started with the Internet of Things View
  • Sergey Barskiy, Code-First Development with Entity Framework View
  • Dick Grune et al., Modern Compiler Design View
  • Jimmy Nilsson, Applying Domain-Driven Design and Patterns View
  • Andrew Hunt, David Thomas, Pragmatic Programmer: From Journeyman to Master View
  • Bertrand Meyer, Object-Oriented Software Construction View
  • Steve Freeman, Growing Object-Oriented Software, Guided by Tests View
  • Kent Beck, Extreme Programming Explained: Embrace Change View
  • Michael C. Feathers, Working Effectively with Legacy Code View
  • Steve Krug, Don't Make Me Think: A Common Sense Approach to Web Usability View
  • Dino Esposito, Andrea Saltarello, Microsoft .NET - Architecting Applications for the Enterprise View
  • Zeeshan Hirani et al., Entity Framework 6 Recipes View
  • Ross Mistry, Stacia Misner, Introducing Microsoft SQL Server 2014 View
  • Rebecca Wirfs-Brock, Alan McKean, Object Design: Roles, Responsibilities, and Collaborations View
  • Martin Fowler, Refactoring: Improving the Design of Existing Code View
  • Robert C. Martin, Micah Martin, Agile Principles, Patterns, and Practices in C# View
  • Vaughn Vernon, Implementing Domain-Driven Design View
  • Donald E. Knuth, The Art of Computer Programming, Volume 1: Fundamental Algorithms View
  • Bill Wilder, Cloud Architecture Patterns View
  • Robert C. Martin, Clean Code: A Handbook of Agile Software Craftsmanship View
  • Eric Evans, Domain-Driven Design: Tackling Complexity in the Heart of Software View
  • Frederick P. Brooks Jr., The Mythical Man-Month View
  • John Bentley, Programming Pearls View
  • Mark Seemann, Dependency Injection in .NET View
  • Tomas Petricek, Real-World Functional Programming: With Examples in F# and C# View
  • Martin Fowler, Patterns of Enterprise Applications Architecture View
  • David Flanagan, JavaScript The Definitive Guide View
  • Erich Gamma et al., Design Patterns: Elements of Reusable Object-Oriented Software View
  • Julia Lerman, Programing Entity Framework View
  • Scott Millet et al., Pro Agile .NET Development with SCRUM View
  • James Bender, Jeff McWherter, Professional Test-Driven Development With C# View
  • Gary Hall, Pro WPF and Silverlight MVVM View
  • Roy Osherove, The Art of Unit Testing View
  • Peter Lubbers et al., Pro HTML5 Programming View
  • Grigoris Antoniou et al., A Semantic Web Primer View
  • Ian H. Witten et al., Data Mining: Practical Machine Learning Tools and Techniques View
  • Axel Schreiner, Object-Oriented Programming With ANSI C View
  • Paolo Pialorsi, Programming Microsoft LINQ in Microsoft .NET Framework 4 View
  • Stoecker Matthew, MCTS Self Paced Training Kit 70-511 View
  • Peter Norvig, Stuart Russell, Artificial Intelligence: A Modern Approach View
  • Andrew Troelsen, Pro C# with .NET 3.0 View
  • Microsoft Corporation, Improving .Net Application Performance and Scalability View
  • Andrew Tanenbaum, David Wetherall, Computer Networks View