Friday, November 30, 2007

Code Documentation

At work I've worked with a lot of people who are either just out of College or still in College. There has been an interesting trend in their code's documentation: they like a lot of it.

I'm guessing that they were taught that code had to have comments and they were probably deducted points if they didn't have any. However, they weren't deducted points if they wrote bad comments and they weren't granted points if they wrote good comments. My guess is no one ever told them what the difference between a good comment and a bad comment was. So usually one of the first things I try to teach is what my guidelines for comments are.
  1. Meta data is a bad substitute for good readable code
  2. Write future proof comments. Don't write a summary comment that says what each step of your method will be. This is guaranteed to be out of date when someone else changes your method's code and forgets to update the comment. Now your comment is a lie.
  3. Tell me what your methods, properties, or objects will accomplish for me. Don't tell me how to use them. I can determine how best to use it once I understand what it does.
  4. Only current code matters, what the code did in the past is not important. Don't document history in your code files.
  5. Add line comments if the line is confusing or needs clarification. If it's clear on it's own, don't clutter it up with a comment.
  6. Break code into methods instead of using large or intricate commented sections.
  7. The shorter the better
Two things drive all these guidelines:
  1. The goal is readable code
  2. Its better to read code than to read meta data
If your code isn't readable, you're going to be afraid to read it, and that's a problem because its better to read code than to read meta data (and comments are just meta data). Why? The meta data may be out of date, or it may not accurately represent the code. In the end, it doesn't matter what you think the code does, it matters what the code actually does. The best way to determine what it actually does? Read it. That doesn't mean you can get rid of all meta data, because you can't. But you can be very careful with what meta data you create and what content it contains.

The main purpose of summary comments is to clarify what code is meant to accomplish when the name may not be sufficiently self explanatory. This will help people (including you) figure out how they should use that code. If they want to really understand what it does, they'll have to read it, but if the summary and name are written well enough they should understand enough to take advantage of its functionality.

The main purpose of line comments is to clarify code that may be harder to understand for some reason. This could be to describe why something is necessary (like a hack). Or to explain the effect a line will have on a line somewhere else (like to cause a loop to break).

There are cases where you may need to not follow these guidelines, that's why they're guidelines. However, in most cases they've served me well and helped me produce cleaner and more easily understood code.

Tuesday, November 27, 2007

IEnumerable, not just for simple collections

In C# IEnumerable is what lets you say foreach( string s in someListOfStrings ) {}
In C# 2.0 you can create objects that can be enumerated over very easily using the very Ruby-like "yield return" keyword. Here's a dumb example:

private List strings;
public IEnumerable Strings
if ( strings == null ) yield break;
foreach( string s in strings )
yield return s;

The compiler will take care of all the magic of managing the state of your loops or recursion or whatever.

Pretend that the code above was in a class called ExampleStrings. I could write this code:
foreach( string s in exampleStrings.Strings ) {}

Like I said, that was a dumb example, but now you've seen an example of how easy it is to make something Enumerable. And because of how easy it is, I'm a big IEnumerable fan. I've found two cases where I really like to use it:
  • When a library needs to return a bunch of "stuff" but doesn't know exactly how the consumer wants to use it
  • When some non-trivial work needs to be performed to determine what the next element to be returned should be
Take the first one first. Suppose you're writing a library which needs to return the name of all the scanners attached to the computer. You could write this to return a List, but what if the consumer needs a DataTable? You'll build your list and return it, then the consumer will loop through your list and build a DataTable. If you return IEnumerable instead of List you make this O(n) instead of O(2n). You also delay whatever calls need to be made to find out what scanners are connected to when you actually start looping through them. That's because your IEnumerable code doesn't execute when the property is referenced. So in the following code a break point placed in the get of our Strings property wouldn't hit until the last line:
IEnumerable strings = exampleStrings.Strings;
if ( strings == null ) return;
List l = new List( strings );

So maybe O(n) vs O(2n) isn't that big of a deal. And the fact that you don't have to create a List object isn't too huge either. Its still nicer, cleaner, and totally easy to do though, so why not do it?

