HackerNews Readings
40,000 HackerNews book recommendations identified using NLP and deep learning

Scroll down for comments...

The Pragmatic Programmer: 20th Anniversary Edition, 2nd Edition: Your Journey to Mastery

David Thomas, Andrew Hunt, et al.

4.8 on Amazon

396 HN comments

Masters of Doom: How Two Guys Created an Empire and Transformed Pop Culture

David Kushner, Wil Wheaton, et al.

4.8 on Amazon

262 HN comments

Designing Data-Intensive Applications: The Big Ideas Behind Reliable, Scalable, and Maintainable Systems

Martin Kleppmann

4.8 on Amazon

241 HN comments

Clean Code: A Handbook of Agile Software Craftsmanship

Robert C. Martin

4.7 on Amazon

232 HN comments

Code: The Hidden Language of Computer Hardware and Software

Charles Petzold

4.6 on Amazon

186 HN comments

Cracking the Coding Interview: 189 Programming Questions and Solutions

Gayle Laakmann McDowell

4.7 on Amazon

180 HN comments

The Soul of A New Machine

Tracy Kidder

4.6 on Amazon

177 HN comments

Refactoring: Improving the Design of Existing Code (2nd Edition) (Addison-Wesley Signature Series (Fowler))

Martin Fowler

4.7 on Amazon

116 HN comments

Thinking in Systems: A Primer

Donella H. Meadows and Diana Wright

4.6 on Amazon

104 HN comments

Superintelligence: Paths, Dangers, Strategies

Nick Bostrom, Napoleon Ryan, et al.

4.4 on Amazon

90 HN comments

The Idea Factory: Bell Labs and the Great Age of American Innovation

Jon Gertner

4.6 on Amazon

85 HN comments

Effective Java

Joshua Bloch

4.8 on Amazon

84 HN comments

Domain-Driven Design: Tackling Complexity in the Heart of Software

Eric Evans

4.6 on Amazon

83 HN comments

Weapons of Math Destruction: How Big Data Increases Inequality and Threatens Democracy

Cathy O'Neil

4.5 on Amazon

75 HN comments

A Philosophy of Software Design

John Ousterhout

4.4 on Amazon

74 HN comments

Prev Page 1/16 Next
Sorted by relevance

noir_lordonJan 9, 2019

What a beautifully written article with informative links.

http://lucacardelli.name/Papers/TypefulProg.pdf is now next on my list when I finish reading A Philosophy of Software Design (which is brilliant if you haven't seen it).

afarrellonSep 6, 2019

> What is good design, what is good naming, over-engineering

A Philosophy of Software Design by John Osterhout is a good book on these questions.

vitornovictoronNov 9, 2018

A great talk on the topic - John Ousterhout: "A Philosophy of Software Design": https://youtu.be/bmSAYlu0NcY

tejinderssonAug 17, 2018

His book a philosophy of software design is an excellent read.

grammarnazzzionMay 25, 2021

TLDR: Author recommends "A Philosophy of Software Design" over "Clean Code"

dvirskyonDec 23, 2018

A Philosophy Of Software Design by John Ousterhout. Pretty short, but interesting and does a nice job at dissecting the mistakes we make that lead to software complexity.

https://www.goodreads.com/book/show/39996759-a-philosophy-of...

augustkonDec 22, 2020

John Ousterhout's "A Philosophy of Software Design" is an interesting alternative to Clean Code.

pbadenskionDec 8, 2020

"A Philosophy of Software Design" by John Ousterhout - a recent find and probably the best book on programme design I've ever read. Author is an experienced programmer and Computer Science professor at Stanford.

devnonymousonJuly 24, 2021

Interesting article. FWIW, although unrelated, this is by John Ousterhout, the author of "A philosophy of software design"

[1] https://hn.algolia.com/?q=a+philosophy+of+software+design

hodgesrmonSep 4, 2018

I use 'A Philosophy of Software Design' as my goto-list for reviewing pull requests. It has a great set of points that apply across a wide variety of applications.

auslegungonOct 1, 2018

I’ve been impressed with A Philosophy of Software Design. The Little Typer The Little Typer (The MIT Press) https://www.amazon.com/dp/0262536439/ref=cm_sw_r_cp_api_pXxS... looks promising

