Wednesday, June 26, 2013

Certain Uncertainty

"There are known knowns. These are things we know that we know. There are known unknowns. That is to say, there are things that we know we don't know. But there are also unknown unknowns. There are things we don't know we don't know." --Donald Rumsfeld

--Ed. Note: Changed to link to Gene Hughson's G+ profile rather than just mention his name. Should have thought of that the first time.

+Gene Hughson , author of a blog that is shortly going to be added to my "What I Read" section, has a fascinating article on the dangers of Premature Certainty. It's quite long, but well worth reading. Worth reading a couple of times, in fact.

Right out of the gate, he gets to the meat of it:
"Premature certainty, locking in too soon to a particular quality of service metric or approach to a functional requirement can cause as many problems as requirements that are too vague. For quality of service, also known as “non-functional”, requirements, this manifests as metrics that lack a basis in reality, metrics that do not account for differing circumstances, and/or metrics that fail to align with their objective. For functional requirements, premature certainty presents as designs masquerading as requirements (specifying “how” instead of “what”) and/or contradictory requirements. For both functional and quality of service requirements, this turns what should be an aid to understanding into an impediment, as well as a source of conflict."
There are several important points here that every software architect needs to keep in mind. The temptation in a software project is to start talking about performance and quality of service- the dreaded Non-Functional Requirements, or NFRs- far too soon. It's an understandable temptation as it's near and dear to the business unit's heart. It's also a subject largely misunderstood by the business unit's heart. When Donald Knuth said "Premature optimization is the root of all evil (or at least most of it) in programming.", he was talking to programmers more than the business unit, but both sides ought to take heed of his warning.

So why is this so dangerous? Generally, isn't focusing on optimization and performance A Good Thing? Well, sure, but there's a great difference between focusing on performance and deciding on how to measure it. Especially if you decide on how to measure it before you're finished.

The problem is that NFRs are more like decorating a living room than building one. When you build a living room, you have definite dimensions you conform to.  You have building materials that you need to use, you have building codes you need to adhere to, and these are all very measurable and easily tracked. In decorating a living room, however, you have a general set guidelines to work within, but few hard and fast rules, if any. "I want the room to be light and airy" or "I want a more modern feel" are both valid sets of instructions for room designers, but it would be absurd to tell a designed "I want a minimum of 5.8 on the Light/Airy scale and am willing to settle for a 3.2 Modernness level". Yes, the designer is expected to engage the room's owner on every step of the design process, but you can't really know the final result until you see the final result. And there's certainly no scale against which to measure the final result.

This is the difference between Qualitative and Quantitative requirements, and making sure that everyone understands the difference between the two, and into which any given requirement falls, is the difference between building meaningful and meaningless requirements. Hughson references Tom Graves' Metrics for Qualitative Requirements:
To put it at perhaps its simplest, there’s a qualitative difference between quantitative-requirements and qualitative ones: and the latter cannot and must not be reduced solely to some form of quantitative metric, else the quality that makes it ‘qualitative’ will itself be lost.

And therein lies the proverbial rub. The concept of the managed project so often comes from purely quantitative worlds. Construction is an excellent example. The projects I saw at a defense contractor are also prime examples of quantitative projects- you received a set of specs and you build to the specs. NFRs didn't factor in. Software development simply isn't like that and the disconnect comes in when we try to treat software development projects as if they were purely quantitative. As architects, it often falls on us to manage this disconnect because we're often caught between the business, which often hasn't considered the difference between the two types of requirements, and the development staff, who will almost certainly understand the difference but on a more experiential level that is more difficult to communicate to someone lacking the same experiences. And as the group that is often tasked with communication between the two groups, it's of critical importance that software architects understand the difference between the two kinds of requirements and can clearly communicate the difference and its importance to the business unit.

Hughson also goes on to discuss the importance of developing functional requirements that have a level of certainly to be useful while still keeping the level of uncertainty needed to stay flexible and allow architects to do their job. Also a good read, and also necessary to keep in mind. However, as I'm in the middle of attempting to manage the development of NFRs on a current project, I very much focused on the first part and wanted to write this out as an attempt to better understand the points Hughson was making. I think it helped me and I hope it helped you, too.

Monday, June 24, 2013

Programming and Philosophy

“This, what is it in itself, and by itself, according to its proper constitution? What is the substance of it? What is the matter, or proper use? What is the form, or efficient cause? What is it for in this world, and how long will it abide? Thus must thou examine all things that present themselves unto thee.” --Meditations, Marcus Aurelius

“That forces you to sort it out in your own mind. And the more slow and dim-witted your pupil, the more you have to break things down into more and more simple ideas. And that’s really the essence of programming. By the time you've sorted out a complicated idea into little steps that even a stupid machine can deal with, you've learned something about it yourself.” --Dirk Gently’s Holistic Detective Agency, Douglas Adams



I once read a posted question from a person asking advice on what degree to pursue in preparation for a computer game programming career. My answer, in its entirety was:

Although it's been awhile since I left college, I know several universities are starting degree programs that are geared more toward practical applications of programming skills. Whether it's called "Computer Engineering" or "Informatics" (A word that's always somewhat bewildered me) these degrees are more centered on applying the concepts of Computer Science.
In other words, you won't learn how to write sorting algorithms, but you will learn how to use them in various platforms. Take for what you will.
Personally, I don't care. Give me someone that can mentally deconstruct a problem and think through a practical solution. They can be taught to be good programmers, assuming they haven't already learned. In a lot of ways, I'd take someone with a philosophy degree. Someone who is used to asking what the nature of an object is and it's role in the system it resides in is a heck of a lot more useful than a "Cowboy Coder" that just blasts through something to get a project done.
 Without software development, programming is ultimately a pointless exercise. Computer Science is intellectually stimulating and a necessary part of software development. However, unless applied for some practical use it is nothing more than theoretical pedantry. And while Computer Science is encompassed by Software Development, it is by no means the most important aspect.


Software development is about solving a problem. Whether it’s “I need an online application to sell my product” or “I need a game on my mobile device to pass the time”, software development fills a need. And in order to fill a need, you first have to understand the need and the domain in which that need will be filled. These are not trivial points, nor are they tasks left to a business analyst or some such, although it is up to such a person to help the development staff understand these things.


A teacher of mine, back when I began learning about software development, told me that programming is about creating idealized models of real world concepts. In order to implement a payment processor, for instance, you need to create a software analog of the concept of a payment. Of the machine that accepts the payment. Of the items you are paying for. And in order to create accurate models of these real world ideas, you need to understand them, what they do, what they know and are responsible for, and how they fit into the whole. Again, this is not a triviality. Creating a model of a payment that knows about the items being purchased causes problems when it is time to create a new kind of payment or a new way of representing the items being purchased. Just as creating a shopping cart that knows how to pay for its contents causes problems when a new kind of cart or payment is needed. This is a fundamental concept in software development and one that can not be properly implemented by someone that doesn't understand the problem to be solved or the domain in which it is to be solved.

This is the reason for my comment. I don’t care if you can swap variable values without an intermediary variable. I don’t care if you can hand-code a sorting algorithm or think you can write a better encryption scheme or algorithm. In fact, in order, I say “Who cares?”, “Use a tool”, and “No you can’t. Use a tool.” I care if you can ask the questions “What is this? What does it mean to be this? What does this thing do and what does it know?” I want someone that can deconstruct a problem and break it down into little steps that a stupid machine can understand, thus increasing his own understanding of the problem. Without these abilities, a developer’s actual programming ability can only be properly applied by accident. In other words, in order to become a successful software developer, one must first become a philosopher.


Friday, June 21, 2013

Another Programming Blog? Seriously?

"Just because you don't know what the right answer is - maybe there's even no way you could know what the right answer is - doesn't make your answer right or even okay. It's much simpler than that. It's just plain wrong." --Dr. House, "Three Stories"

"Tough decisions made in the absence of information" --A saying around my office

The idea of a programming blog isn't exactly new. In fact, it seems that in the software development world you can hardly throw a virtual rock without bouncing it off of a couple of blogging developers. I'd even go so far as to say that with the ubiquity of stackoverflow, a purely programming technique blog is nearly pointless anymore. So why bother adding content that is almost certainly redundant?

To put it mildly, the subject of "What is the code to implement this technique with this development platform" is well covered. It's somewhat harder, in my opinion, to find good advice and articles on the subject of how to structure your code to not make your life harder in the future. Or how to think about code structure so that the decisions pertinent to your project are clearer and easier to make. Note- I did not say "Easy to make" but rather "Easier to make". If the decisions were easy there would be no need for someone to make them.

I don't intend to post a lot of code. In fact, I specifically don't want to post a lot of code. I think that without code, I'll be forced to focus more on the thought process behind the techniques and concepts rather than how to implement them. Again- implementation is well covered.  Knowing what concepts are relevant and why is much harder because of two facts that I have found to be almost universally true:

  1. There are no "right" answers. Merely decisions and the underlying reasons for those decisions.
  2. Even if there is a right answer, you likely won't know it ahead of time
Any reader that has made it this far (And thank you for that, by the way) has certainly noticed that these truths not only contradict Dr. House's point above, but reject his statement out of hand. I didn't lead with that quote to present it as a correct- or even viable- way to approach software design and architecture. I have found, however, a prevailing expectation among project stakeholders and sometimes even IT management that this sort of principle applies. This isn't an expectation to be "managed", as the project buzzword goes. This is an expectation to be ended. As software architects, we strive to make the best decisions based on the information we have. Then we go on to refine those decisions to account for situations that we expect, based on our experiences in the craft. But not only can we not account for everything, as I will cover in a future article, we shouldn't even try. Because of that, things are missed. Sometimes it's okay. Sometimes you grin and bear it. Sometimes you kick yourself- assuming someone else isn't already providing you with that service. Whichever way it goes, all you can do is make the best decisions with the best information you can.

I'm here to try and help with that.