As usual, its the second bullet that really makes taking a look at IEnumerable worth while. I've used this pattern in two actual projects too. One I referenced in an early post, Fun With Circles. The other I've used when I was manually performing some data paging.

In fun with circles I used IEnumerable to abstract away the calculation that determined the Point where the next dot in my circle should go. That way I completely separated my drawing code from the math to determine where to draw.

In the data paging example I created an IEnumerable DataFetcher. All the consumer had to do was tell the DataFetcher where to start and what direction to go in (start, end, specific record ID and forward or backward) and then simply foreach through the resulting rows. When the consumer had enough rows to fill its page, it would simply break out of the loop. If the data source ran out of data first, then the loop would end on its own. With this in place the consumer was completely isolated from when the data was being retrieved and how it was being "stitched" together. This also made it incredibly easy to add new data fetching behavior to the DataFetcher class as needed. Then by simply setting a property on the class you could change its underlying behavior without the consumer updating any other lines of code.

Of course, IEnumerable isn't required for any of this. You can accomplish the same thing with a GetNext() method. IEnumerable just adds some very nice syntactic sugar to both the consumer's code and the source's code.

Monday, November 26, 2007

Windows PowerShell

If you haven't heard of PowerShell, its a windows command line shell which uses .NET objects for everything, and I'm a fan.

For example, in cmd or bash or whatever, when you type dir or ls you get a text display of a directory's contents. The command outputs formated text. In PowerShell if you type dir you get System.IO.DirectoryInfo and System.IO.FileInfo objects. That's right .NET objects. By default, those types get displayed to the screen in a table format. Wanna change how the output is formated? Pipe it to one of the format commands: dir | format-wide

There are three incredibly cool things here:
  • The command outputs .NET objects
  • The display is independent of the command
  • The pipe command inputs .NET objects from one command to another
This is leaps and bounds better than any other command line shell I've ever used. You don't have to do a bunch of text manipulation to get at the information you want, just call the property. Or call a method. If it's .NET you can do it. And that means you can use your own .NET objects from the command line too. Also, you don't have to learn the formating behavior of many different commands. They're all consistent because they all output .NET objects which are formated with the three format-* commands.