bobwaycottonDec 26, 2018

I’ve enjoyed the depth of thought found in—and triggered by—John Ousterhout’s A Philosophy of Software Design. It packs a lot into an easy-to-read, directly to-the-point format.

a_bonoboonFeb 3, 2020

You might enjoy Ousterhout's A Philosophy of Software Design - it discusses the many ways a programmer/system designer can fight rising complexity in the code base

signa11onApr 24, 2020

fwiw, i found John Ousterhout's "A Philosophy of Software Design" pretty good actually (despite having misgivings about it earlier)

afarrellonApr 13, 2020

A Philosophy of Software Design by John Osterhout: https://www.amazon.co.uk/dp/B07N1XLQ7D/ref=dp-kindle-redirec...

Concise, readable, and highly applicable.

afarrellonMay 30, 2020

A Philosophy of Software Design.

Very well-written. At 190 pages, quite likely finish-able in a weekend. But if you get 70% of the way through it, that is still very valuable. It makes sense as an underlying set of principles that explain why you would use design patterns.

noir_lordonJuly 29, 2019

The author of Tcl/Tk wrote a fantastic book recently called "A Philosophy of Software Design" and it's brilliant, hands down my favourite programming book of the last decade.

tmalyonSep 16, 2018

I would focus on communication skills. Knowing what the end user wants is really important.

For technical skills, I recommend reading Clean Code, Test Driven Development, and The Philosophy of Software Design.

brian_spieringonMay 29, 2019

John Ousterhout's "A Philosophy of Software Design" is a good book on the subject. He has worked with Google.

timClicksonJuly 5, 2019

One really excellent resource that I'm making my way through currently is "A Philosophy of Software Design" by Ousterhout. It's very practical and provides several strategies for reducing complexity and identifying practices that contribute to it.

girishsoonApr 16, 2021

Second A Philosophy of Software Design it's a very good book.

atmosxonFeb 7, 2019

Reading “A Philosophy of Software Design” now, which answers these questions. The author states that raised red flags apply to systems too.

So without context is hard to tell, but it’s a quick read, you might want to take a look and spot possible improvements without sacrificing quality.

tincholioonOct 23, 2020

I'm skeptical of any Uncle Bob-isms (and to some degree of Fowler's stuff) as well, but if you want a good description of technical debt and why it's actually a problem, Ousterhout does it nicely in his "A Philosophy of Software Design".

That book is a little gem, short and well-written

afarrellonJuly 16, 2020

The Wikipedia article on Working Memory followed by at least the first four chapters of A Philosophy of Software Design. This is really good for providing an underlying “why” for any other technique.

MeteorMarconNov 10, 2019

The book "A Philosophy of Software Design" should interest you then:
https://www.amazon.com/t/dp/1732102201
It argues, among other things, that deep interfaces matter more than code complexity inside a module.

yumaikasonOct 3, 2018

If you can, find a copy of "A Philosophy of Software Design", and read the whole thing.

It'll give you a lot of higher level things to think about as you're diving deep into your first tech stack.

afarrellonMay 9, 2020

If y'all haven't read John Osterhout's book A Philosophy of Software Design, I highly recommend it.

It is concise and presents a clear view of what makes code easier to work with. I've found its concepts useful when trying to think of what to say during code reviews.

augustkonMar 25, 2020

"The most experienced programmer uses hacks all the time; the important part is that you're getting stuff done."

I couldn't disagree more, the grown up programmers use a strategic approach, not a tactical one. As Jonh Ousterhout put it in his book A Philosophy of Software Design "The first step towards becoming a good software designer is to realize that working code isn't enough."

auslegungonDec 2, 2018

1. The Problem of Pain by CS Lewis
2. A Philosophy of Software Design https://www.amazon.com/dp/1732102201/ref=cm_sw_r_cp_api_i_EK...
3. Haskell from First Principles http://haskellbook.com
4. Les Miserables
5. Continuous Delivery https://continuousdelivery.com

abhghonOct 28, 2019

