A Philosophy of Software Design
================================================================================
                           by John Ousterhout
--------------------------------------------------------------------------------

Started: December 2023
Completed: January 2024

When my former employer announced that  we would start using SAFE agile,
I was concerned. I didn't know what "SAFE" was, but I had been burned by
my prior exposure to agile at  the company. This meant an obsession with
Jira tickets  and a daily standup  meeting where you tell  a manager why
your homework isn't done. I hated  watching my colleagues squirm and the
whole thing felt childish. I had  also been newly promoted to supervisor
(i.e. leading a team of engineers) and I wanted to keep an open mind.

I decided to create a reading group to learn more about agile. The group
was a  voluntary mix of engineers  and supervisors and we  met every two
weeks. I bought a few books off  Amazon and selected the one that seemed
the  most promising  based on  the introductions.  We read  "The Art  of
Agile" by James Shore. I ended  up hating SAFE, but being very intrigued
by Agile. When  the official training arrived, my team  were prepared to
fight  off the  consultancy  drones that  tried to  teach  us Agile  via
PowerPoint. Beyond  the immediate  purpose of  learning agile,  the book
club was a success and other books were suggested as follow-ups. We read
Robert Martin's "Clean Code" the next year. I enjoyed reading a book and
considering somebody  else's opinions on software  design. Possibly more
enjoyable were  the discussions with  my colleagues.  A lot of  the time
work discussion is very narrowly focused on the problem at hand. I liked
learning how other  engineers responded to the same text.  What did they
like? What were they skeptical about?

John Osterhout's  "A Philosopy of  Software Design"  was on the  list of
books to  read, but  we did  not get to  it before  I left  the company.
Instead, I read it last month on my own.

The book is a good complement to Clean Code, since a lot of the author's
opinions contradict the sort of things  that you hear in clean code. For
example, Clean  Code wants  a function  to read a  bit like  an outline.
Inside  the body,  a few  well-named function  calls give  a high  level
description of what is being done. To  see more detail, enter one of the
functions and find another list of  well-named function calls at a lower
level. Keep  probing and you'll eventually  find a small, easy  to read,
encapsulated piece of  logic. Each function is relatively  small and all
of the function calls operate at  the same level of abstraction. This is
an appealing idea, when function grows  in length beyond a screenful and
can  be  difficult to  follow  what's  going on.  Additionally,  massive
nesting (e.g. an if statement inside a loop inside another if statement)
can be  hard to comprehend.  That said,  jumping from small  function to
small function has its own cognitive burden. Many of the small functions
turn out to  be "well-named" wrappers of other  functions, hardly adding
anything  to the  mix.  Getting from  one  piece of  logic  to the  next
involved following the thread of function calls 10 layers back up to the
parent caller  and then  10 layers  back down  to find  the next  bit of
logic.

Ousterhout is skeptical  of functions that wrap  other functions without
any value  add. I think he  would urge the  reader to consider if  it is
more straightforward to simply include  the logic directly in the parent
caller with  an appropriate  explanatory comment  giving the  high level
gist. I'm  happy to  see this  alternative viewpoint  as the  Clean Code
approach can be taken to an extreme.

Compared to Clean  Code, APSD is much more openly  in favor of comments.
The book  was not written in  a vacuum and  often cites Clean Code  as a
source of alternate  opinions. When digging into the examples  of how to
comment, I got  the feeling that the  two authors are not  so far apart.
Where Ousterhout is most compelling  on comments are his descriptions of
how  to  document a  function.  The  documentation should  describe  the
inputs, outputs and  error behaviors, while avoiding  description of the
implementation details.  Users should be  able to understand how  to use
the function  without digging into  the implementation. I don't  get the
sense that Robert Martin would disagree.

A major  focus of the  book is Ousterhout's  concept of narrow  and deep
interface. According to his idea,  interfaces should do the most (depth)
given the fewest  inputs (narrowness). This is a concept  that's hard to
argue with. I'm  not sure how groundbreaking it is,  but narrow and deep
give a  nice visual.  Just as  we want  to encapsulate  member variables
inside  the private  portion  of a  class, we  want  to encapsulate  our
algorithms inside of function bodies. To the greatest extent possible we
want functions to expose what they do, but not how they do it.

While the book does provide examples the advice is generally at a higher
level. Usually  the advice comes  with a caveat  that it should  only be
followed within  reason. This  is where I  found the book  to be  at its
weakest. All good advice is only good so long as it isn't taken too far.
There were times  where I would agree  with a point that  the author was
making, but could also think of cases where I thought the advice was not
applicable. Was that because it was  an example of taking the advice too
far or  was I  not open-minded enough.  This is, of  course, the  art of
software development. When  do we follow the rules and  when do we break
the rules.  As a follow-up  to Clean Code,  this book helps  us consider
some different perspectives, but I don't think it stands on its own.