Get Off The Critical Path

From the words of wisdom department:

When I worked for the Boston based web development team of a major financial services firm, Jim was my manager. Jim would admonish his team to “get off the critical path.”

There’s an animated cartoon where a character is riding on a toy train and laying track as fast as possible in front of the moving engine. Software development can sometimes feel like laying railroad track from the front of a moving train — while also building the train.

Any large project with many contributors will have choke points where tasks that fail to be completed on schedule will slow or stall the work of others. No one wants to be the target of finger pointing when a project schedule slips but “get off the critical path” was not intended as a cynical CYA tactic.

Jim’s approach was not selfish, but holistic. “Get off the critical path” is about planning and communicating, anticipating needs and setting expectations, and being open about setbacks and flexible about alternatives. It’s about having all the members of a team providing good customer service to each other and to all the other teams on a project.

More from the words of wisdom department:
constructive nonconformist: Know What You Know And Know What You Don’t Know

Camping Out

Back in June I took our son camping for the first time. It was a very short trip; We pitched a tent on the front lawn. (This is a Father/Son activity. Mommy’s not keen on sleeping on the ground.)

When the two of us (with some help from the neighbor kids) set up the tent, he was very excited to sleep in the tent. But later, after nightfall, sleeping out in the tent took on a different aspect.

“Daddy I scared.”

I asked what he was scared of.

“Monsters! Scary monsters outside.”

He’s a big fan of Elmo so I explained that monsters don’t have to be scary and that there are many friendly monsters like Elmo and Cookie Monster.

He considered this and looked at me very thoughtfully for a moment.

Then he announced “Elephants! Scary elephants outside.”

Netscape Cookies (circa 1997)

Here’s a short note I originally published on the web in July 1997. I dredged it up recently because I had forgotten the syntax of the cookie meta element.

Cookies are supported by both Netscape Navigator and Microsoft Internet Explorer. A cookie may be set by a header response directive or an http-equiv meta tag.

Header Directive Format:
Set-Cookie: NAME=VALUE; expires=DATE; path=PATH; domain=DOMAIN_NAME; secure

Meta Tag Format:
<meta http-equiv="Set-Cookie" content="NAME=VALUE; expires=DATE; path=PATH; domain=DOMAIN_NAME; secure">

A more complete description of cookies is available in the following Netscape documents:

Tech Note: Cookies: what they are and how they workTech Note: How to write a server-side CGI program to set and read cookiesSpecification: Client Side State - HTTP Cookies

The GMT string for the first second of January 1, 1970 UTC, as required by the expires attribute, is

Thu, 01-Jan-1970 00:00:01 GMT

This is the beginning of time on Unix and Win32 systems.

Also of interest is RFC 2109, a proposed standard for an “HTTP State Management Mechanism.”

I didn’t explain seven years ago but there is a reason why it’s good to know the “GMT string for the first second of January 1, 1970 UTC.” It’s an arbitrary but consistent value to use for removing cookies.

Update January 2014

Updated Netscape document links to use the Internet Archive Wayback Machine.

RFC 2109 has been obsoleted. See RFC 6265.

A Single Point of Correctness

To increase the reliability of a system, engineers strive to eliminate single points of failure. Elimination of a single point of failure is often achieved by adding redundancy.

In the design and in the structuring of code, adding redundancy doesn’t increase reliability. Just the opposite. Duplicate code creates problems.

I once worked with a programmer who could produce great amounts of code very quickly. He achieved these results by prodigiously copying and pasting. The code he produced was difficult to understand and maintain. Fixing a bug could become very involved because it wasn’t enough to identify and understand the issue; it was necessary to find every potential pasted instance of the suspect code.

Strive for a single point of correctness. A single authoritative expression of an idea contributes to greater reliability and cheaper, faster maintainence. If the authoritative expression is wrong the software can be incorrect consistently and there’s just one place to make the fix.

Related Reading
Orthogonality and the DRY Principle.

Know What You Know And Know What You Don’t Know

From the words of wisdom department:

Ten years ago I was working as a software engineer for a small company in Los Angeles. (The company was located on Pacific Avenue in Venice but that’s another story.)

Jerry was the company’s Vice President and I had great respect for him at the time. He understood that software development is a nonlinear open-ended creative process. He would often say “Know what you know and know what you don’t know.” In a former career he was an attorney with the Department of Justice and I can see the same advice being applied to preparing for a trial.

In the context of software development his adage has, for me, become shorthand for a number of related ideas that I have internalized:

Be well prepared. Read the RFP and the business requirements. Listen to the customer. Ask lots of questions.

Test assumptions. Verify what you think you understand. For example clarify that different parties are not using the same words for different concepts.

Get the lay of the land. Get a feel for the feature set and how the project will sub-divide into tasks and how the tasks will fit together.

Look for problems early. Turn over as many rocks as you can as early as you can. Look for issues in the requirements and specifications. Experiment with any required but unfamiliar APIs and libraries. Look for the stuff that can bust your schedule.

Give yourself permission not to know. In the short term knowing what is unknown is more important than solving the unknown.

Understand where your risks are and manage the risk. The unknown can harbor a lot of potential risk. Where on your evolving mental map of the project do you note “here be monsters?”

Build research into the project plan. Create project tasks that are to write test programs or prototypes for issues that are deemed difficult or just poorly understood.

Tackle the unknowns and the hard problems first. Front load the project plan with the tasks that have the greatest chance of going wrong. Every project will have unexpected setbacks. Wouldn’t it be great to have all the setbacks up front and have the project get easier as you race to the finish?

Understand that the process is iterative. You may recognize most of these points as design activities. Design doesn’t stop when coding begins.

More from the words of wisdom department:
constructive nonconformist: Get Off The Critical Path

Pragmatic Programmer

Around this time last year I was reading serialized installments of an interview with Andy Hunt and Dave Thomas on Artima.comy. Andy Hunt and Dave Thomas are the authors of The Pragmatic Programmer: From Journeyman to Master and you can get a flavor of the book from reading the ten installments of the Artima interview.

Don’t Live with Broken Windows
Orthogonality and the DRY Principle
Good Enough Software
Abstraction and Detail
Building Adaptable Systems
Programming Close to the Domain
Programming is Gardening, not Engineering
Tracer Bullets and Prototypes
Programming Defensively
Plain Text and XML

I highly recommend the book. It’s a fun read (if you think software engineering can be fun (I do)) and structured in short punchy sections that make it ideal for reading on the commuter train.

Disallowing Copying in a C++ Class

How would you design a C++ class so that objects of that class type can’t be copied? Why would you want objects that can’t be copied?

I have asked many people those two questions. For a long time those two questions were part of my standard repertoire of interview questions for candidates for positions requiring knowledge of C++. Most of the people I asked did not have ready answers. That was okay. The intent was to see how the candidate would approach solving the problem and how much knowledge of construction and assignment in C++ the candidate possessed.

How To
To prevent copying, a C++ class needs to declare a copy constructor and an assignment operator (operator=). At face value it’s counter-intuitive. To prevent copying, declare a copy constructor?

By default C++ allows copying. For any class that doesn’t declare its own, the C++ compiler will provide a default copy constructor and a default assignment operator. No good for a ‘no copy’ class.

Declare a copy constructor and an assignment operator so the compiler won’t provide the default versions but make both methods private and don’t provide implementations.

If an external non-friend function or class method calls the copy constructor or the assignment operator, compilation will fail because the methods are private. Friends and methods of the same class can call privates but compilation will still fail because the copy constructor and assignment operator are declared but not defined. (Intentionally declaring but not defining a method is sometimes termed “poisoning a method.”)

Example
class NoCopy
{
public:
    …
private:
    // copy ops are private to prevent copying
    NoCopy(const NoCopy&); // no implementation
    NoCopy& operator=(const NoCopy&); // no implementation
    …
};

Why
Why would copying be disallowed? The motivations can be generalized as either logical or pragmatic.

Logical is when copying doesn’t make sense for the class type or model.

A class type that implements the Singleton design pattern is an example. A singleton should disallow copying by definition.

Another example might be a class type that wraps an external resource that has no copy semantics. For instance a class designer could decide that it is not meaningful for an object that wraps a thread to support copying.

A pragmatic motivation is when copy support doesn’t violate the class type’s logic but a decision is made to not allow copying anyway. This could be an exercise of the YAGNI principle. Or it could be based on knowledge that a copy operation for the given class type is very expensive and should be prohibited.

Class Design
A C++ class design is not complete if copying hasn’t been considered. Do the default copy constructor and assignment operator provide the correct copy behavior? Probably not if the class has any data members that are pointers. And if not, decide to either implement correct copying or disallow copying. Don’t leave a time bomb for the next programmer.

Unlike C++, Java requires an explicit decision to implement copying rather than providing a default that can be wrong. But objects in Java are all references and the ability to copy is actually rarely needed.

The Java experience can be emulated in C++ by preferring to pass objects by reference and const reference. Objects that are never passed by value can pragmatically disallow copying.

Snow

It’s snowing in eastern Massachusetts tonight.

The 5 o’clock commuter train from Boston nearly overshot the platform completely. Passengers from the lead cars had to tramp through the woods. The conductor quipped that the track must be slick.

My wife and son met me at the train station.

When we get home, my son is very excited. “Play tag daddy!”

He’s three. He loves to be chased round the kitchen table. “Get me, get me”, he says. It’s apparently ferociously funny when I change direction on him. He’s laughing too hard to run.

“Play hide seek!” I ask him him who will count first. “Daddy count.”

He always hides in the same place — under the dinning room table. He giggles uncontrollably. I pretend I can’t find him.

My family is all asleep now. I can hear a snow plow and the wind outside.