Structure and Interpretation of Computer Programmers

I make it easier and faster for you to write high-quality software.

Thursday, October 31, 2019

Sprouts

Having discussed reasons for change with a colleague on my team, we came up with the sprouts of change. Good software is antifragile in the face of changing:

  • Situation
  • People
  • Requirements
  • Organisation
  • Understanding
  • Technology
  • Society

Like any good acronym, it’s really tenuous.

posted by Graham at 14:28  

Wednesday, October 30, 2019

Change

I was just discussing software architecture and next steps with a team building a tool to help analyse MRI images of brains. Most of the questions we asked explored ways to proceed by focussing on change:

  • what if the budget for that commercial component shows up? How would that change the system?
  • what if you find this data source isn’t good enough? How would you find that out?
  • which of these capabilities does the customer find most important? When will they change their minds?

that sort of thing.

We have all sorts of words for planning for, and mitigating the risk of, changes in low-level software design. In fact a book on building maintainable software talks about nothing else, because maintainable software is antifragile software.

But it happened that I wasn’t reading that book at the time, I was reading about high-level design and software architecture. The guide I was reading talked a lot about capturing the requirements and constraints in your software architecture, and this is all important stuff. If someone’s paying for your thing, you need to ensure it can do the things they’re paying for it to do. After all, they’re probably paying to be able to do the things that your software lets them do; they aren’t paying to have some software. Software isn’t real.

However, most of the reason your development will slow down once you’ve got that first version out of the door is that the world (which might be real) changes in ways that it’s hard to adapt your software to. Most of the reason you’re not adding new features is that you’re fixing bugs, i.e. changing the behaviour of the software from one that matches the flawed conception you had of what it should do to one that matches the flawed conception you now have of what it should do.

A good architecture should identify, localise, and separate sources of change in the software system. And then it should probably do whatever you think the customers think they want.

posted by Graham at 14:15  

Monday, October 28, 2019

The value of the things on the left

With the rise of critical writing like Bertand Meyer’s Agile! The Good, the Hype, and the Ugly, Daniel Mezick’s Agile-Industrial Complex, and my own Fragile Manifesto, it’s easy to conclude the this Agile thing is getting tired. We’re comfortable enough now with the values and principles of the manifesto that, even if software has exited the perennial crisis, we still have problems, we’re willing to criticise our elders and betters rather than our own practices.

It’s perhaps hard to see from this distance, but the manifesto for Agile Software Development was revolutionary when it was published. Not, perhaps, among the people who had been “doing it and helping others to do it”.

Nor, indeed, would it have been seen as revolutionary to the people who were supposed to read it at the time. Of course we value working software over comprehensive documentation. Our three-stage signoff process for the functional specification before you even start writing any software is because we want working software. We need to control the software process so that non-working software doesn’t get made. Yes, of course working software is the primary measure of progress. The fact that we don’t know whether we have any working software until two thirds of the project duration is passed is just how good management works.

At one point, quite a few years after the manifesto was published and before everybody used the A-word to mean “the thing we do”, I worked at a company with a very Roycean waterfall process. The senior engineering management came from a hardware engineering background, where that approach to project management was popular and successful (and maybe helpful, but I’m not a hardware engineer). To those managers, Agile was an invitation for the inmates to take over the asylum.

Developers are notoriously fickle and hard to manage, and you want them to create their own self-organising team? Sounds like anarchy! We understand that you want to release a working increment every two to four weeks with a preference toward the shorter duration, but doesn’t that mean senior managers will spend their entire lives reviewing and signing off on functional specifications and test plans?

The managers who were open to new ideas were considering the Rational Unified Process, which by that time could be defined as Agile for the “nobody ever got fired for buying an IBM” crowd:

The Rational Unified Process. Image: wikimedia

That software engineering department now has different management and is Agile. They have releases at least every month (they already released daily, though those releases were of minimal scope). They respond to change rather than follow a plan (they already did this, though through hefty “change control” procedures). They meet daily to discuss progress (they already did this).

