This evening, a co-worker came and told me about some static he was getting for wanting to upgrade an application he was working on from .NET 1.1 to 2.0. The first thing that popped into my mind was something someone told me when I first went to work at Ciber:

My boss was this brilliant guy named Josh and we were discussing why I should upgrade to XP (this was 2002.) I was against it. Windows 2000 Server worked great. I could create multiple web sites in IIS 5.0. I could do this, do that, it was more stable, faster, etc.

Then we went back to my desk and he showed me something like this:

He didn't have to follow the visual with, "So...you like having that many patches applied to your computer?", but he did.

General purpose computer software generally improves over time. You can take the improvements in the form of a bunch of little Band-Aid patches that you might not have applied right, or in the form of an upgrade. With an upgrade you run the risk of having to deal with an unexpected change.

But let's face it: you were going to have to deal with that change eventually anyway, unless you don't plan on sticking around very long. Taking the upgrade, finding what's broken, is inevitable.


 
Categories: bs

July 18, 2007
@ 06:48 AM
  1. Oct. 25, 1978: First pet goldfish died. Realized living things die. Cried for weeks.
  2. Dec. 25, 1980: Opened gift from "Santa" that I had seen in parent's closet. Realized Santa is a lie. 
  3. July 16, 2007: Couldn't get this code to compile:

  ...realized that System.Windows.DependencyProperty and System.Workflow.ComponentModel.DependencyProperty are two entirely different classes. Only System.Windows.DependencyProperty, or more precisely System.Windows.PropertyMetadata supports the nifty CoerceValue callback.

I wonder why we have two separate families of DependencyProperty related stuff? Seems really weird and poorly thought out. Kind of "Hack"-ish.

What really hurts is that there doesn't seem to be a good way to coerce custom type dependency properties in WF-land. The answer is right there in WPF's PropertyMetadata, but we can't use it in WF.

The thing I was really trying to do was have a generic iterator-like activity that contained custom activities with custom type dependency properties. Like a ForEach activity that contained a custom Activity like "LoadPortfolio" with a Dependency Property called "Client" that was a custom type. The ForEach has a DataItem property it sets to the current item it is iterating in the context of each child, but because ForEach is general purpose, the type of DataItem is System.Object.

It would be easy to coerce DataItem to "Client" (just cast or use "as"!) but there doesn't seem to be a mechanism to do this in WF, and because of the type mismatch, my workflow can't even load.

So do I make a special ForEach for each type I want to iterate over? Do I change the Client property on my LoadPortfolio activity to type System.Object?

Hopefully I'll find a way to work around this that I can live with soon.


 
Categories: wf | wpf

I like to code as little as possible.

I am not referring to how much time I spend coding, but more how terse and compact ("neat") the code is. If it's growing hairs trim them. If it's more than one complete thought, extract method.

One thing that's been causing me to grit my teeth a lot lately seems to be caused whenever I hear the term, "error handling," usually like, "look at that code! it's crap! There's no error handling!" where, in my opinion, error handling has no business being. It hurts even more when the person is someone I respect and otherwise agree with on all matters technical.

Extraneous error handling seems to me to be one the fastest ways for code to go from simple and clean:

to stressed out and hairy:

For a long time, when I first started learning .NET, I had this C++/COM baggage I brought with me, where I thought HRESULTs and IErrorInfo was the right way to do error handling. I had brief experience working with java and remember being shocked at how some java programmers thought the ratio of "catch" to other keywords in their programs should be approaching 1:1. I had concluded that "try" was bad, and .NET was worse off because of it.

Then I read what the P&P Team thought about the exceptions and breathed a sigh of relief. I had my strategy:

Exception Propagation

There are three main ways to propagate exceptions:

  • Let the exception propagate automatically

    With this approach, you do nothing and deliberately ignore the exception. This causes the control to move immediately from the current code block up the call stack until a catch block with a filter that matches the exception type is found.

...

(emphasis mine)

This is how I think 99% of code should handle exception, just as it's how I think 99% or bystanders should handle high speed car chases. Don't do anything! Let someone else who knows what they are doing handle it.

For this to work, you often need to alter other bad habits as well, such as instead of "try { DoSomethingToFileThatMightNotExist(fileName); } catch (FileNotFoundException) { /* ignore */ }" say "if (File.Exists(fileName)) DoSomethingToFileThatMightNotExist(fileName); }".

This also helps with debugging. Who likes it when you turn on "Stop when exception is thrown" in the debugger only to find there are a gazillion exceptions you don't care about being caught by code that ignores them?

All this leads me to see "try" as a code smell. I look extra hard at code with "try" and even harder at code with "catch". If I can, I refactor them away as quickly as I can.

Ideally, a user facing program should have only one place where errors are handled: the place where it decides how much to show to the user and how much to report to you via some other channel.

This helps me keep my code small, neat, and clean.


 
Categories: debugging | design | refactoring

See this.

I love "The Premature Optimizer":

Never use String.IsNullOrEmpty! Didn't you know that there's a huge bug in the Framework that makes that function kill kittens if you call it on a multi-proc system with more than 4.5 gigs of RAM? Plus, it adds five microseconds of overhead as it accesses eax twice necessitating 4 extra clock cycles. Measure it? Should I have to, it's SO obvious that's inefficient!

When I write code, especially when alone, I imagine I am having a conversation with someone and trying to explain what I want the computer to do through code. It's like pair programming with an imaginary friend I call, "Future-Guy-That-Has-To-Maintain-This-Code." Not as good as real pair-programming, but whatever. 

When I read this, I remember thinking, "Crap! I've been saying String.IsNullOrEmpty is the bomb for a long time now, because it's so obvious and self-explanatory...now I am going to have to stop using it and explain why every freaking time! This sucks!" I recovered, but I think my imaginary pair-buddy that day must have been "The Premature Optimizer."

As to the labels/stereotypes thing: I think a better name for this would be "anti-pattern." These are all examples of people I _wouldn't_ want to work with, not personality types I hope the Visual Studio team wastes valuable time catering to, unless it's in the form of a cure or some kind of corrective treatment.


 
Categories:

July 1, 2007
@ 05:26 AM

I just got back from a training session with Pluralsight in LA. It was a really great program and I learned a lot. I have 47 pages of notes from 5 days of training, which is very high for me (I'm not really a note person, but there was just too much information in this course for me to stream straight to memory.)

If you are interested in WF and/or WCF and just haven't had the time to just sit down and plow through everything, this course is the bomb. Aaron and Matt did a great job getting us through the material and answering all our questions. I would recommend this course to anyone.


 
Categories: