Main | August 2006 »

July 31, 2006

Doing Things Wrongly

Our DBA had a problem. He was trying to figure out the best way to populate a bridge table with the full set of keys from two source tables. The answer was to do a simple Cartesian product. It hadn’t occurred to him. The problem was that he had it classified as the wrong way to do things. Not surprising, I guess … this site describing such joins points out that Cartesian joins are “usually done by mistake.”

Be sure not to exclude things from your arsenal of solutions by classifying them as “the wrong way to do things.” Sometimes the wrong thing is precisely what you need.

July 30, 2006

Design and Ambiguity

Eide Neurolearnings has an article on “ambiguity” and how developing minds deal with it. I disagree with many of their implications (for instance, that the difficulty children have in dealing with ambiguity is a discrepancy between the development of the reasoning and communicating abilities), not to mention the very … err … ambiguous use of the term, “ambiguity” in each of the associated articles.

So I will limit myself to discussing ambiguity in brainstorming.

There’s no such thing.

Oh, fine, I’ll elaborate.

This referenced article describes the tolerance of ambiguity as “the ability to live in a universe where there are no right or wrong answers, where ideas or thoughts are vague and yet unformed.” These are two very different things. The former phrase is an assertion that, epistemologically, concepts have little or no relation to reality and, therefore, can not be used to determine truth or validity in relation to reality (alternatively, it could just be embracement of the same old tired subjective reality beliefs … yawn.) The latter phrase, on the other hand, is useful ... a statement that concepts can be incomplete. In other words, a statement of “insufficient data”.

What does this mean for us in a design situation … how do we minimize ambiguity, identify it, resolve it, and keep it from causing problems in our projects? (Note that this is not an exhaustive list … I don’t describe, for instance, the things that must be done in the process of mapping abstracts to concretes.)

  1. Thoroughly define your context.
  2. Identify constraints (typically concretes, so be aware of how these are reflected abstractly.)
  3. Take measures to know what you know about every concept (attributes, intrinsic behavior, relationships, classifications, and methods of interaction), both in terms of completeness and confidence.
  4. Take measures to know what you don’t know, both in terms of requirements to accomplish the specified goal as well as deficiencies implied by context, interaction, relationship, and      methods of implementation.
  5. Figure out if the things you don’t know are relevant to the individual step in the chain of reasoning.
  6. Figure out if a later reasoned step mitigates a lack of information in a former step.
  7. Describe the efforts necessary to resolve each deficiency.
  8. If you choose not to break up the brainstorming session in order to resolve the deficiencies, figure out what you think the conclusion will be, give it a degree of confidence, a      significance with regard to subsequent conclusions, and a description of risk to the entire solution if your conclusion is wrong.
  9. Figure out if you can design out the risk (i.e., if a deficiency in knowledge has two ways in which it can resolved, determine if you are able to implement your solution in such a way that either case can be handled).

Omniscience is a fantasy. Beware anyone who never says, "I don't know." Train anyone who acknowledges ignorance, but doesn't yet deal with it in a structured manner. Embrace anyone who can describe for you a solution that compensates for ambiguity. Fire anyone who says, "You can't know."

July 28, 2006

Bathroom Code

I've worked in office buildings across this country, and there's something that can always be said, without fail. The bathrooms are always poorly designed.

In the building I'm currently working in, for instance, there's a narrow lane between the side of a stall and the sinks, which, in and of itself, isn't a big deal ... except that the paper towel dispenser and trash receptacle are positioned at the closed end of that narrow lane, so anyone washing their hands in any but the leftmost sink must get paper towels by crossing anyone to his left, dripping water on the floor and, possibly, his impediment's clothes. Also, the door is on the opposite side. Which means that those people who like to open the door with a paper towel protecting their hands (not that any of you fail to wash your hands thoroughly, you vectors) will frequently just throw the used paper towel on the floor. How tidy.