But, importantly, they do the things they do because it helps them release software, not because it helps them hit project milestones. The revolution really did land there.

posted by Graham at 14:08  

Thursday, October 24, 2019

Zen and the Art of Software Maintenance

In one part of the book Zen and the Art of Motorcycle Maintenance, which is neither about Zen nor motorcycle maintenance, there are two motorcycles and two riders. John Sutherland is a romanticist who appreciates the external qualities of his motorcycle: its aesthetics, and its use as a vehicle. The narrator is a classicist who appreciates the internal qualities of his motorcycle: its workings, parts, and mechanisms. When Sutherland has a problem with his bike he takes it to a mechanic. When the narrator does, he rationalises about the problem and attempts to discover a solution.

The book, which as its subtitle gives away is “an inquiry into values”, then follows the narrator’s exploration of a third way of considering quality that marries the romantic and classical notions holistically.

Now we come onto software. Software doesn’t exist. At some level, its abstractions and mathematics get translated into a sequence of states of an electronic machine that turns logic into procedure: but even that is a description that’s a few degrees abstracted from what software and computers really do.

Nonetheless, software has external and internal qualities. It has aesthetics and utility, and can be assessed romantically. A decidedly pedestrian word to describe the romanticist view of software is “requirements”, but it’s a common word in software engineering that means the right thing.

Software also has workings, parts, and mechanics. Words from software engineering to describe the classical view of software include architecture, design, clean code, SOLID…

…there are many more of these words! Unsurprisingly, the people who build software and who change software tend to take a classical view of the software, and have a lot more words to describe its internal qualities than its external qualities.

Typically, the people who are paying for software are interested in the romantic view. They want it to work to achieve some goal, and want someone else (us!) to care about what makes it work. Perhaps that’s why so many software teams phrase their requirements as “As a romantic, I want to task so that I can goal.”

Which is to say that making software professionally involves subordinating classical interpretations of quality to romantic interpretations. Which is not to say that a purely-classical viewpoint is unvaluable. It’s just a different thing from teaching a computer somersaults for a paying audience.

And maybe that subordination of our classical view to the customer/gold owner’s romantic view is the source of the principles:

Our highest priority is to satisfy the customer through early and continuous delivery of valuable software.

and:

Working software is the primary measure of progress.

In fact, this second one is not quite true. It suggests that you could somehow “count software”, and the more (working) software you’ve delivered, the better you’re doing. In fact, romanticism shows us that people only want software in that it enables some process or business opportunity, or makes it more efficient, or reduces errors, or lets them enjoy some downtime, or helps them achieve some other goal. So really progress toward that goal is the primary measure of progress, and working software is a leading metric that we hope tells us how we’re working toward that goal.

So all of those code quality and software architecture things are in support of the external view of the software, which is itself in support of some other, probably non-software-related, goal. And that’s why the cleanliness, or architectural niceness, or whatever classical quality, of the code is not absolute, but depends on how those qualities support the romantic qualities of the code.

Real life comes at you fast, though. When you’re working on version 1, you want to do as little work, as quickly as possible, to get to the point where you can validate that there are enough customers who derive enough value to make the product worthwhile. But by the time you come to work on version 1.0.1, you wish you’d taken the time to make version 1 maintainable and easy to change. Most subsequent versions are a little from column A and a little from column B, as you try new things and iterate on the things that worked.

As fast as possible, but no faster, I guess.

posted by Graham at 23:51  

Wednesday, October 16, 2019

A question of focus

The problem with The Labrary is that I offer to do so many things – because I could do them, and do them well – that it can be hard to find the one thing I could do for you that would be most helpful:

  • Artificial Intelligence
  • Agile Development
  • Continuous Delivery
  • Software Architecture
  • Technical Writing
  • Developer Experience
  • Programmer Mentoring

Each of these supports the mission of “making it faster and easier to make high-quality software that respects privacy and freedom”, but all of them is overwhelming. I have credentials/experience to back up each of them, but probably don’t have the reputation as a general expert that someone like Dan North or Liz Keogh can use to have people ask me anything.

