DaedTech

Stories about Software

By

Don’t Just Flag It — Fix It!

Editorial Note: I originally wrote this post for the SubMain blog.  You can check out the original here, at their site.  While you’re there, download a trial of CodeIt.Right.

More years ago than I’d care to admit, I took a software engineering course as part of my graduate CS program.  At the time, I worked a full time job during the day and did remote classes in the evening.  As a result, I disproportionately valued classes with applicability to my job.  And this class offered plenty of that.

We scratched the surface on such diverse topics as agile methodologies, automated testing, cost of code ownership, and more.  But I found myself perhaps most interested by the dive we did into refactoring.  The idea of reworking internal structure of code while preserving inputs and outputs is a surprisingly complex one.

Historical Complexity of Refactoring

At the risk of dating myself, I took this course in the fall of 2006.  While automated refactorings in your IDE now seem commonplace, back then, they were hard.  In fact, the professor of the course considered them to be sufficiently difficult as to steer a group of mine away from a project implementing some.  In the world of 2006, I suspect he had the right of it.  We steered clear.

In 2016, implementing automated refactorings still presents a challenge.  But modern tool and IDE vendors can stand on the shoulders of giants, so to speak.  Back then?  Not so much.

Refactorings present a unique challenge to tool vendors because of the inherent risk.  They can really screw up users’ code.  If a mistake happens, best case scenario is that the resultant code fails to compile because then, at least, it fails fast.  Worse still is semantically and syntactically correct code that somehow behaves improperly.  In this situation, a refactoring — a safe change to code — becomes a modification to the behavior of production code instead.  Ouch.

On top of the risk, the implementation of refactoring anywhere beyond the trivial involves heady concepts such as abstract syntax trees.  In other words, it’s not for lightweights.  So to recap, refactoring is risky and difficult.  And this is the landscape faced by tool authors.

I Don’t Fix — I Just Flag

If you live in the US, you may have seen a commercial that features a funny quip.  If I’m not mistaken, it advertises for some sort of fraud prevention services.  (Pardon any slight inaccuracies, as I recount this as best I can, from memory.)

In the ad, bank robbers hold a bank hostage in a rather cliche, dramatic scene.  Off to the side, a woman stands near a security guard, asking him why he didn’t do anything to stop it.  “I’m not a robbery prevention service — I’m a robbery monitoring service.  Oh, by the way, there’s a robbery.”

It brings a chuckle, but it also brings an underlying point.  In many situations, monitoring alone can prove woefully ineffective, prompting frustration.  As a former manager and current consultant, I generally advise people that they should only point out problems when they have also prepared solution proposals.  It can mean the difference between complaining and solving.

So you can imagine and probably share my frustration at tools that just flag problems and leave it to you to investigate further and fix them.  We feel like the woman standing next to the “robbery monitor,” wondering how useful the service is to us.

Levels of Solution

Going back to the subject of software development, we see this dynamic in a number of places.  The compiler, the IDE, productivity ad-ins, static analysis tools, and linting utilities all offer us warnings to heed.

Often, that’s all we get.  The utility says, “hey, something is wrong here, but you’re going to have to figure out what.”  I tend to think of that as the basic level of service, or level 0, if you will.

The next level, level 1, involves at least offering some form of next action.  It might be as simple as offering a help file, inline reading, or a link to more information.  Anything above “this is a problem.”

Level 2 ups the ante by offering a recommendation for what to do next.  “You have a dependency cycle.  You should fix this by looking at these three components and removing one mutual dependency.”  It goes beyond giving you a next thing to do and gives you the next thing to do.

Level 3 rounds out the field by actually performing the action for you (following a prompt, of course).  “You’ve accidentally hidden a method on the parent class.  Click here to rename or click here to make parent virtual.”  That’s just an example off the top, of course, but it illustrates the interaction paradigm.  “We’ve noticed a problem and you can click here to fix it.”

Fixes in Your Tooling

When evaluating your own tools, look to climb as high up this hierarchy as you can.  Favor tools that identify problems, but offer fixes whenever possible.

There are a number of such tools out there, including CodeIt.Right.  Using tools like this is a pleasure, because it removes the burden of research and implementation from you.  Well, you can always do the research if you want, but at your own leisure.  But it’s much better to do research at your leisure than when you’re trying to accomplish something else.

