Showing posts with label rant. Show all posts
Showing posts with label rant. Show all posts

Monday, November 11, 2013

When is the right time to select a source code control tool?


If you’re about to start a new project it’s a good time to consider what version control solution you’re going to use.-- Article discussing TFS vs Git
I read the above statement in an article recently and my brain threw an exception when it parsed it. You know how that works. You're scanning along the text and all of a sudden, half a paragraph later, an interrupt is raised "Wait, did I really just read that?" You stop and go back over it.

There are plenty of articles covering how to choose a source code control tool. Many places compare and contrast all the options,[1] both open and close sourced. You can find articles that discuss the pros and cons of distributed VCSs vs centralized ones. However, I don't recall ever seeing one about when to choose one. The following is my opinion on this seemingly under-discussed topic.

The quote above is one of many similar statements I've seen over the years. It wouldn't surprise me if many project startup policies include choice of VCS as one of their bullet points. So, I'm not picking on this particular article, it just presents some common wisdom that I don't consider all that wise and I'm using it as a jumping off point to open the discussion.

First some context. Most of my career has been in developing shrink wrap software. The projects I work on are small parts of larger products that in turn are one of many that make up a company's product line.

The VCS contains vital enterprise assets. It should contain everything needed to build the current products for a company: the source code, build scripts, installer scripts, developer environment configuration scripts. It should also contain all the supporting documentation for users, both external and internal. Because it maintains versions of all these files, it also contains metadata about all them. It tracks who changed what, when and, if good change set notes are used, why. It may also be linked to an issue tracker, putting those changes in a larger context than just the source code. There may be a CRM system that gets linked to it. It is one piece of a larger whole.

For a development group to start a new project and consider what VCS they're going to use is like the accounting department opening a new checking account and considering what accounting package they're going to track the transactions in. The accounting department will have an existing system in place that tracks more than simple checking registry entries. They would not change this just for a single account. In the same way, the development group should have existing systems in place to handle not just VCS but all the support systems that surround a project. They should keep all the projects in the same ecosystem.

Keeping everything in one place does a number of things. It decreases startup time; there's one less decision to make. It reduces training; developer's don't need to become proficient in yet another tool. It eliminates confusion about "where do I go to get X?" It enhances cohesion among projects; it's easier to share code that may be common. It reduces maintenance costs; there's one less server that needs to be provisioned, integrated, maintained, backed up, and so on.

In my opinion, choice of VCS is something that should be done long before any particular project starts and should not be within the purview of any single project. So, when I read something that says a new project is a good time to choose a version control system, by initial, totally biased reaction is to scream "NO!"[2]


1. And in fact that was the focus of the above article.
2. And the same could be said, to varying degrees, of any software project support tool, be it VCS as discussed here or issue tracking or process control or documentation tools or build tools or UI widget libraries or IDEs or -- the list can go on and on.

Thursday, July 19, 2012

Are Coding Philosophies Irrelevant?

I recently read a rant opinion piece about how the behind the scenes part of an application is irrelevant. The author had some good points. One was, from an end user's perspective, how an application is put together is irrelevant. Another one was that success in the marketplace is not determined by which patterns are used, what the development tool-chain looks like or which language is used. I agree with all this. However he went on to say that therefore, these behind-the-scenes things are irrelevant.

To this I respectfully disagree. If the code base for an application is only to instruct the computer how to do something now, then I suppose the author might have a point. But, I think the author forgot that the end user is only one user of the application and source code is important for more than the current compile. Another very important user is the developer. Over the course of an application's lifetime, there might be many developers who will work with that code. Or there might be one who maintains it for its entire life. In either case, the source is used as much, if not more, to communicate to those reading the code what is going on as it is for the computer.

The computer just does as it's told. It doesn't care what it's told or the meaning behind the why or how. It doesn't have any concept about patterns or tool-chains or philosophies. These things are not used to communicate intent to the computer. As a simplistic example, the assignment of the sum of y and z to x, to the computer is meaningless. It doesn't care why this addition is done, or the importance of assigning the result to one place over another. The mechanics of line
x = y + z
are clear to both computer and programmer but it could mean anything. And, the meaning is irrelevant to the computer. But, to the developer, it is crucial to understanding the bigger picture.