This was my reason for foraying into Tcl too. Till then I had used Java's AWT and Swing; but prototyping with Tcl/Tk was way faster and intuitive. Mid-2000s. I ended up liking the language - idiosyncratic as it was. Partly the reason I am curious about and planning to read Ousterhout's (creator of Tcl) book "A Philosophy of software Design" soon.

noir_lordonAug 9, 2020

Constantly.

I don't mind high level videos to give a 10,000ft view but for everything else the written word wins every time.

Currently re-reading A Philosophy of Software Design and just started "Grokking Algorithms" alongside the 2-3 fictional books I have on the go at any given time.

dmuxonJan 25, 2020

>Basically use the least level of abstraction that can reasonably get the job done.

There is a great section of John Ousterhout's "A Philosophy of Software Design" that goes into this. He mentions that moving code to functions / methods doesn't eliminate complexity, it nuat kind of shifts it: it adds complexity to the "interface" of the module.

Sometimes leaving code inline with its original context is better.

lboassoonAug 30, 2018

Another excellent resource is "A Philosophy of Software Design" [0], from John Ousterhout (known for Tcl/Tk, Raft, RAMCloud, Log-Structured File System). Like Niklaus Wirth, he is striving for designs that fight complexities and yield simple and powerful abstractions. This book is so much better than overrated books like "Code Complete" and "Clean Code" for a fraction of the page count.

[0] https://www.amazon.com/Philosophy-Software-Design-John-Ouste...

discreteeventonNov 13, 2020

There is a similar concept in "A Philosophy of Software Design" by John Ousterhout. Large/deep modules with simple interfaces lead to less complexity than small modules with complex interfaces. It's a bit radical because it conflicts with the obsession we have for low level re-use and composability.

noir_lordonJune 26, 2021

I always consider if a bug is a result of the wrong level of abstraction first before fixing it.