I have no idea why this would be the case. My only guess is that bathrooms are boring, so the job of designing bathrooms is given to the most junior people in the architect's office. Probably fresh out of school, rarely having worked in office buildings, not yet having trained themselves (or been trained) to design for practical use. Form follows function, but function includes actual use, not just theoretical, ideal use.

What's the equivalent of designing bathrooms on your project? Who's got the job, and what instruction did you give them?

A Little More On Exceptions

I've found a number of good links describing various aspects of exception/event logging:

Exception Handling Best Practices in .Net

Handling and Throwing Exceptions (MSDN)

Daniel Turini's Lair (Exception Handling Best Practices in .Net)

and then here's an IBM Redbook that provides some nice theory on the subject of Event Management and Best Practices.

And then there's this one here that I think needs some clarification and warning ...
he speaks of handling the errors "centrally", and what he appears to mean by that is to use a single uniform method (or collection of methods). No problem, provided you remember his other statement about using available context, and design your application infrastructure accordingly (i.e., if you have an exception way down at the bottom of your process stack, make sure you can convey all the relevant information you need to report, identify, and (hopefully) resolve the problem all the way back up, and that it can be handled correctly by that central event handler. This may mean defining a serializable wrapper class to encapsulate a set of contextual properties that can then be passed back up the chain, possibly across remoting boundaries, etc.

He also suggests reporting errors to the Windows Event Logs. "I'm going to have to go ahead and sort of disagree with [him] there."

There are many issues I have with writing to the event logs:

  1. For the most part you're stuck with text. It's nice if you can serialize objects that are relevant to the event/exception context and have them available for automated analysis. Sure, you could serialize them up as XML instead of binary, if you want to take the performance hit, but you still don't have a good way of deserializing and accessing them programmatically.
  2. If your application is running on one machine, no problem. If you're on a web farm, do you really want to have to check every machine's event log to get the information for whatever exception a specific customer is screaming about? And that's assuming you actually did use a centralized handler and don't also have to look on multiple tiers ... application servers, database servers, whatever. Sure, you can use a third party app like Rutherford suggests to monitor them all for you, but quis custodiet ipsos custodes?
  3. If your centralized exception handler is at the web level (as it probably has to be unless you don't care about web-level exceptions), are you really dumping your exception information to the web server's event log? With as much context information as possible so the exception can be tracked down? To a machine in your security DMZ?

July 27, 2006

Programming: Language and Thought

Programming is a difficult art to do well. I don’t mean the high level design or the specification of implementation patterns to use, I mean the actual “let me type up the implementation of this single procedure” effort. The problem lies in the need to have both structured, repeatable, consistent patterns of consideration and thinking, while simultaneously having a set of mental processes that lend themselves to innovation and unconventional insight. There’s the added difficulty caused by the fact that programming is often iterative in nature … you might add the portions of the code here, expect there to be interaction over there, and have to come back here to change things around based on behavior and expectation there.

Setting up a template of things to consider doesn’t work for many reasons, not the least of which is that, for the template to be useful across the board, it would have to be so generic and abstract that the concrete specifics of how to use it in a particular circumstance would allow the programmer so much flexibility that he’d dismiss the template entirely (which he would be inclined to do, since a template of what to think about would be offensive to him and his expensive training). Besides, if you have a template of steps to consider, you allow yourself to be constrained by that template, and innovation suffers.

Frankly, there is no solution. However, there are things that can be done to improve the situation by nudging the programmer’s mind in such a way that he considers certain aspects as part of his normal (and possibly unique) programming manner. The key is language and its use.

Words are referents that point to concepts. When you use a word, you’re indicating to a person that they should consider aspects of the concept. Multiple words might refer to the same concept, but indicate that different aspects of the concept should be considered relevant (this is one of the reasons that accurate use of language is important to unambiguous communication.) The structure of the language can also indicate a particular contextual framework in which the referred concepts should be evaluated.

Similarly, if you force a programmer to consider the language he is to use, or the structure he is to use, you can nudge his thought processes in such a way that he considers a particular necessary aspect of coding that he might otherwise overlook. As such, the person responsible for establishing a company’s (or API) coding style must consider areas in which he can provide this nudge. I’ll provide a few examples (please note that these are _examples_, and I will not enter into a debate about whether my particular example is the right or wrong way to do things.)

Classes, in general, reflect a conceptual entity. Therefore, classes should be named with the noun or noun phrase part of speech. By doing so, the programmer is forced to envision the thing and its intended context. Not only does this cause the programmer to more thoroughly evaluate that context (project business processes) allowing the team to identify deficiencies in specification, and also allows him to identify a meaningful hierarchy of related concepts such that a class hierarchy can be defined, but it also makes it easier for him to keep a mental image of the entity being modeled in mind as the coding proceeds.

Properties and methods have their own requirements and naming styles that can lend themselves to better development style. I’ll address these in the comments if necessary, but otherwise I’ll leave it as an exercise to the reader.

The Microsoft Visual Studio environment allows a developer to construct code “regions”, which are just delimited areas of code identified by a common name (with the ability to collapse everything down to a single node identified by that name.) If the coding standards require regions based on the access type of a particular property or method (e.g., #region Protected Methods), that reminds and encourages the programmer to evaluate what access level is actually appropriate, since recommended practice requires that you use the most restrictive that is reasonable.

There are times when resources must be closed or explicitly released (in the case of interacting with unmanaged code or GDI objects, given a few Microsoft GDI leaks), but programmers will frequently forget to consider this. If your coding style always requires that every code block be put in a Try … Finally structure (given that the Finally block is usually where you want to do that kind of clean-up), then the programmer is reminded in every procedure that he should evaluate whether that kind of clean-up is necessary. You don’t want it to be a Try … Catch or Try … Catch … Finally block, because this would encourage the programmer to unnecessarily handle exceptions, and this is not recommended practice.

Keep these techniques in mind, and consider them when documenting your own coding standards guides. Comments of other suggestions welcome, of course.

July 25, 2006

Corporate Cronyism

If you are trying to achieve a goal, it is entirely reasonable to hire people you trust to facilitate the accomplishment of that goal. Trustworthy people being fairly rare, people in positions of authority tend to keep the same people around them as they move from effort to effort.

People who dislike the particular goals of a person will describe this situation as “cronyism”, but the term, “crony”, implies no such evaluation of goals or methods. It just means an associate you’ve had for a long time (from “khronos”, Greek for time.) People that use the term, “cronyism”, want to imply an immoral or evil intent by virtue (so to speak) of the fact that you’ve got trusted associates around you, implying that the associates support you, not because of their evaluation and support of the goals, but because of, at best, lap-dog obeisance and obedience. They use the term in such a way that you have a visceral reaction to the term itself, avoiding the need to actually evaluate and refute the goals and intent specifically. Any statement by anyone who uses the term must immediately be given lower credibility, and greater effort and thoroughness must be used when evaluating their other claims.

However, identifying cronyism, particularly in business management, has its uses. For instance, if a CEO has a history of success while being surrounded and supported by the same staff, company after company, then that suggests that success in the current venture might be more plausible.

If, on the other hand, a CEO has a history of failures (bankruptcies, resignations for non-success, desperation mergers, etc.), and he has continued to surround himself with the same supporting staff, you must conclude one of the following:

  1. he does not associate repeated failure with himself and his decisions or competence
  2. he  does not associate repeated failure with his support staff and their decisions or competence
  3. his goal is not the success of his company, but is, instead, something that he is achieving despite each failure … therefore, he _does_ view himself as successful

Close scrutiny must be given to the situation to determine which of these is the case and, if the case is either of the first two, what the actual cause of repeated failure was (a predilection for lost causes, for instance.) Needless to say, as an employee or potential employee, accurate identification of this situation is essential.

As an employee, here’s a subset of things to be answered:

  • How many failed situations?
  • Role of each supporting individual?
  • Any individuals departing after each failure? If so, any publicity surrounding the departure, and any subsequent success on the part of that individual?
  • Is there a common theme surrounding each situation (industry, business model, stated corporate philosophy, customer type, etc.)?
  • Would this position be worth it if you only kept it for 1 year before being laid off? 6 months? 3?

Think of other things to ask, what each says about the situation, and what terms you must demand when being hired in order to compensate for the situation.

July 24, 2006

Time and Intent

Ok, I've decided to be a little tighter on the scope of this blog. There are plenty of blogs out there that identify the consequences of poor thinking skills in, for instance, the realm of politics, but those posts can not be evaluated adequately by most of the population because of those same poor thinking skills. This is not surprising, given that the US public school system fails to consider actual thought or even correlation to reality to be significant issues when focusing on stuffing as much disconnected information into our heads as possible. This needs to change.

Therefore, this blog will focus on four things that are of interest to me:

  1. Suggestions of mental processes to cultivate that facilitate accurate thinking (e.g., evaluating form vs content vs intent of statements)
  2. Applying such thinking to business-related activities (from a management perspective)
  3. Analytical skills that programmers should cultivate (e.g., SQL optimization and management BS detection)
  4. Consequences of sloppy thinking on individuals (e.g., relationship of the denial of standards to self esteem)

The problem with limiting myself to these subjects is that I'll basically be talking to myself. Although there are a couple of relevant blogs that I know about, most blogs deal with issues a little farther along the philosophical chain from epistemology. Therefore, link references and trackbacks will consist of three types: examples of good thinking that I've described in the past (or concurrent with the link reference), examples of a particular pattern or example of bad thinking, and cases in which a particular thought process might have saved someone from unfortunate consequences. I will try to make these examples as obvious as possible, with as little complexity or subtlety as possible so that the point being made is clear.

One thing I will not do (at this time) is try to convince anyone why accurate thinking is necessary. I figure that anyone who hasn't concluded this is lost, anyway, and we should just treat them as children and hope they don't breed.

July 21, 2006

Local Meltdown or Global Society?

There are countries that have practiced female infanticide for centuries (an act that has started to embrace technology in the form of gender-selective abortions.) Historically, when the number of available females has dropped significantly below the number of males seeking wives, bad things happen.

In the US, it has always been considered important for women to find husbands who can actually support a family ... even if the woman intends to work, the goal of acquiring a husband who _could_ provide sole support remains. That holds true despite the degree of gender equality we pretend to have embraced (perhaps because it's mitigated by the amount of misandry we've also embraced.) In modern society, that means an educated man. But we're rapidly eliminating the critter. I wonder what will happen when the future generations of girls grow up and find few viable husbands.

Perhaps seek out husbands in India and China, where the men can't find wives?

Or something quite a bit less civilized?

The Render Principle

In 1969, a guy named Dr. Laurence Peter wrote a book in which he described a consequence of promoting on merit within a hierarchical organization. The consequence was that people get promoted because they are competent at their jobs, and eventually reach a position in which they are no longer competent. In a fit of creativity, he called this the Peter Principle.

There are a few obvious and not so obvious consequences to this. One is that, in a company which has had managerial turnover, any person who has been in the same position for an extended period of time is probably not competent to do the job. There are obvious caveats to this, and the evaluation must be made on a case by case basis … for instance, a person in charge of every absolutely critical project a company has produced over a period of years probably handles that effort very well.

A not so obvious consequence is that creative upper management has identified this problem, and has invented the idea of a “sideways promotion” in which they give the no-longer-competent person a set of duties that is more in line with his previously displayed level of competence, but at a hierarchical level equivalent to his most recent promotion. This, of course, results in upper management bloat, because someone has to do the job that is being vacated by the “sideways promotion”, so another manager is promoted to that position.

Upper management bloat as a result of “sideways promotion” also frequently changes the focus of a company from developing products to developing process (since those managers can not be put back in charge of the product development they previously controlled, but are only competent within that context and must do something to give the perception of productivity.) Companies that become predominantly process generators rather than product producers are in trouble, and this is what happened to many small consulting companies toward the end of the Internet bubble. Although this cause paled in comparison to one I will mention momentarily.

In 1990, Scott Adams (creator of Dilbert) made the satirical observation that companies promote their least competent employees to management to limit the amount of damage they can do to the company (similar to my frequent desire to have different political parties control each of the Legislative and Executive branches of the US government.)  Unfortunately, this observation had its root in fact. And, as Scott Adams intended his Dilbert Principle to be satirical, I choose to slap my own name on my interpretation of it … therefore, the Render Principle:

The problem is that, in an environment in which the fundamental production requires a high level of education or training and a creative and disciplined mind, the number of competent, not to mention talented, employees is fairly constrained. In a tight market, they become absolutely rare. So, while the traditional promotional methods require that these talented individuals be promoted into positions of management, in, for instance, the IT field, a company that did so would find itself unable to produce quality products (this effect can be mitigated by putting in procedural checks, like formalized unit, integration, regression, and user testing.)

But these companies need management that is familiar with the development requirements and techniques … therefore, they must promote from the same pool of employees. If it would be suicidal to promote their competent employees, they have no choice but to promote their less capable counterparts, evading the fact that inability to perform the minutiae of product development probably indicates a lack of understanding of the entire process. This is usually not suicidal because the competent developers frequently have such a strong work ethic that they will save seemingly doomed projects from the ineptitude of project managers, but this results in very long hours, poor home life, poor health, and general job dissatisfaction (the only reason they don’t leave for a better position is how pervasive the situation is in the industry.)

There are features of bad managers that complicate the issue and put more work on the remaining developers (for instance, interpreting their inability to manage as a lack of control of the development process, forcing them to impose unnecessary layers of process and documentation on an already burdened development team), but I will address those at another time.

Knowing this is the situation, all competent IT professionals, when interviewing for new jobs, should ask questions that will identify if they will be working under one of these types of managers. Think about what kinds of questions those would have to be.

July 20, 2006

... to be commanded

"Think of it as evolution in action."

Playing the Game

Back when I was in school, my mother (a teacher) told me that I needed to learn to “play the game” with regard to school and schoolwork. What she meant by this was that I needed to do the things the teacher wanted (as opposed to things that were actually productive, educational, or indicative of some transfer of knowledge or experience) in order to be judged good. If I were judged good, I would get good grades and, consequently, into college (this being before the Internet boom, when graduating from college was pretty much required in order to have a comfortable life.)

I should mention that she was making this statement in reference to activities demanded by a person designated as a “Master Teacher” by my school system.

Being a potentially rational child (as all children are before being corrupted by adult minds), I thought this was pretty silly. While discipline and obedience might be considered useful traits, the lessons that I concluded were being taught were 1. that the perception of accomplishment was more important than actual accomplishment and 2. the educational system was about accomplishing arbitrary steps in a process (that is never explained, justified, verified, and appears to have no relation to reality), not actual learning.

And in my consequent efforts, both of these conclusions proved to be true. If this book is any indication, those lessons don’t change as you advance through the educational system.

So students are getting lessons that learning is not a useful goal … that actions associated with school are tasks to complete, disconnected from any other use but the immediate grades the accomplishment earns them. This is but one of the ridiculously large number of implicit and explicit indicators that actual thought (the facilitation of which is the whole point of learning) is not a useful or desirable thing.

And teachers seem to be surprised that students don’t continue efforts that they think should be educational, or that the risk of failure outweighs the potential benefit of learning:

Communities of Learners

The Game of School

Helping "Fake Readers" Become Proficient Life-Long Readers

My mother visited the other day. During one part of a conversation, I mentioned that I remembered the lessons she taught me. What I didn’t say was that many of those lessons were unintentional.

Do you know what lessons you’re actually teaching your children?

July 19, 2006

An Inaugural Post

And so it begins again. This thing is being put up for two reasons ...
1. to write up the comments and articles I've currently been telling to the cat
2. to motivate myself to finish writing my own blog software intended merely to test my own architecture before using it for a large-scale site completely unrelated to blogs.

This post is also to test what information is actually displayed on the page.

This will probably be the least contentious post I ever make. Share and enjoy.