To the computer, these two lines are equivalent to the one above.
balance = beginningBalance + deposit
newHeading = currentHeading + errorDelta
However, to a developer, assuming the variable names are accurate for the problem domain, they communicate very different things.

In the same way, other more abstract organizations of how a given piece of software is written communicate, to various degrees and with various success, important information to the developer. Patterns, tool-chains and coding philosophies are irrelevant to the compiler. To the developer, they can, if effectively used, convey information crucial to understanding the problem the software attempts to solve and the original author's vision of how to do it.

In the greater scheme of things, they are far from being irrelevant.

They are critical.


Update: I just ran across this quote I thought was appropriate:
The best programs are written so that computing machines can perform them quickly and so that human beings can understand them clearly. A programmer is ideally an essayist who works with traditional aesthetic and literary forms as well as mathematical concepts, to communicate the way that an algorithm works and to convince a reader that the results will be correct.
-- Donald E. Knuth, Selected Papers on Computer Science
And this reminded me of another quote:
You're creating a vocabulary, not writing a program. Be a poet for a moment.
-- Kent Beck

Friday, December 3, 2010

DRY vs KISS

Two developers are playing poker. The chips are all on the table and it's time to show their hands. One throws down the DRY hand. The other throws down KISS. Which hand wins? Who gets to take the pot home?

There are many guidelines in software development. These are two prominent ones: DRY and KISS. For those who haven't heard of them, DRY stands for Don't Repeat Yourself and KISS stands for Keep It Simple, Stupid.

The underlying principle behind DRY is that there should be one authoritative source for any artifact in a piece of software. This can take different forms depending on the context. One example might be a constant literal. If a literal, for example a numeric value or a string value, exists more than one place in a program, it's a bad thing. The duplication should be removed and replaced with a named constant. The constant becomes the authoritative source for the value. This also has the side effect of making the software more readable if a good name is chosen because the meaning can be conveyed, not just the value. Another example is duplicated code. If lines of code are copied and pasted, there becomes more than one authority for the code's behavior. Instead, those duplicated lines should be put in a function that can be called from the various places the behavior is needed.

The KISS principle is based on the idea that complexity makes code that's hard to understand, maintain and debug. Code that is hard to understand will have more bugs in it to begin with and take longer to get working properly. It will also be harder for the person who has to maintain it to make changes and hence will increase the cost of ownership over the lifetime of the product.

On the surface, I think most developers will agree that both these principles are good. However, I think there is disagreement upon which one trumps the other.

An argument could be made that removing duplication increases complexity. In the examples for DRY above, adding a function or constant declaration adds indirection. As you read the code, the value is not immediately obvious and the behavior is not readily apparent. You have to go somewhere or use some feature in the IDE to find the value or determine what the routine does. In addition to readability, as you write, you have extra work to make a separate function. It is much faster to simply copy what you need and paste it somewhere else.

I understand these arguments. I know first hand the temptation to grab a section of code and paste it somewhere else. I know the pain of slowing down and having to think deeply about how to not make the duplicate copy of the code. Given all that...

DRY trumps KISS every time.

When I look at the long term maintainability, having one place where behavior or values or anything else is defined is always the better thing. I've experienced first hand maintenance of code with high levels of duplication. I have made changes in one place without knowing about the duplication and not also fixing the same code elsewhere. I have seen others do the same thing. The testing and validation in these scenarios can get very painful. When maintaining software and making changes, dealing with a single authority is much more accurate and faster, even with increased indirection.

In addition to long term maintainability when behavior should be changed, not repeating yourself reduces the chance of copy and paste errors. More times than I care to count, I've found bugs where a block of code was copied and minor changes made throughout it. Missing even one thing that should be changed will result in insidious bugs setting up residence in your application. Many times these won't be caught until much later in the product's life-cycle, increasing the cost of fixing them.