In "A Philosophy of Software Design" Ousterhout talks about the difference between tactical and strategic programming (great book mostly because it codifies a lot of what I think is the "One True Way" so I'm biased) and it's really easy to bang out a fix for variant 98 of the bug vs rethinking it so variants 0 through 97 which haven't been reported yet but exist can't happen.

hodgesrmonJune 13, 2018

He also has a new book "A Philosophy of Software Design" that is short and worth reading. (I'm currently on chapter 7.)

timclarkonSep 5, 2020

A philosophy of software design - John Ousterhout

This has an interesting generic discussion of API design which is technology agnostic.

noir_lordonFeb 22, 2019

"A Philosophy of Software Design" by Ousterhout is my favourite of the last few years.

It's a shortish book but there is stuff in it I'm still unpacking on the third read through and a lot of stuff I sorta instinctively knew but it's nice to see someone else thinks the same.

gregfjohnsononMay 12, 2021

Excellent observations. The essay illustrates what it is advocating by the generous clarity, simplicity, and accessibility with which it is written.

John Osterhout wrote what may be the best elaboration of this perspective in his wonderful book "A Philosophy of Software Design."

A couple of related thoughts from an old grizzled programmer (moi ;-), gregfjohnson.com):

Rule number one: All code must follow the Porthole Principle. The fundamental issue in programming is that we each look out at the world through a mental "porthole" that limits our field of view. We are limited in how much we can see and understand at any one time. Therefore, systems must be structured so that they can be understood completely, at all levels, even though we are only allowed to investigate them piecemeal, through our own limited and finite cognitive windows.

Abstraction is the essential tool that allows us to create systems of arbitrary size and complexity. A beautifully designed abstraction is easy to understand and use. It is so trustworthy that you don't feel any need to worry about how it is implemented. Finally, and most importantly, it enables you to reason with rigor and precision about the correctness of the code you are writing that makes use of it.

lstamouronMay 12, 2021

(2020), but timeless.

If you like this post, you might also like reading the relatively short book, A Philosophy of Software Design by John Ousterhout, or the talk you'll find on YouTube by the same name, which covers roughly half the topics in the book.

hikarudoonJuly 6, 2020

On the topic of the "theory" (mental model) of a program, I recommend John Ousterhout's book "A Philosophy of Software Design". You get such gems as:

"... the greatest limitation in writing software is our ability to understand the systems we are creating."

"Complexity manifests itself in three general ways... change amplification, cognitive load, and unknown unknowns."

"Complexity is caused by two things: dependencies and obscurity."

"Obscurity occurs when important information is not obvious."

"The goal of modular design is to minimize the dependencies between modules."

tmalyonDec 12, 2018

Never Split the Difference - I loved this book and would highly recommend it to sharpen your negotiation skills.

Extreme Ownership - I also really enjoyed this book. I listened to the audio and it was read by the authors. Both Navy Seals, the stories they used about their time in war was very eye opening. The concepts are all about leadership, and if you a manager or part of a team, you will get some benefit.

Getting Things Done - 2001 edition, very practical approach to organizing everything on your plate. I will probably re-read this again.

Learning How to Learn: How to Succeed in School Without Spending All Your Time Studying; A Guide for Kids and Teens - a great book that has great tips on learning for kids and adults.

A Philosophy of Software Design - still reading it, I really am enjoying it so far. I like the big picture approach it takes to discussing software design and complexity.

Mindset - I just started this book. So far it is just explaining the general concept in different ways. I am hoping the latter part will get into some practical tips and methods.

blubonAug 25, 2019

I read parts of the refactoring book (1st edition) when it came out to see what kind of refactorings the author mentions. Since I didn't remember much from it, I decided this year to take a look at the 2nd edition, which to my amusement is written in JavaScript. After reading the example refactoring at the beginning I abandoned the book, because it champions the "code as prose" idea, which is rightfully contradicted by Ousterhout in his "A Philosophy of Software Design".

"Enterprise architecture" was not relevant for me, I wasn't doing any EA when I started reading it and quickly lost interest. The only potentially engaging topic was concurrency, but there are much better books available about that topic.

"Pattern-Oriented Software Architecture" (I am only familiar with vol 1 & 2) has wider applicability and is more compelling in my opinion. And they have references and examples. For instance the Pipes & Filters architecture patterns gives UNIX [Bac86], CMS Pipelines [HRV95] and LASSPTools [Set95] as examples and references "The Pipeline Design Pattern" [VBT95].

I do see case studies and references, but not from these authors I mentioned.

lstamouronSep 21, 2019

If you like this, you’ll probably also like https://seilevel.com/business-analyst-resources/rml-book/ and various videos and webinars from Seilevel on YouTube which I added to a playlist (not in any particular order so please scroll through it): https://www.youtube.com/playlist?list=PL2miG2CzrxakbZswQH-O4...

Also relevant, the Design Structure Matrix (DSM): https://dsmweb.org/ and https://mitpress.mit.edu/books/design-structure-matrix-metho... (mostly learning by example, not all software-relevant, available as an e-Textbook on Amazon) If you code in Java, IntelliJ has this diagram included.

Finally if you’re looking on advice on how to break software into modules based on making your API surfaces easier to use for yourself and other programmers, have a look at A Philosophy of Software Design. It’s not comprehensive, but it’s concise and relatively easy to read: https://books.google.ca/books/about/A_Philosophy_of_Software...

tmalyonMar 21, 2019

Getting Things Done (2001) by David Allen - great method to organize all your tasks and stay on top of things

Clean Coder by Bob Martin - good ideas on being a professional programmer

A Philosophy of Software Design by John Ousterhout - big picture ideas on design

Test Driven Development by Kent Beck - good basis for thinking about design and testing

Legacy Code by Michael Feathers - understanding the issues of legacy code helps us to design better software

layer8onDec 8, 2020

> It's not that these books are bad, or out of date. It's more that they exposed some new ideas at the time that, to the books credit, have been picked up and made mainstream or basic/required knowledge for the working programmer

What books do you recommend though to get novice (or not so novice) programmers up to speed? IMO there is a lack of modern literature and general introductory material to the kind of wisdom you otherwise only get after decade(s) of software development (if at all, for quite a number of people).

A recent one I liked is “A Philosophy of Software Design”, but it only covers so much ground, and some of its advice requires further qualification.

JtsummersonMay 25, 2021

The Pragmatic Programmer, Refactoring (I'm rereading it after many years with the 2018 edition, opinion not totally formed on this one), Working Effectively With Legacy Code, A Philosophy of Software Design. It's been a long time since I've read Clean Code, I don't quite get the hate from the other thread here today so I'm rereading it now. I figure it'll take me a couple days and worst case I'll agree with the criticism and stop recommending it.

dgb23onAug 9, 2021

In A Philosophy of Software Design the author talks at length about this and proposes that "deeper" modules (classes/methods/functions etc.) provide the most cost/benefit ratio, where the interface of a module is the cost and the functionality is the benefit.

Code doesn't magically become less complex by hacking it into pieces.

philosopher1234onMar 13, 2020

Each method has its own innate complexity, the complexity of "whats this method do? when do I use it? Why would I use this method instead of a different method in this class? Now I have to dive into this method to read its implementation which pulls me out of the reading context I was in before"

Also, your point about the meaning beyond the code can be served by a comment, which drops the constraint of "don't make it too long" and "write in camel case", and also allows inline code reading!

There's a time and a place for everything. I reccomend "A Philosophy of Software Design" for a book that elaborates on the idea of "less and longer methods tend to be better than many concise methods".

What you want to make short/simple is the API, rather than the implementation!

blubonAug 24, 2019

Yes, "A Philosophy of Software Design" is brilliant, precisely because the author supports their statements through the many experiments they performed with students and

The fact that they're the author of a well-known piece of software helps, although we should not use this as the main criteria to evaluate a text.

Offering at least evidence based on experimentation is essential if we want to move past personality cults and having entire teams work based on what someone wrote on a blog somewhere.

throwaway16011onSep 26, 2020

> These should give you, in my humble opinion, some fresh motivation and abstract overview on software development in general.

Thanks for the kind words!

> From your post it is a bit unclear what you mean by feeling under-experienced compared to your peers. Is it at technical level? Work ethic/principles? Understanding of the whole technology stack? Or perhaps process in your company?

I feel the greatest trepidation around devops. Particularly in recent years I have noticed I am struggling to grasp the fundamental concepts of common tools. Kubernetes is a convenient example. Beyond k8s itself, I feel as if I'm drowning in the ecosystem which has grown around it.

At some point my mind seems to all lost all plasticity.

> These should give you, in my humble opinion, some fresh motivation and abstract overview on software development in general.

Absolutely! Both books gave me great encouragement very early in my career, I should read them again. Indeed, I will hopefully have a greater appreciation and better understanding of the topics covered now that I have more experience.

I stopped reading books on software around the time I started feeling inadequate in my position. They became more of a source of anxiety than inspiration. That must sound perverse!

I recently started reading "A Philosophy of Software Design" (978-1732102200). It has been a refreshing experience and I am hoping eases my back into such literature.

notoriousarunonFeb 18, 2021

Read extensively, practice your craft & don't lose your focus.

These books will help you day-to-day with your general programming knowledge...

> Philosophy of Software Design https://www.amazon.com/Philosophy-Software-Design-John-Ouste...

> The Pragmatic Programmer https://www.amazon.com/Pragmatic-Programmer-Journeyman-Maste...

> Clean Code https://www.amazon.com/Clean-Code-Handbook-Software-Craftsma...

> Mythical Man-Month https://www.amazon.com/Mythical-Man-Month-Anniversary-Softwa...

jasimonOct 30, 2018

I'm enjoying Ousterhaut's "A Philosophy of Software Design", but it is striking how much it is shaped and limited by the languages that are implicitly considered (mostly, imperative OO languages).

One oddity is the view of the class as the only real scope at which one can build abstractions. The idea that one can use little abstractions to build big abstractions, without cluttering the final abstraction to be presented to the user, is nowhere in sight.

Most shockingly to me, I've found no reference to types as a design tool. Sure, precise names help you avoid confusing physical block ids and logical ones. But wouldn't a type-based distinction be way better?

- https://twitter.com/yminsky/status/1005066579929911296

JtsummersonApr 16, 2021

The Psychology of Computer Programming by Gerald Weinberg. Some dated language (which he calls out himself in the 25th anniversary edition), but overall very good.

A Philosophy of Software Design by John Ousterhout, short book, quick read. I'll be rereading it once I figure out which bookshelf my wife hid it on (she doesn't like my bookstack approach to "organizing" and moved many things to shelves while I wasn't paying attention).

bwh2onApr 16, 2021

I was underwhelmed by A Philosophy of Software Design. The first 100 pages are solid, but the last 70 didn't resonate with me at all.

In those last 70 pages, the author advocates strongly for lengthy comments which felt excessive and often unnecessary to me. Here's an example from page 124:

  // Controls cursor blinking: true means the cursor is visible,
// false means the cursor is not displayed.
private boolean cursorVisible = true;

AlexCoventryonSep 9, 2018

> the judgment / taste required to make maintainable changes to a million LOC repository

Try The Art of Readable Code (a pair of google authors, IIRC), and Ousterhout's A Philosophy of Software Design.

sureshjayaramanonMar 22, 2019

Does "A Philosophy of Software Design" need some experience to appreciate what the author is talking about?

pvarangotonDec 16, 2018

This is not as unpopular as what reading about productivity and process from blogs or books by people who sell canned methodologies will make you think. Thinking retrospectively I think more than half of the projects I've worked in practiced agile in a way more akin to your views than to what you are complaining about "everyone does".

It's also not too different to what old books like Fowler's refactoring or the Working With Legacy Code book say, or what modern books like Philosophy of Software Design say.

afarrellonJuly 9, 2019

You would probably like the book A Philosophy of Software Design by Dr. John Osterhout.

fdsvnsmvasonSep 10, 2018

Thanks everyone, the comments are much appreciated. Here's a list of books and other media resources recommended so far in the thread:

Robert C. Martin, Clean code: https://www.amazon.com/Clean-Code-Handbook-Software-Craftsma...

Vaughn Vernon, various: https://vaughnvernon.co/?page_id=168

Steve McConnell, Code Complete: https://www.amazon.com/Code-Complete-Practical-Handbook-Cons... 2

Clean coder: https://cleancoders.com/ videos

Hunt and Thomas, The Pragmatic Programmer: https://www.amazon.com/Pragmatic-Programmer-Journeyman-Maste...

Hitchhiker's Guide to Python: https://docs.python-guide.org/

Dustin Boswell The Art of Readable Code: https://www.amazon.com/Art-Readable-Code-Practical-Technique...

John Ousterhout, A Philosophy of Software Design: https://www.amazon.com/Philosophy-Software-Design-John-Ouste... This one looks particularly interesting, thanks AlexCoventry!

Kent Beck, Test Driven Development: https://www.amazon.com/Test-Driven-Development-Kent-Beck/dp/...

Dan Bader, Python Tricks: The Book: https://dbader.org/

Ian Sommerville, Software Engineering: https://www.amazon.com/Software-Engineering-10th-Ian-Sommerv...

Svilen Dobrev, various: http://www.svilendobrev.com/rabota/

dgb23onJuly 19, 2021

Not specifically software design, but insofar related books that take the perspective of programmers with unique insights:

- Coders at Work (Seibel)

- Working in Public (Eghbal)

The first one is very entertaining. Read it a couple years ago and found it gives some valuable perspective. The second one is on my reading list, it was recommended around these boards.

Related to software design, there are many. The two that are on my recent list are:

- Software Design for Flexibility (Sussman, Hanson)

- A Philosophy of Software Design (Ousterhout)

I can't comment personally on their content yet, still have to work through those two, but I have zero doubts to learn something valuable. Certainly consider them.

devchris10onJuly 22, 2020

A Philosophy of Software Design - John Ousterhout

cliffcroslandonAug 24, 2019

Reading an enumeration of architecture options can be helpful, but I've probably found more value in works like Ousterhout's "A Philosophy of Software Design" that cover fundamental design principles. Such principles seem to be applicable no matter the project.

I appreciate that Ousterhout tries to support these principles with some data from his own experience (building Tcl, RamCloud where Raft consensus was discovered, etc) and from code reviews of student projects in his design course, but he admits that there is a lack of data about things like design.

Sample principles from Ousterhout:

* When developing an interface, favor exposing a small number of functions each with deep functionality over exposing a large number of functions each with shallow functionality. For example, favor Unix file I/O interface (open, close, read, write, unlink) over Java file I/O interface (File, FileReader, BufferedReader, FileWriter, BufferedWriter, FileNotFoundException, ... etc.)

* When choosing between keeping your code specific and keeping your code general, favor "somewhat" general. For example, instead of exposing "deleteNextCharacter(text, pos), deleteNextWord(text, pos), deleteNextSentence(text, pos)", just expose "delete(text, pos, length)" and let the caller use it how they will.

svatonJan 27, 2019

Relevant recent discussion:

https://news.ycombinator.com/item?id=18959636 (John Carmack on Inlined Code (2014))

• This comment, which contains a useful example: https://news.ycombinator.com/item?id=18832382

Please let me know of any further discussion on the topic. (I'm also reminded of Ousterhout's advice in A Philosophy of Software Design that “classes should be ‘thick’” — see talk https://www.youtube.com/watch?v=bmSAYlu0NcY or (unrelated) slides: https://platformlab.stanford.edu/Seminar%20Talks/retreat-201... )

One thing I see people miss in this discussion is that there's a tradeoff between having an individual function be understandable (shorter functions are easier to understand) having the entire codebase or interrelationships between functions be easier to understand (fewer functions are easier to understand). When there's an example presented like in the post, it's often presented as an example with a single function, and of course four short functions may each be easier to understand than a single function, but you've also added three nodes to the “graph” (of functions and calls between them) and now you need to study whether these functions are called from anywhere. To make up for this one may start introducing classes/objects to indicate “private”/“public” functions, and so on. (Some languages allow nested functions, which can help.)

Most of all I'd say reading very different styles of code, and seeing how people achieve great things in unusual ways (e.g. with lots of abstraction, or with very little abstraction), can be an illuminating experience (see my comment in this thread about reading Knuth's programs).

hodgesrmonAug 15, 2018

The company where I work has senior engineering staff whose main responsibility is to provide technical guidance. This includes doing code reviews and creating a good review culture by example. We're judged by the overall project outcome in the same way that the managers are.

Even with that structure I found it challenging to develop a good reviewing style that picked up the important stuff without getting bogged down in silly details that lead to arguments. Reading John Ousterhout's "A Philosophy of Software Design" was really helpful. He focuses on module decomposition, quality of public interfaces, and documentation among other things.

achouonJune 21, 2019

I think the best single observation about cognitive load is in Ousterhout's book A Philosophy of Software Design[1]. In the book he promotes the idea that classes should be "deep", such that their top-level surface API is small relative to the complexity they hide underneath.

This applies to the microservice/monolith debate as well. And it basically boils down to the observation that having lots of shallow services doesn't really reduce complexity. Each service may be simple unto itself, but the proliferation of many such services creates complexity at the next level of abstraction. Having well designed services with a simple API, but hide large amounts of complexity beneath, really reduces cognitive load for the system as a whole. And by "simple API" I think it's important to realize that this includes capturing as much of the complexity of error handling and exceptional cases as much as possible, so the user of the services has less to worry about when calling it.

[1]: https://www.amazon.com/Philosophy-Software-Design-John-Ouste...

afarrellonApr 6, 2020

I think the responses of "Well, it doesn't astonish me" and "principle least my surprise" point to something deep about how to write code for other humans:

As a field, we would benefit greatly from learning more cognitive science.

A core suggestion of John Osterhout's book A Philosophy of Software Design is to have well-named modules with 'thin' interfaces which accomplish a reasonably-deep set of responsibilities. But...why?

Working Memory -- Humans have limited Working Memory.

If you give a function:

- A clear name.

- Few simple parameters.

- No side-effects not in the name.

- No GOTOs or exceptions.

then a human can glance at it, put the name and parameters into working memory, and carry on.

But if you split up a namable responsibility across multiple files, then a human reading the codebase to understand data flow would need many more open editor windows or to hold much more info in working memory.

elliusonFeb 22, 2020

As an addendum to this, I would frame the problem as "complexity," one aspect or symptom of which is requirements volatility.

Complexity comes from two sources in software projects. The first is the domain. As other commenters have pointed out, domain experts are usually half-aware of their domain requirements because much of the complexity has been buried under their expertise and intuition. Domain requirements also inherently change over time as markets, professional standards, and technology evolve. So the process of development involves a shifting discovery of new aspects of the domain as things which were unconscious become consciously learned.

The other aspect of complexity is the technology applied to the problem. Computer technology is inherently complex, and the imperfect mapping between domain problems and technology adds a third angle.

The best books I've seen for dealing with these problems are "Clean Architecture," "A Philosophy of Software Design," and "Principles of Product Development Flow." The first two explain how to build good systems that encapsulate complexity and are geared towards changeability. Such systems are flexible as new aspects of domain complexity are discovered over time. The latter book takes a higher level view of how to design projects to cope with the discovery process in a way that is economically viable and justifiable to the people financing projects, and also in a way that arranges work so that developers can actually be productive and not become swamped by the complexity problem or bad processes and practices.

layer8onDec 18, 2020

A better formulation of DRY is SPOT — Single Point Of Truth. In the event that the logic is changed in one copy, should the other copy always be updated accordingly? If the answer is yes, combine them into a single copy, so that they don’t diverge and create ambiguous “sources of truth” in the future. Conversely, if it is likely that the logic in the two copies will need to diverge in the future, due to having a different context, then do not combine them, because they represent different “truths” that just currently happen to have the same form.

Of course, the answer to that question can change over time, and one has to combine or duplicate accordingly. This also serves to document the intent that “yes, these two occurrences are expected to evolve identically”, or “no, these two occurrences are expected to evolve independently, even though they currently happen to look the same”.

The article is correct though that there is a trade-off in terms of the complexity created by the abstraction, and in how important the “common truth” is. Sometimes a source comment pointing out the dependency is better than introducing a nontrivial abstraction.

The book “A Philosophy of Software Design” argues that there are two sources of complexity in software: dependencies and obscurity. Combining two similar pieces of logic into one can reduce dependencies (of one having to be changed when the other is changed), but can increase obscurity due to the added abstraction. If the combining was done for the wrong reasons (the two occurrences actually need to evolve independently), then the dependencies are increased instead of reduced.

bertmuthalalyonMay 1, 2020

I think the conversation has shifted slightly this decade to avoiding incidental (accidental) complexity (I didn’t realize Fred Brooks popularized the term!), which I wish the author would address.

Otherwise this essay is spot on when it comes to essential conplexity.

Incidentally, the question of “where complexity lives” is one of the focal points of “A Philosophy of Software Design,” which comes highly recommended if you’re trying to come up with your strategy for managing complexity from first principles.

bchonJuly 29, 2019

Tcl/Tk is listed below by others, but it’s worth noting that both Richard Hipp (SQLite) and Antirez (redis) are (or were) very deeply involved with Tcl. I think there maybe a positive feedback loop/environment wrt engineering discipline. It’s worth exploring. I also second the praise below of John Ousterhout’s (inventor of Tcl/Tk) book “A Philosophy of Software Design”.

TeMPOraLonDec 28, 2018

I agree.

In Philosophy of Software Design, J. Ousterhout says that this TDD practice encourages "tactical programming", i.e. trying to solve the current open ticket with minimum amount of work, instead of solving the problem correctly. Personally I'd go further. To me, this approach encourages replacing your brain with a dumb gradient descent process. Instead of thinking about the problem and solution, you just keep writing an ever larger monster whose sole purpose is to interpolate between test cases.

Tests themselves are useful. Following a process that makes meaning implicit instead of explicit? Not so much.

praptakonApr 12, 2021

"A Philosophy of Software Design" by John Ousterhout talks about the costs of introducing abstractions, with the implication that modules should be "narrow and deep".

The width is defined as the size of the interface (the cost) and the depth as the functionality that it buys you or maybe the complexity it hides (I'm recalling from memory, don't have the book at hand).

A file system that exposes the file interface (as in Unix) is given as a positive example. It has few functions and buys you, well, everything a file system offers.

shidoshionAug 31, 2018

pp. 76-77 of Ousterhout's "A Philosophy of Software Design" talk about the issues with boilerplate try-catch. He basically does not approve, as they make readability suffer and often do not do what they advertise (truly catch errors.) I don't know how he would feel about production assertions, but I'm guessing he would buy into it if it helps reduce complexity. In the sense of finding remedies to troublesome bugs--which will occur.
Built withby tracyhenry

.

Follow me on