If you've spent much time with a command line you should be starting to see how powerful this is. Here's an actual example. I needed to find out what file extensions people were putting into the document management application here at work. My first thought was to write a Ruby script that would iterate through all the files under a given directory (including subdirectories) and add the extension to an array (if it wasn't already added), then display the array to the command line. Pretty simple script.

Then I thought, I bet I could use PowerShell do this.
dir -recurse | select-object extension -unique

select-object is a command that pulls out a given property from an object. dir | select-object extension will show you the extension for every file in the current directory. Adding the -unique flag will remove duplicate extensions, showing you each extension exactly once.

I wont turn this into a PowerShell tutorial, for that you can refer to Scott Hanselman on PowerShell or just download it and read the documentation it comes with, which is actually quite good. Then start diving into the help, which is also quite good.

Tuesday, November 20, 2007

Personification in Software Design

When you're in a design meeting and people are throwing ideas around it's easy to get confused. People have this funny habit of not fully specifying their subjects. For example, "It wont store versions." What is "it"? The website? The application?

This really does happen all the time, it doesn't matter who you're talking to. Its really hard to avoid. When you're the one talking, you have a mental picture in your head. You're just trying to convert that to words so other people will see it too. But the people you're talking to don't have the same mental picture, so "it" could mean something completely different to them.

You're really trying to shape their mental picture to match yours while continuously updating yours to reflect theirs, so you have to be very specific until you can settle on some common terminology to represent that picture.

I like to use Personification to make this go smoother.
the attribution of a personal nature or character to inanimate objects or abstract notions, esp. as a rhetorical figure

I like to take this one step further and make the people I'm talking to represent the various components of the system. Person A is the database, person B is the website, person C is the application, and I'm the Document Management system. I've found that this works really well. Now I can say "You wont store versions, but I will" instead of "The website wont store versions, but the Document Management system in the application will."

Not only does this make the sentence shorter but it makes it easier for our mental models to jive and its funny. "Maybe you wouldn't have performance problems if you weren't written in Javascript!" See?

Monday, November 19, 2007

Keyboard follow-up

In Tools of the Trade: Keyboard I talked about the importance of keyboards as well as some of the models I was looking into.

Shortly after, I ventured out into the wild world of consumerism where I visited Micro Center, Circuit City, and Best Buy trying out the various keyboards. I decided to start with the Microsoft Natural Ergonomic Keyboard 4000. Turns out, that's where I'm going to end too. This is a fantastic keyboard.

It has one flaw: the space bar. If you push the space bar near the top, it gets kind of stuck. It's also the only key that's loud and "clack-y." I was able to get used to it, but it is less than ideal.

I was willing to get used to it because this keyboard has a lot going for it. Its most distinguishing feature is that it is raised from the back and slants down away from you. This is in contrast to most models which have feet in the back causing them to slant down toward you. Having it slant away is actually a lot more comfortable. I find that I rest the back of my hands on the wrist pad and allow my fingers to dangle down onto the keys. This seems to keep some of the stress off my wrists.

I also love the touch and spacing of the keys. They require more pressure and travel distance than some keyboards today, but not enough to make it annoying. Its a good balance.

I bought it from Micro Center. They sold me an OEM model that came in a simple brown unmarked box for half what Best Buy and Circuit City had it for.

Thursday, November 15, 2007

Do It And Report Back

Object Oriented programming is simultaneously easy and hard. It's easy because when done right things have a way of just falling into place. It's hard because it can be difficult to know if you're doing it right until things don't fall into place...

This is a pattern I run into all the time: I want to write a class which will perform some routine. The routine will consist of many steps which have to follow a certain work flow. By putting all this behind a method call I can abstract the details of the work flow and how the steps are done. However, after all is said and done, I need to know what happened. When the method is simple this can often just be a single return value, GetString() returns a string. If it returns null, there was no string to get. But when your method has many steps to perform this can get more complicated. It may need to return different information depending on what happened. I need the method to report back more than just a single value, I need a status report.

Let's look at an example. Suppose you're given a file path and you want to "scrub" it. Pretend you want to make sure the file type is not on some list of "excluded" file types. Then, if it's a shortcut you want to resolve to the target path. If it's a folder you want to expand the folder into all its files. There is some non-trivial work to be done here and it could be used in multiple locations, so it would be nice to abstract the whole process into a single call.

If we do this it could report back with:
  • File okay (file path)
  • File excluded (file path, file type)
  • Shortcut resolved (shortcut path, target path)
  • Folder expanded (list of file paths, list of excluded files)
Here is how I've been coding this sort of thing (in C#):
public enum ScrubResultType
FileOkay, FileExcluded, ShortcutResolved, FolderExpanded

public abstract class ScrubResult
public ScrubResultType Type
if ( this is ScrubFileOkay )
return ScrubResultType.FileOkay;
else if ( this is ScrubFileExcluded )
return ScrubResultType.FileExcluded;
else if ( this is ScrubShortcutResolved )
return ScrubResultType.ShortcutResolved;

public abstract bool IsError { get; }

public class ScrubFileOkay : ScrubResult
public string FilePath;
public override bool IsError { get { return false; } }

public class ScrubFileExcluded : ScrubResult
public string FilePath;
public string FileType;
public override bool IsError { get { return true; } }

public class ScrubShortcutResolved : ScrubResult
public string ShortcutPath;
public string TargetPath;
public override bool IsError { get { return false; } }

public class ScrubFolderExpanded : ScrubResult
public string[] ExpandedPaths;
public string[] ExcludedFiles;
public string FolderPath;
public override bool IsError { get { return false; } }

I've defined an enumeration which contains all the possible "return types." Then because each return type might need to carry back different information I've used polymorphism to create a class for each possible return type. With a system like this in place I can write code as follows:

ScrubResult sr = FileScrubber.Scrub( "..." );
if ( sr.IsError )
if ( sr.Type == ScrubResultType.FileExcluded )
ScrubFileExcluded sfe = (ScrubFileExcluded)sr;
String.Format( "File {0} of type {1} is excluded",
sfe.FilePath, sfe.FileType ) );
// handle result based on type