Just today I violated this principle... even after thinking "do I really want to do this?"... even with the draft of this article fresh in my mind... and I introduced a bug that took me a minute to figure out. I had these two lines:
const string name1 = "value one" ;
var value1 = !computeValueForName(name1);
That I duplicated and changed to this:
const string name2 = "value two" ;
var value2 = !computeValueForName(name1);
See the error? When I did, I promptly refactored this to:
var names = new [] { "value1" , "value2" };
var values = from n in names select !computeValueForName(n);
So, yeah, when I see violations of DRY I have almost a compulsive need to fix it. How about you?

Thursday, September 9, 2010

Apple Rants

I first played with an Apple computer in the early '80s at a local computer store. My next experience was with a Macintosh an employer purchased to play on. Over the years, I've worked on mini-computers, S-100 based computers, PCs with various versions of DOS, Unix and Windows. Despite friendly jabs I may give friends, I don't really consider myself a computer or operating system bigot. I've watched the maturing of Apple computers from the side-lines, fairly impressed by the changes I've seen over the last 10 or so years. I have a number of friends who are Mac fans and have observed the improvements over their shoulders. I saw a lot of Apples as Windows machines at a recent Microsoft conference. More than once I've heard that the MacBook was the best Windows laptop around.

Given all this, when I recently needed to get a new computer I decided to take the plunge and get a MacBook Pro. I was pretty excited to get something so different than my usual fare. It arrived last week and I've spent the better part of the weekend and last couple days configuring it and a new Windows server I got at the same time. Overall, I really like it. The hardware design, the look and feel, the fit and finish are superb. It feels really solid. It feels like a BMW or Mercedes compared to the Dell's Chevy or Ford feel. As good as the hardware is, the operating system software doesn't seem to match up. The following paragraphs rant about some of the issues I have with it.

The biggest issue has to be the Copy/Cut/Paste key mappings. Why are they different than Windows and Linux? What was the reasoning that said they should do something different from the rest of the industry that has no real value? To be different? In my opinion, this is a major impediment to people new to OS X feeling comfortable with it. On SuperUser.com I did find a hint to be able to remap the keys, so they now work as I expect. I wonder though how many people just put up with it as frustrated users.[1]

The next issues seems like a huge anachronism. Circa 1985, before windowing PC operating systems had multi-tasking, each application took over the screen. In those days, putting the Menu bar at the top of screen made sense. However, as soon as you could have more than one application open at a time and visible on screen, basic user experience guidelines dictate the menu bar should be with the window it controls, not at the top of the screen. Given their big emphasis on design in some areas, why Apple thinks violating basic user design principles of keeping similar functions close to where they're used as it relates to the menu bar completely escapes me.[2]

Microsoft has used the SMB protocol for computer discovery and file sharing for a long time. It has become the defacto standard. I find it incredible that there is no way to browse the network and find computers dynamically on the Mac. It seems one can only connect to a networked computer if you already know the name. And to connect to it you have to use a fairly cryptic "smb://computer_name:139" syntax. Really? ... Really? Linux has "just worked" in this regard for many years. And it's worked overall better than Windows itself has. It's about time Apple caught up to the real world.

Finally, Snow Leopard just seems less stable than Linux and Windows have in a long time. Its stability feels like Windows did for the Windows 95 release. Several times in last couple days things have gotten wonky that were fixed by rebooting. A number of times when this happened, shutdown didn't work. It just hung after clearing the screen; I had to power down by holding the power button until it powered off. I can't remember the last time that happened on a Windows or Linux box.

Given all these rants, I don't want to give the impression I don't like my new machine. It is speedy. It is solid physically. And really, overall, I haven't had a ton of problems. Perhaps the problems I have had are more remarkable and obvious given the cleanness of the rest of the system. I'm not yet ready to do as some have and install something else as the base operating system and run OS X in a virtual machine.

2. See "The Structure Principle" at Principles of User Interface Design. Many people talk about this principle such as this one and this one.