Copy
View this email in your browser
Arch-Engineer
Code better

Some thoughts on goto

Dijkstra's "Go To Considered Harmful" is so well-known it's become a snowclone. To many, goto statements have become an object as historical as punchcards, taught only so long as to tell they're not useful. When I could barely write "Hello World," my father, who started with Fortran in the 70's, told about the dark ages of goto vs. the blessed renaissance of "you know it always comes back" subroutines.

If that's your view, then some news: goto statements remain quite common, and quite useful. 

This will probably have no effect on any of you. Most you probably work in languages that don't have goto (notwithstanding one April Fool's joke for Python). If you work in C, then you probably already know this. But there are a few more general lessons here from thinking about this.

First, some perspective on what Dijkstra spoke against, vs. its more restricted use today.

I was born long after the victory of structured programming, so my experience with the dark days comes second third hand: as a tool developer. I once sat down with a company in Seattle that sells maintenance and conversion tools to COBOL shops. In their demo, they spoke of "automatically documenting" code, and then showed me the "documentation" that they generate: a control-flow diagram!

Though their customers may have been suffering, spaghetti so tangled that one needs a control-flow diagram to understand it now scarcely exists. Let's spool it aside and ask the fundamental question: Why control flow?

Take a function, and split it at every line. Each line can be given a logical description of its input/output behavior. These can be grouped into a handful of contiguous meaningful chunks, which together compose into the intended behavior of the entire function.

With each line or chunk, one can also associate a boolean formula that dictates whether it runs. That formula is called a "path condition." To the extent that the meaningful chunks (or rather, their desired behavior) are not arbitrary, neither are the path conditions.

So long as these chunks run in some order which satisfies their preconditions and obeys their path conditions, the function will work. There's even a trick where you replace all control-flow with a single while-loop and switch statement, with the cases in arbitrary order.

From this primordial soup, one can sequence chunks according to their path conditions. Thence control-flow.

Most of the time, the conditions under which a line should run are a subset or a superset of those around it (a stack discipline). This is when structured programming shines.

Unfortunately, there's no fundamental reason this should always be the case.

If there is a case when the path conditions do not obey the stack discipline, then you need indirect control flow. If that use-case is not covered by return, break, or continue, then you want goto.

When one deletes a goto and replaces it with nested conditionals, the same code is running under the same path conditions.

At this point, the only difference between the two approaches is ergonomic. And there's a lot to be said for the flatter code produced by goto.

The canonical case where goto is useful is in error handling: putting some cleanup code at the end of a function, and doing a goto error on failure in the middle. Relevant Internet discussion: Goto in the Linux KernelGoto discussion in the C2 Wiki . I specifically want to call out the "goto hell" example in the C2 Wiki article as exemplifying massively changing a program to remove goto, but without modifying the path conditions of any meaningful line.

Sadly, the goto-based error-handling pattern is hard to use even in the supersets of C. In C++, one cannot goto past a constructor (i.e.: most variable declarations). In Objective-C, one cannot goto past any method call.

But, beyond error-handling, I recently learned another case where goto statements can be a quite elegant solution: state machines. And that brings me to...

 

Book Review: Elements of Programming


I'm on a very long mission to find all the good writing about software design. Over the past two years, I've had multiple people suggest "Elements of Programming," written by Alexander Stepanov, best known as the creator of the C++ STL. The C++ STL is among the most magical libraries used today, and "Elements of Programming" has been described as Stepanov's 200-page justification of how he build it.

So, is Stepanov's "Elements of Programming" something every programmer should read?

No.

But it does contain a neat trick for writing state machines with goto statements.

Book Review: Elements of Programming

Advanced Software Design Web Course: Now Open


A few months ago, a student from the March run of the course informed me of his first major success in what he set out to do when he came to me: guiding his team away from a bad design decision.

Last week, a 1-on-1 coaching client informed me that he got his dream job.

Watching people achieve their dreams is my greatest joy, and the knowledge that I taught them some skills that helped is my greatest pride. And there's a new chance opening to gain some software design skills: The next run of my Advanced Software Design Web Course, starting 10/8, is now accepting applications. There are 5 slots remaining.

 
Copyright © 2020 Mirdin, All rights reserved.