The other, important concern here is that you find trusted tooling to help you with this sort of thing.  After all, you don’t want something messing with your source code if it might mess up your source code.  But, assuming you can trust it, this provides an invaluable boost to your effectiveness by automatically resolving your problems and by helping you learn.

In the year 2016, we have far more tooling available, with a far better track record, than we did in 2006.  Leverage it whenever possible so that you can focus on solving the pressing problems of your day to day work.

By

Taking the Guild Metaphor Too Far

Today, I’d like to talk about the pervasiveness of the craft guild metaphor in today’s software development landscape.  Specifically, I want to talk about how I think we’ve jumped the shark with this and how it now harms more than helps.  I recognize that I’m probably going to inspire some ire and get myself in trouble here, but please hear me out a bit.

First of all, some words of caveat.  I don’t say this from a place of any hostility or really even criticism.  In other words, I don’t take the position, “you’re all making a mistake with this and being silly.”  Rather, the more I wrote in Developer Hegemony, the more the guild metaphor came to feel wrong to me.  But only during the course of the last few days did I figure out how to articulate why.  So now, I post from the perspective of, “I think we recently took a slight wrong turn and that we should stop to reconnoiter a bit.”

Before I get to building my case, I want to spend some time applauding the guild metaphor for what I believe it has provided us.  I believe it important that I do so because it clarifies my position.  You can’t make a “wrong turn” without having started on the right track.

Also note that I don’t believe anyone has stated what I’m about to say as the reasoning for the metaphor.  What you will read next comes from inferences I have made.

Prequel to the Guild Metaphor: Drilling Holes in Sheet Metal

Corporate software development, by and large, got its start helping organizations capitalize on efficiency opportunities.  Some VP of something, looking at a typed spreadsheet, would say “if we could speed this process up by 25%, we could hit our third quarter numbers!  Poindexter, come in here and do that thing you do with the computer and make it so!”

Poindexter would then leave and come back a few days later.  “I flipped the bits and bypassed the mainframe and transmogrified the capacitor and –“

“In English, Poindexter!”

“Oh, right, sorry Mr. Rearden.  I was able to do a 30% speedup.”

“Good work, Poindexter!”

In this world, you had business people who would create strategy and delegate cost savings to geeks in bite sized morsels.  The geeks would diligently execute their tasks.

Because of this historical and ubiquitous communication deficit, the business people misunderstood the nature of geek work.  Their mental model of software development paralleled it to building construction and manufacturing.  The geeks occupied the role of line level laborers in their particular domain.  And so decades of horribly mismanaged software projects ensued.

“Come on, Poindexter, I need your codes for the next speedup by Friday or we won’t make our numbers!”

“But, Mr. Rearden, you don’t understand – it’s not that simple!  We can’t just – “

“Look, Poindexter, it’s not rocket science.  Just code faster and copy and paste the thing you did last time.  Think of yourself as a guy who drills holes in sheet metal, Poindexter.  Get a stronger drill bit, and lay the last sheet over the new one, using it as a template.  Do I have to think of everything?!”

“But, Mr. Rearden, it doesn’t work that – “

“Shut up Poindexter, or I’ll find a cheaper, offshore Poindexter!”

Read More

By

Plugging Leaky Abstractions

Editorial Note: I originally wrote this post for the NDepend blog.  You can check out the original here, at their site.  While you’re there, download NDepend and play around with it.

In 2002, Joel Spolsky coined something he called “The Law of Leaky Abstractions.”  In software, an “abstraction” hides complexity of an underlying system from those using the abstraction.  Examples abound, but for a quick understanding, think of an ORM hiding from you the details of database interaction.

The Law of Leaky Abstractions states that, “all non-trivial abstractions, to some degree, are leaky.”  “Leaky” indicates that the abstraction fails to adequately hide its internal details.  Imagine, for instance, that while modifying the objects generated by your ORM, you suddenly needed to manage the particulars of some SQL query.  The abstraction leaked, forcing you to understand the details that it was supposed to hide.


Spolsky’s point may inspire a fatalistic feeling.  After all, if the things are doomed to leak, why bother with them in the first place?  But I like to consider it a caution against chasing perfection rather than a lament.

Abstractions in software help us the same way figurative language helps our prose.  Metaphors and analogies offer ease of understanding, but at the accepted price of lost precision.  If you press a metaphor enough, it will inevitably break down.  But that doesn’t render metaphors useless — far from it.