This is an actual example of something I was seriously considering doing. I ended up deciding that the User implications of such a situation were scary enough to not warrant adding this. At least not for now.

When the return types don't have different information to carry back then the different classes aren't required and a single class with a "Type" property that returns an enumeration value is good enough. I have used the simpler version in code.

I like this pattern, but I've never really seen it anywhere. Have you seen it? Do you like it? Have you solved the same problem in a different way?

Wednesday, November 14, 2007

Happy Viming

In Programming Meets Editing I mentioned that my favorite editor is gVim, and that I was considering buying ViEmu so I could use the Vim input model inside Visual Studio. Today I finally got myself in gear and bought ViEmu and installed it at work.

ViEmu shoutout: Its impressive. It can't be easy to make Visual Studio play well with the Vim input model, but ViEmu manages it flawlessly. It even has a pretty smart method of managing Visual Studio's keybindings. If you want to go in and out of "ViEmu mode" it will disable and enable conflicting keybindings for you.

If you've ever been interested in learning Vim, the ViEmu developer Jon has created some really nice "graphical cheat sheets" that make learning Vim quite a bit easier. He has also written some good articles on why Vim is so nice: "Why, oh WHY..." and "The Vi input model". Those articles will sum it up better than I can, so I recommend you check them out if you're at all interested.

But that's not going to stop me from throwing in my own 2 cents. What makes Vim great?
  • It is comfortable to use
  • It lets you say what you want to do
Its comfortable because your fingers hardly ever have to leave the home row. Just the fact that you can move the cursor around with out moving your hand over to the arrow keys becomes really nice. I'm serious! It seems like such a minor thing, but after you've used it that way for awhile, going back will annoy you. Its like when you have a badly designed UI where you have to type in a text box, then move the mouse to select the next box, then type more, then move the mouse, then type more, etc.

Another example is the "t" and "f" keys which are like mini searches. "t" means to and "f" means find. Type "fa" and it will move your cursor to the next occurrence of the letter a on the current line. "ta" will move your cursor to right before the next occurrence. "T" and "F" go backwards. Again this is nice because it replaces a string of keyboard actions that might look like "ctl+right,ctl+right,right,right,right" Not only is that simply more keystrokes, it also requires you to move your hands around and perform some control key acrobatics.

Both of these examples demonstrate how Vim is comfortable. The second also demonstrates how it lets me say what I mean. Instead of using a combination of meaningless movement keys to get to the letter a, I said "go to a." At first blush this doesn't seem like it would matter, but as the Vim commands become second nature you can start talking to your editor at a much higher level without thinking about it.

It lets you stay focused on what you're trying to do to the text and not how to do it.

Its important to note that these are just the simplest examples I could think of. Vim has A LOT more to offer. Its also important to answer this question: will it make you more productive? Maybe, I don't know, its hard to say. Does it matter? If it makes you more comfortable and less irritated (ctl+right,ctl+right,ctl+right,ctl+right,ctl+right...), isn't that good enough? After all, I'm going to guess you spend a lot of time typing into that editor of yours.

Finally, if you're interested in giving Vim a shot I would certainly encourage it. It does have a pretty steep learning curve, but the cool thing is you can still do all the "notepad" style editing things you're used to. So you can learn it at whatever pace you want to, one feature at a time. If you're in Visual Studio, ViEmu has a 30 day trial. If you're in Eclipse, there is a Vi plugin. And if you're just editing text there's always gVim.

Monday, November 12, 2007

To Estimate or Not To Estimate

