Finding the Sweet Spot

We’re developers. We love code.

We’re developers. We hate code. “No code is better than no code”.

We have developers. They are a great resource.

We have developers. They are a terrible expense.

Each developer is unique.

Developers are a commodity.

A long time ago, when I was a “programmer/analyst” for a major advertising firm, we ran into a bit of a conflict with someone from account management. I don’t remember the details, but it had something to do with scope changes and ill-defined requirements. And no matter how off the wall their requests were, how self-contradictory, how internally inconsistent, we had to go with them. It was disturbing and would sometimes get a little heated.

Finally a senior executive — silver-haired and well-suited as you might reasonably imagine in those immediately post-Mad Men days — took me aside, saying, “One thing you have to remember: They are a profit center. You are a cost center. The sooner you incorporate that into your being, the less discomfort you’ll feel.”

Whether you call us programmers or software engineers or developers, we’re a pretty fortunate bunch. With the exception of just a couple of downturns over the last number of decades, we’ve been generally in demand. We’ve been generally pretty well-compensated. And, perhaps because of that last item, there’s always been an attempt to commoditize us. Whether it’s the not-so-virtuous cycle of technology adoption (“we’ll use X because there are a lot of software engineers that know X so a lot of people learn X because it’s popular and some of them shouldn’t be writing code at all so the quality of  those who write X goes down so…”) or off-shoring or whatever there’s a desire to make things at least predictable but mostly, well, cheaper.

And that’s a shame. Admittedly looking from the inside, developers can often have a rather broad view of a company and deep concerns for its success. And we tend to be a reasonably clever bunch as well. We do, in general, blanch at the way much of business is done, with its reliance on hierarchy and on deeply abstracted metrics (often preferring, it seems, the state of the chosen metrics over the reality of the situation) but tend not to limit our view of things to the associated bits-and-bytes we push around.

This is not to say,  for a moment, that we don’t enjoy the pure delight of techie nerd-wrestling; finding a more efficient way to move data or a more effective algorithm to find a small bit of truth is always a delight. But we care about the bottom line. We have a true understanding that if the organization does not have success neither do we.

But finding the sweet spot is a non-trivial exercise. Engineers need to be engaged and involved as well as being left alone to do their jobs. They need to be appreciated as humans contributing as well as being appreciated as a resource. And they need to be respected as people who are often dealing with the unknown. Developers spend a good deal of their time finding needles in haystacks, discovering ways to model a not-completely-consistently-defined reality.

Given what we cost, finding that sweet spot is well worth it.

“Adversarial Programming”

I am not talking about having two coders, each of which is trying to destroy the other’s life and career, being chained together and forced to pair. What I am talking about, though, is an idea to add to the list of pairing/mobbing options that exist.

One of the typical rules observed in any multi-programmer paradigm is that there is one and only one driver. That one person at the one keyboard is the only one who presses the buttons and makes the magic appear on the screen. What if we did something different than the one-driver rule?

I’m proposing doing just that. But instead of just having two different people at two different keyboards clicking away madly, we merge in ideas from TDD. In this case, one of the keyboards is writing tests, the other is writing code. Tests are an expression of requirements; code fulfills those requirements. As functionality develops, tests can be written to expose possible corners where behavior may not be as desired. Tests try to break, code is refined to fix. The adversarial back-and-forth creates a rhythm that should have an optimizing effect upon the process.

This could also be fruitfully extended to a mob programming context (and may, in fact, work better there). There would still be two drivers, but the other members of the team would be making contributions as appropriate.

[I’m looking forward to an opportunity to implement this, at least in the small. I’l report back.]

Just an intro…

I’ve written code on these and these and these and these. I wrote some SL/I (a dialect of PL/I), where the semicolon was spelled “.,”. Made a living in Algol. Even wrote some APL code.

I have a copy of “The C Programming Language” (not the ANSI C EDITION).

Procedural? Check. OO? Check. Homoiconic? Check. Immutable? Check. Functional? Check, check.

I like this stuff and I sometimes write about it.

The previous entries here are items originally written for Sparefoot’s Engineering Blog, which I use here with permission. Thank y’all for that.

Today’s Aphorisms (2017-10-04)

Create value or create language by which your colleagues can create value. It’s all value.

“People > Process” means just that. It’s unambiguous.

Narrow contexts compose a hell of a lot better.

Saying “we’ll simplify later” is the worst kind of technical debt.

Complication eats effort. And yields nothing.

Dealing with complication is like paying protection money; all it does is cost.

TEAM is a powerful concept. Multiple sets of eyes is a benefit, not a cost.

Locality Matters (2017-09-07)

One of the things that can make our codebase somewhat difficult to work with (making defects much too easy to create) is that we often lack locality of concept.

(Hmmm. Sounds like something Gold would say. But what the hell does it mean?)

Code both does things and decides how things are to be done. Is this valid? No? Kick it out! Is it red? Do this. Is it blue? Do this. Is it purple? Ah, that’s a special case, do thisthis and this.

Despite the possible complexity of these decisions, it’s not too hard to keep all the business logic contained therein straight – at least so long as all of that business logic lives in the same place. Often, for what are good, pragmatic reasons at the time of writing, some of this logic ends up getting smeared about the codebase. And before long, some of the behavior associated with various objects becomes somewhat less clear, especially when new functionality is introduced.

So keep that in mind. No one really wants to have to do a deep code grovel to understand how an instance of a class behaves; besides, having to do such a grovel greatly enhances the chances of getting things wrong.

So keep it together, because locality matters!

Getting It Write the First Time (2017-08-20)

We write code. That’s what we do.

Well, that’s not entirely correct. We solve problems. We provide solutions. When we can do it without code, we declare it a win.

But most of the time we write code.

How do we write code? We don’t chisel it into stone. We don’t have to pull individual pieces of type from various drawers and physically typeset it page by page. We don’t carve it into wood. We don’t spend the time and effort of bending pipe-cleaners into letters and numbers (and punctuation) and glue it to a large board.

No. We open an editor or an IDE or whatever and just start hitting the keys on the keyboard. Some are faster than others. (And most are faster than me.)

But is it hard to write code? Well, no. Certainly no harder than writing about code. Or writing about the design of code. So what we do is easy, right?

Well, sometimes. But overall not so much. Yes, writing code is easy. Writing good code, on the other hand, code that scales well, code that is robust, code that does what we think it does and what it should do, code we can read, code that can be changed reasonably when such changes in requirements occur, code that runs fast enough for our requirements, well THAT’S HARD.

Frequently we nerd wrestle over system design; we ask whether this functionality should go here or go there, whether we should take this approach or that approach. We stand at whiteboards and draw an endless array of pictures and diagrams, boxes, arrows, dotted lines, all that kind of stuff. Now I am, by no means, suggesting that these are not valuable activities. Thrashing out our hypotheses on things we don’t know yet, on systems yet to be created is our opportunity to learn, our opportunity to form a sufficient model of a system to actually implement it.

Sometimes, though, se can get a little stuck. Boxes and pictures and arrows can be somewhat ambiguous. Different people can come away from such a session with different understandings of what’s been proposed. What if (he asked) we had some kind of notation, some kind of consistent abstraction in which to express our system design decisions? Hmmm. What could something like that possibly look like?