Thus, if you have a leaky abstraction, you can take steps to “plug” it, so to speak.  Spolsky says it himself, right in the law he coined: “all non-trivial abstractions are, to some degree, leaky.”  We have the ability to lessen that degree.

Read More

By

The Developer Feedback Loop

Editorial Note: I originally wrote this post for the SubMain blog.  You can check out the original here, at their site.  While you’re there, check out some of the products that they offer, including GhostDoc and CodeIt.Right.

If you write software, the term “feedback loop” might have made its way into your vocabulary.  It charts a slightly indirect route from its conception and into the developer lexicon, though, so let’s start with the term’s origin.  A feedback loop in general systems uses its output as one of its inputs.

Kind of vague, huh?  I’ll clarify with an example.  I’m actually writing this post from a hotel room, so I can see the air conditioner from my seat.  Charlotte, North Carolina, my temporary home, boasts some pretty steamy weather this time of year, so I’m giving the machine a workout.  Its LED display reads 70 Fahrenheit and it’s cranking to make that happen.

When the AC unit hits exactly 70 degrees, as measured by its thermostat, it will take a break.  But as soon as the thermostat starts inching toward 71, it will turn itself back on and start working again.  Such is the Sisyphean struggle of climate control.

TerrifiedOfFurnace

Important for us here, though, is the mechanics of this system.  The AC unit alters the temperature in the room (its output).  But it also uses the temperature in the room as input (if < 71, do nothing, else cool the room).  Climate control in buildings operates via feedback loop.

Appropriating the Term for Software Development

It takes a bit of a cognitive leap to think of your own tradecraft in terms of feedback loops.  Most likely this happens because you become part of the system.  Most people find it harder to reason about things from within.

In software development, you complete the loop.  You write code, the compiler builds it, the OS runs it, you observe the result, and decide what to do to the code next.  The output of that system becomes the input to drive the next round.

If you have heard the term before, you’ve probably also heard the term “tightening the feedback loop.”  Whether or not you’ve heard it, what people mean by this is reducing the cycle time of the aforementioned system.  People throwing that term around look to streamline the write->build->run->write again process.

Read More

By

What Does Code Quality Really Mean?

Editorial Note: I originally wrote this post for the SmartBear blog.  You can check out the original here, at their site.  While you’re there, have a look around and check out Collaborator, the code review tool.

Let’s say that you wanted a definitive explanation, once and for all, as to what constitutes code quality.  You might take to google and type “definition of code quality,” which would yield a post from this very blog as well as a sampling of Q&A sites.  For the purposes of this post, however, I’d like to examine the entry that occurs here, at programmers’ stack exchange.  I think it may be the perfect microcosm for this discussion.

The Q&A Site Consensus

The question is simple enough: “what does it mean to write good code?”  The answer receiving the most votes is one in which the respondent draws a parallel to top-notch pool players, who are so good that they set up their next shot as an easy one, even while making the current shot. High-quality code “looks like it was easy and straightforward to do.”  This is a classic example of “I can’t define it, but I know it when I see it.”  You can recognize code quality because it “looks easy.”

pool-player

Next up in vote total was a response that cited a popular, somewhat crass cartoon.  The gist of it is that code quality is inversely proportional to the number of perturbed utterances per minute on the part of people reading the code.  High quality code is code that triggers this response infrequently, whereas low quality code triggers this response vehemently and regularly.  Like the answer preceding it, this is not a definition but a recognition heuristic.  But with this response, the respondent clarifies that such a definition may actually be impossible, and heuristics are the best approximation.

From there, the answers get more specific and acquire fewer votes each.  One respondent offers “how fast can you understand the code” as the defining criteria for high quality code.  It is easy to imagine push-back by someone pointing out that “while(true) { }” is trivial to understand, but the resultant application that simply hangs is probably not the product of high quality code.  For the most part, the rest of the answers list properties of good code in an attempt to provide the requested definition.  “Good code is bug-free, reusable, well-documented, easy to change, etc.”  None of these garnered many votes, but each did receive a few.

So what was the verdict?  There was no accepted answer and the moderators closed the question as “not constructive.”  The reason cited was, “this question will likely solicit debate, arguments, polling, or extended discussion,” thus rendering the question not a fit for Stack Exchange’s paradigm of being a Q&A site with discrete and concrete answers.  This is not an indictment of the question, per se, but rather a determination that it’s inherently subjective.

Read More