I have recently been spending a lot of time with two different "project management" applications: FogBugz and Team Foundation Server. FogBugz originally attracted my attention because I read Joel Spolsky's blog, Joel on Software, and he's the CEO of Fog Creek Software which makes FogBugz. TFS attracted my attention because it includes a new Source Control system which is a-w-a-y better than Visual Source Safe. I have been evaluating these products and trying to figure out which I'd rather use, its a harder task than it sounds.

The new version of FogBugz, 6.0, mainly consists of Evidence Based Scheduling. I have to be totally honest and say that EBS is not only very cool but makes total sense and I believe it would totally work. However it requires two things: 1) time tracking and 2) work item estimates.

Joel Spolsky recommends keeping your estimates under 16 hours, anything longer than that doesn't stand a chance of being accurate. That means you need a lot of very detailed tasks entered in the system (ex: develop function foo). Once you have estimates at this level you can start to get good predictions of when you'll ship AND you can start to pick and choose what tasks you want to do based on how much time you have left.

TFS doesn't really have any scheduling. It has Remaining Work and Completed Work fields (but only on the Task work item type, not on the Bug work item type...), but no reporting, no nice views, and no nice way to enter time (you have to subtract from the remaining work field manually when you add Completed Work...). The TFS developers seem unconvinced that estimating work at the level Joel recommends is at all worth while. Witness these articles on the Teams WIT Tools blog.

Personally I think estimating how long a task will take is a great idea. I think creating a list of tasks at that detailed level would not only help a developer think through what they're going to do before they dive into it but also help them get an idea of "where they're at" with all their work. I think it would make managing work loads a lot easier too. Not to mention the fact that the ship date estimates would make it possible for you to determine when your initial "blind" estimates were wrong or when scope creep is starting to get the best of you.

My question for all of you is, what do you do at your work? It doesn't even have to be programming work. Do you estimate work? At the detailed task level, or at a more abstract level? Is it helpful? And if you don't estimate work, do you wish you did?

UPDATE: I've posted a follow up post, Managing Projects

Wednesday, November 7, 2007

Use that computer!

If you're like me, you don't like Windows XP's start menu. You might like the pinning and the recently used programs section, but you despise the popout hierarchical menus. You also dislike the desktop, and find it more or less useless, much like Coding Horror says. I also wouldn't be surprised to hear that you really don't like the task bar, and find it so cluttered that you obsessively open and close all your windows all day long so that you never have more than 3 or 4 open at the same time.

This is where you may start to be a little less like me. I have searched for alternative UIs for launching programs and managing currently open programs for years. The list of things I have tried includes: Ashton Shell Replacement (win), KDE (linux), GNOME (linux), Enlightenment (linux), IceWM (linux), Xfce (linux), Fluxbox (linux), Symphony OS (linux), Rocket dock (win), Top Desk (win). At some point or another, for some reason or another, I gave up on all of those.

Here's my current setup: Launchy for launching programs and Task Switch XP for switching between running programs.


Task Switch XP:

Launchy runs in the background and is called forward with a configurable keyboard shortcut. I bind mine to alt + q. To use it you just type the name of whatever program you want to run. If that program is buried somewhere in your start menu, launchy will find it. The best part about launchy is that it learns. So if you have 4 programs that start with the letter "f," the first time you type f you'll see all 4 programs in the drop down. If you go ahead and type more letters so that it narrows the selection, "fire", it will select firefox and you can hit enter to launch the program. Next time you type "f", firefox will be the default suggestion.

Mine has trained itself so that this is all I need to type now:
f -> firefox
th -> thunderbird
v -> visual studio
wo -> microsoft word
ie -> internet explorer
sq -> sql management studio
gv -> gvim
cmd -> command line
not -> notepad
tom -> tomboy

The best part of that is that you're not memorizing some weird keyboard shortcut, you're just typing the name of the program you want, and boom, it figures out what you mean before you've even finished typing the full name.

