“Computer programs are the most complex things that humans make. Programs are made up of a huge number of parts, expressed as functions, statements, and expressions that are arranged in sequences that must be virtually free of error. The runtime behavior has little resemblance to the program that implements it. Software is usually expected to be modified over the course of its productive life. The process of converting one correct program into a different correct program is extremely challenging.”
-Douglas Crockford
Posted: September 16th, 2011 | Author: benlakey | Filed under: benlakey.com | Tags: software craftsmanship, software engineering | No Comments »
How do you measure programmer productivity?
When the Lisa team was pushing to finalize their software in 1982, project managers started requiring programmers to submit weekly forms reporting on the number of lines of code they had written. Bill Atkinson thought that was silly. For the week in which he had rewritten QuickDraw’s region calculation routines to be six times faster and 2000 lines shorter, he put “-2000″ on the form. After a few more weeks the managers stopped asking him to fill out the form, and he gladly complied.
Posted: August 26th, 2011 | Author: benlakey | Filed under: benlakey.com | Tags: Apple, software craftsmanship, software engineering | No Comments »
I originally posted this on our development blog over at MSNBC.
Are you familiar with feedback loops? A feedback loop is a loop in which information encountered by the system is fed back into the system, and the system can then respond to it. You’ve probably seen a diagram similar to this:

Feedback loops are very important for a system since they allow the system to evolve and adapt to change. A great example of this seen in nature is the human body’s temperature regulation:

Without feedback, the body would have no way of making the minor adjustments it needs.
Feedback loops turn out to be extremely valuable in software development as well. Agile development practices all relate to the notion of a feedback loop:
- Unit tests
- Pair Programming
- Sprints
- Stand-up meetings
- Code reviews
You may notice something about these practices; The feedback loops are very fast. Feedback loops that are slow are of little value, because by the time you respond to one set of feedback, the next may have already arrived, which would render your initial response meaningless.
In the example of body temperature regulation, it would be pretty useless to have the body react with sweat hours after a temperature change occurs.
We want feedback loops to be as fast as possible so that we can find out whats working, whats not working, and what needs to change right now.
- Change something
- Find out how it went
- Learn from it and adjust
- Rinse and repeat
Automation is a great way to achieve our feedback loop goals in software development. In addition to the agile practices above, we can also try to implement the following whenever possible:
- Continuous integration
- Increasing the frequency at which code is released
- Automated acceptance tests
- Automated code analysis
A set of tight feedback loops like these can allow us to respond to change rapidly. Every time someone checks in code, the automation can tell us immediately whether we are in a healthy state, which will allow us to immediately correct any problems if they occur.
Posted: August 23rd, 2011 | Author: benlakey | Filed under: benlakey.com | Tags: agile, software engineering | No Comments »
Hello boys and girls, it’s been a while. Let’s talk about OO design.
Have you heard of the Law of Demeter? If you develop software, you should. You may actually be familiar with its concepts without actually knowing that it had a formal name. At it’s core, the Law of Demeter is the explicit capture of the intent of encapsulation. The rules are as follows.
A method FooMethod of a class Foo should only call the methods of these:
- Foo
- An object created by FooMethod
- An object passed as an argument to FooMethod
- An object reference held as an instance variable of Foo
Uncle Bob summarizes it nicely: “In other words, talk to friends, not to strangers.”
This all sounds dandy and obvious, but it’s easy to forget and slip up when dealing with complicated designs, or designs that are poorly understood.
Happy coding.
Posted: July 18th, 2011 | Author: benlakey | Filed under: benlakey.com | Tags: abstraction, encapsulation, oo, software craftsmanship, software engineering | 1 Comment »
The title of this blog post was originally to be ‘criticism’, but This Developer’s Life already used that. I suppose it’s for the best anyhow, since the idea behind this post is to address not only criticism, but the ability to communicate as well. It stems from a discussion my wife and I had as we walked home from a screening of the extended edition of Lord of the Rings: Fellowship of the Ring last night.
Being a nerd, engineer, computer scientist, programmer, coder, web developer, or any other such title that you can lump us into, is hard. It’s not only hard because of the increasing complexities of emerging technologies. Some of the biggest difficulty for us is actually around interpersonal relationship skills. We find others to be strange, alien creatures, who we do not understand. We marvel at how easily it can come to some, but at the same time look with a perplexed eye, since we do not think as they do. Why is this? It’s because we see the world through monochrome tinted glasses; We see a world of boolean logic, in which something either is, or it isn’t. It is with this polarizing conviction that we derive our deep seated views, holy wars about technologies, and get extremely testy when confronted. Further, because the world is of course not black and white, true or false, we find middle ground to be… uncomfortable. So then what you end up with is a personality type that is not only polarized, but also critical. We are critical of those things which are not tidied, tied off, cleaned up, made parallel, and understood. It’s really a double edged sword.
So, when you confront someone with a different view from their own, and that view is firmly seated in their mind, what happens? The reaction is, perhaps surprising, perhaps not, that they actually will stick to what they know more adamantly than before. This is known in the psychology community as the ‘backfire effect‘. My wife posits that this could actually be the cause of many of the world’s serious problems, such as religious wars, government policy stance on moral issues, etc. So what is one supposed to do to attempt to pry open anothers mind? How do we do it without seeming like we’re forcing our views on theirs? We just want to crack through ever so slightly, so as to allow alternative perspectives to enter their locked mind. I’m not sure I have the answer on how to do this. Maybe you do.
Nerd psychology is a vast, complex topic. The personality of the ‘alpha geek’ is so pervasive in the industry of software engineering, that you can often times learn how to deal with many, by just basing your interactions off of one. The attitudes of “I know it all”, and “this way is best”, and “obviously this technology X is not as good as Y”, are like a poison, a poison which threatens to turn our programmers world of creation into a cesspool of bickering, snapping at one another, dismissing eachother as not intelligent, and an all around gnashing of teeth. Too often this poison presents itself, and when it does, its typically accompanied by a very unpleasant, snarky, “I’m better than you” attitude. This attitude leaks through in a very obvious way, even when it is not vocalized or intended to be communicated. We must drive this poison out, and attempt to make eachother see the world through a spectrum of colors. The value of other perspectives in software engineering cannot be overstated, and is too often a blind spot for otherwise gifted developers.
Posted: June 15th, 2011 | Author: benlakey | Filed under: benlakey.com | Tags: soft skills, software engineering | 2 Comments »
In C# when you want to have a named constant you have a choice between ‘const’ and ‘readonly’. For example:
public const string FooConst = "Bar";
public static readonly string FooReadonly = "Bar";
Which is appropriate?
Assembly Recompilation
You should only ever use ‘const’ on private fields. Using ‘const’ on a public field means that constant must be compiled into any consuming assembly. You might ask why having a constant compiled into consuming assemblies is a problem: The issue is that if you change that field, all consuming assemblies must be recompiled. Using ‘static readonly’ will not require consuming assemblies to be recompiled.
Flexibility/Mutability
Using ‘const’ is only possible with primitives, other value types, and strings, as its value is burned directly into the assembly. ‘Readonly’ on the other hand has no restrictions whatsoever, since it’s just a one time allocation of memory that has measures in place to prevent modification.
Also important to note is that ‘readonly’ only prevents the reference from being modified, not the actual memory being pointed to by the reference. To illustrate, the following is legal:
public class Foo
{
public static readonly IList<string> barReadonly = new List<string>();
public static void AppendString(string newString)
{
barReadonly.Add(newString);
}
}
Run time vs Compile time
A ‘const’ must be initialized immediately in code, and is initialized at compile time. A ‘readonly’ can be initialized at runtime, so long as it’s taken care of before the ctor exits.
Summary
In general, use ‘const’ when you know for certain that a value will never change, ever, or if the value is private. Otherwise, use ‘static readonly’.
Posted: June 5th, 2011 | Author: benlakey | Filed under: benlakey.com | Tags: .NET, C# | No Comments »
Writing good unit tests is challenging. Over time I’ve accumulated a number of principles about what to do in unit tests, as well as what not to do. This list is incomplete, but I’ll start it now.
- Test every possible code path. This means that for each ‘if’ statement, you’ll have at minimum 2 tests. Also known as code coverage.
- Write your tests first. TDD is a hard mindset to get into, but well worth it.
- If you have doubts about whether your code will do what you intend, you haven’t written enough tests.
- Your tests should never make calls to external resources such as a database, filesystem, etc.
- Every test should be self-sufficient and isolated. Your tests should not rely on other tests, or external factors. Be skeptical of setup/teardown code for a test harness class. (xUnit embraces this)
- Don’t test outside your code. There is no need to write test cases for an assembly you are dependent on.
This list will grow over time, especially if you have suggestions I might add.
Posted: June 5th, 2011 | Author: benlakey | Filed under: benlakey.com | Tags: .NET, tdd, unit tests, xunit | No Comments »
There’s a neat little utility created by Microsoft Research called IL Merge which takes multiple .NET assemblies and merges them into one. I’m not sure I have a practical use for it myself, but the availability of such a tool to do so is nice. There is also a chocolatey NuGet package available.
Posted: June 5th, 2011 | Author: benlakey | Filed under: benlakey.com | Tags: .NET, NuGet | No Comments »
Have you ever stopped to reflect at how wild C# has changed over the years? I was just dabbling around with some random code bits in my sandbox, and 4 years ago it would have been quite difficult to imagine this is how C# would look today:
internal class Program
{
private static Random random;
private static Func<char, string> munger1;
private static Func<char, string> munger2;
public static void Main(string[] args)
{
var munger =
random.Next(0, 20) % 2 == 0 ? munger1 : munger2;
string blah = munger('x');
Console.WriteLine("{0} {1}", DateTime.Now, blah);
"OneTwoThree".Select(c => munger(c))
.ToList()
.ForEach(
s =>
{
Task.Factory.StartNew(
() => Console.WriteLine("{0} {1}", DateTime.Now, s));
});
Console.ReadKey();
}
static Program()
{
random = new Random();
munger1 = (
c => { return c.ToString() + random.Next(); });
munger2 = (
c => { return c.ToString().ToUpper(); });
}
}
It’s also important to note that we seem to be on an inevitable path towards functional programming. It will be interesting to see what that shift does to the language (beyond what it already has of course).
Posted: May 13th, 2011 | Author: benlakey | Filed under: benlakey.com | Tags: C# | 1 Comment »
Can you spot why the code below is broken?
class Program
{
public enum Foo
{
Herp,
Derp
}
public class Bar<T>
{
private IDictionary<T, int> typeToNumber;
public Bar()
{
if (!typeof(T).IsEnum)
{
throw new Exception("Only enums are supported.");
}
this.typeToNumber = new Dictionary<T, int>();
var random = new Random();
foreach(var type in Enum.GetValues(typeof(T)).Cast<T>())
{
this.typeToNumber.Add(type, random.Next());
}
}
public int Lottery(T active)
{
return this.typeToNumber
.Where(keyVal => keyVal.Key == active)
.Select(keyVal => keyVal.Value)
.FirstOrDefault();
}
}
public static void Main(string[] args)
{
var bar = new Bar<Foo>();
int x = bar.Lottery(Foo.Herp);
}
}
As it turns out, in C#, you cannot check equality between generic types. This seems fairly obvious once you think about it, since there’s no garauntee that two generic types can even be compared for equality. So how do we solve this problem? One way is to provide a ‘where’ constraint on the class, to restrict the type ‘T’ to be something comparable. That doesn’t work for an Enum though.
How do we solve it for an Enum? Here’s how:
public int WorkingLottery(T active)
{
return this.typeToNumber
.Where(keyVal => EqualityComparer<T>.Default.Equals(keyVal.Key, active))
.Select(keyVal => keyVal.Value)
.FirstOrDefault();
}
Now we’re basically saying that we’re relying on T to have a default equality comparison available. This still carries with it some level of danger, since the default comparison may or may not be what you’re after in all circumstances, but it will get the job done for Enums.
Posted: May 3rd, 2011 | Author: benlakey | Filed under: benlakey.com | Tags: C#, generics, LINQ | No Comments »