So I want to pick one. One thing, probably from that list, and pivot to focus on that. Or at least get in through the door that way, then have the conversations about the other things once you know how much faster and easier I make it for you to make high-quality software.

And I’d really value your suggestions. Which one thing do you know me for, above all others? Which one thing is the pain that the place you work, or places you’ve worked, most need fixing?

Comment here, have a chat, send an email. Thanks for helping me find out what I want to be when I grow up.

posted by Graham at 10:03  

Wednesday, October 9, 2019

Great Documentation, Great Software

A paraphrased conversation, the other day, between me and a customer of one of my customers:

Me: Are you experienced at working with my customer’s developer APIs?

Them: I always feel like a newbie, because there’s so much stuff. But I always end up finding the docs I’m looking for.

Me: I’m writing the docs.

Them: Well, thanks! :D

Whether you’re writing developer APIs or graphical user interfaces, quality documentation that’s easy to find and use when needed is the best way to turn customers from novices who find the complexity offputting, to novices who know they’ll be able to tackle whatever’s coming their way.

Quality documentation is also useful for improving the quality of the software itself.

Docs-driven development

If you already know about test-driven development, you know that a benefit of TDD as a design tool is that it encourages you to think about your code from the perspective of how it will be used. Rather than implementing an algorithm then exposing an API that you hope will be useful, you design the API that helps solve the problem then implement an algorithm to support the use of that API.

Documentation is another tool for encouraging empathy in design. For every point you have to explain, you get to ask:

  • “why do I have to explain this?”

  • “Is there another way to design this such that I don’t need to tell people about this detail?”

  • “Is the thing that I’m telling people how to do, the thing that they would expect to want to do?”

Dev-driven documentation

The questions listed above can be most effectively answered if documentation is part of your iterative cycle of continuous improvement. Documentation can inform design and development, by pointing out cumbersome or difficult parts of the implementation. Development can inform documentation, by showing where the complexity lies and how to deal with it.

Documentation interacts with other activities, too. Test plans should ensure that they cover examples or walkthroughs from the documentation, so that you know the examples you’re giving to your customers actually work. Documenters should collaborate with testers to ensure a shared understanding of what the software is aiming to achieve.

Documents like API specifications, user manuals, or walkthrough videos should be versioned and built alongside the corresponding versions of the software.

Working software over comprehensive documentation

Throughout these activities, the point is not to generate documentation for its own sake. One office I worked in had a shelf containing several feet of documentation for a UNIX system that I never opened: the online documentation and a couple of cookbook-style books were sufficient.

The reason for putting effort into your software’s documentation is that this effort yields improvements in the software. A more empathetic design, a better-tested implementation, and more confident customers are all steps on the path to higher-quality software, easier and faster. And of course, the Labrary can help you with that.

posted by Graham at 11:35  

Thursday, October 3, 2019

Solving the underlying problem

As a software engineer, it’s easy to get work engineering software. Well, maybe not easy, but relatively so: that is the kind of work that comes along most. The kind of work that people are confident I can do. That they can’t do, so would like me to do for money.

It’s also usually the worst work available.

I don’t want to take your shopping list of features, give you a date and a cost, then make those features. Neither of us will be very happy, even if it goes well.

I want to get an understanding of your problem, and demonstrate how software can help in solving it. Maybe what we need to understand isn’t the problem you presented, but the worse problem that wasn’t on your mind. Or the opportunity that’s worth more than a solution to either problem.

Perhaps we ask a question, in solving your problem, to which the answer is that we don’t know, and now we have another problem.

You might not need me to build all of the features you thought of, just one of them. Perhaps that one works better if we don’t build it, but configure something that already exists. Or make it out of paper.

You understand your problem and its domain very well. I understand software very well. Let’s work together on combining that expertise, and both be happier in the process.

posted by Graham at 17:44  

Powered by WordPress