Task Switch XP binds itself to alt + tab by default. It displays your running programs in a vertical list (must nicer than the horizontal list of the task bar) and includes screenshots of each program (much like tweak UI). However, where Task Switch XP sets itself apart is its "sticky" mode (in the configuration utility go to Hotkeys and check "Enable Alt-Tab 'sticky' mode"). With this turned on the window wont close when you release the "alt" key. This means you can call the window forward with alt + tab, then use the arrow keys, or the up/down keys, or the mouse, or the scroll wheel to select the program you want. I even have a button on my mouse configured to bring the dialog forward so I can switch windows without even using the keyboard. This is great because this dialog can support many more open windows before it starts to become cluttered than the Task Bar can.

So Launchy replaces the start menu and Task Switch XP replaces the task bar... As such, I've now configured my task bar to auto-hide.

The only thing I don't have here is the ability to type the name of a currently running program in Task Switch XP and have it filter down the list for me. I'd love to be able to do: "alt+tab fire" and have only firefox windows in the list, but Task Switch XP doesn't have this feature. I have written a program that will do this, but I haven't finished making it pretty yet. Alternatively, I may pull down the Task Switch XP source code and see if I could add the feature I want to it.

Do you use any interesting application management utilities?

Monday, November 5, 2007

Programming meets Editing

Editing text is a significant part of programming. Sure, you spend a lot of time thinking, and a lot of time scribbling on paper and white boards. But you do a ton of editing as well. The only way you can get out of editing is by getting out of programming.

It is interesting that, though editing is such a large part of programming, it is relatively ignored. In my Tools of the Trade: Keyboard post I pointed out that having a comfortable keyboard seems like it should be important given how much typing a programmer does. Along those same lines, it seems like having a good editor should be just as important, if not more so.

I think there are two kinds of programmers, those who have a favorite editor, and those who have never bothered to think about it. Most of the best programmers I know have spent a fair amount of time experimenting with different editors. As usual, wasting time messing with editors doesn't make you a good programmer, and I've known some extremely good programmers who never thought twice about it. On the other hand, generally the people who take the time to think about things like text editors are also the people who think about things like writing good code. I even think that would be a good interview question, "Do you have a favorite text editor?" You could learn a surprising amount about a person's background and actual coding experience through that question.

My favorite editor is Vim, gVim actually. I started editing in the Quick C DOS editor. Then later I used the Zeus editor. Then I stumbled on Vim. And of course, Visual Studio. I had friends in school who used UltraEdit, and recently I've read a lot of hype around Text Mate and the windows clone, E Text Editor. I have never personally used Emacs. I took some time to read about it not long ago, but I've never gone so far as to install it and spend time with it. I tried jEdit for a short period of time, but gave up on it because it took too long to start up.

In the search for an editor I find myself trying to figure out exactly what it is I'm looking for. What makes a good text editor. I think these factors are part of it:
  • Expressivity
    How much can I say and how well can I say it? Ultimately I want to be able to express at a high level what I want to have happen to the text.
  • Composability
    Are there a series of flexible commands which can be combined to perform more complicated operations?
  • Psychic ability
    Does the editor know what I'm doing and help me do it by abstracting out the tedious details? For example, Intellisense, snippets, and auto word completion.
  • Comfort
    Can I type commands easily, or am I performing acrobatic arts with my fingers on the keyboard?
  • Speed
    Is it faster than editing in Notepad?
  • Keeps me oriented
    Keeps me from getting lost in my files and directories
Interestingly these really divide into two categories, you have the strictly text manipulation issues such as speed, comfort, and expressivity. Then you have the more "management" and domain specific issues such as psychic ability and keeping you oriented. Vim is very good at the text manipulation parts, but weak in the management parts. Visual Studio on the other hand is very strong in the management parts.

Visual Studio with Intellisense and re-sharper's background compilation really is wonderful. Add the solution explorer to that and life is pretty good. I wouldn't use an editor that didn't have those features knowing that they exist in Visual Studio. Thus at work I use Visual Studio and not gVim.

Because of this I think I'm going to spring for a ViEmu license. I've used it for the trial period twice now, once on my old computer, once on my new computer. Each time I love having it, but its pricey so I haven't committed yet.

What editor do you use? What editor do you wish you could use?

Friday, November 2, 2007

The Fear of Doing

For a long time I suffered from the relatively common ailment of "The Fear of Doing." The symptoms can vary dramatically and change over time, but the root cause is the same.

I would come up with an idea, maybe for a piece of software, and I would design it and all its abstract elements. I would get right up to the point where I needed to write some code, or research a technology, or look up an api. Then I would stop.

Or, other times, I would be annoyed by something. Maybe something about Windows, like how hard it is to switch between windows, or how hard it is to start a program. Or it could be something in Visual Studio, like how the shortcut keys aren't setup right, or how there's no good way to find a file in a solution. In these cases I would complain about how annoying it all is, and grudgingly go back to dealing with it.

Or, on a few other occasions, I would be interested in something. Like what mechanisms .NET has for parsing XML. Or how the Ruby language differs from the C based languages. Or if one keyboard might be more comfortable to type on than another. When my interest would peak in these cases I would think to myself, "That would be interesting to learn," and then I would go watch TV.

Or, in exceptional circumstances, I might even wonder about things that don't have anything to do with computers or programming! It does happen every now and then. But I'd usually end up leaving my activities at wonderment.

In all of these cases I was willing to think about, or be interested in, or wonder about things right up until the point when I would actually be required to go learn something. Actually, these are bad examples because these are, in reality, examples of things I did actually go learn something about. But not surprisingly, all the stuff I may have thought about but not bothered to learn about... I can't remember anymore, so I couldn't use them as examples.

I should mention early on that thinking about stuff and not "going and learning" isn't necessarily bad. In fact, its quite a bit better than thinking about nothing. Especially because you may very well learn stuff in the process of thinking. Truth be told, some of the best learning occurs when you learn from yourself rather then by "going and learning." However, there are a few things that simply can't be learned that way. And there are many other things that wont be learned that way efficiently.

That being said, there is only so much you can learn by just abstractly thinking about things. Eventually you just have to do something. However, it can be hard to convince yourself that its worth the time it will take to do something. You can always come up with reasons why you shouldn't do something: you might fail, you might get half way through and lose interest, you might start only to find out someone else beat you to the punch and has already done it, it might turn out to be a bad idea, you might finish it and then never use it... The list goes on.

I call this "The Fear of Doing." For me, I credit a project I called BoxVue as one of the first times I got over this. BoxVue was a Konfabulator, I mean Yahoo Widgets, widget that allowed you to organize programs, files, directories, shortcuts, or whatever into groups. Then you could click on the items in the groups, or use the search capability to launch the item with the keyboard. Basically, it was my version of the Windows start menu without the hierarchical pop up menus and with a convenient search. I wrote it because I'd never liked the start menu, never found a nice replacement app, and I was very interested in Konfabulator's programming model (which is a combination of declarative XML and Javascript). I spent quite a while in Photoshop creating the graphics and gVim looking at other widget's code and writing Javascript. I ended up with a product I was quite happy with and I used it for about a month. Then I discovered the Gnome Main Menu in SLED 10 and learned that XP's "pin to start menu" feature was actually pretty nice (I had always turned off the XP start menu and used the old style one) and I completely stopped using BoxVue.

This was one of the first times I'd actually taken the time to learn a new technology and develop a full application with it. And it resulted in failure, more or less. You would think this would only have reinforced my "Fear of Doing," but instead it set me straight. Although I no longer use BoxVue, I learned a ton of stuff from writing it that I do use today. First of all, I learned Javascript is a real language, and an awesome one at that, and I now understand what a "prototype" language is. I also got some decent exposure to a declarative UI style of programming. Shortly after I finished BoxVue, Microsoft starting talking about WPF and Xaml, which we have been looking into at work and which is a declarative UI style of programming, so that was a nice leg up.

Ever since then, every time I've taken the time to do something, its always benefited me later in more ways than I could have predicted before I started. Always.

So what I learned is, even if the "project" fails, the time I invest is totally worth it because it helps me get smarter and get more things done.