So we found a problem recently with a certain scripting language’s argument parsing:


function Test-Argument($a) {
   $a.GetType().FullName
}

[Test 1]: Test-Argument 4
System.Int32
[Test 2]: Test-Argument .5
System.Double
[Test 3]: Test-Argument "hello"
System.String
[Test 4]: Test-Argument Goodbye
System.String
[Test 5]: Test-Argument -42
System.String
[Test 6]: Test-Argument (-42)
System.Int32
 

Why can’t it properly parse -42 as an integer, when it can parse .5 as a double? Well, according to the development team of a certain Fortune 100 company, this behavior is by-design ... Apparently, “.” can be a number, but “-” can’t.

When you know you’ve got it all wrong, but you can’t be bothered to get it right, document it — make it look intentional, and most people won’t question you.

I’m sorry folks, but I’ve had it up to here with the “it’s by design” excuse. I don’t care who you are, and I don’t care who wrote the design spec — when something is as obviously wrong as this, you need to fix it, not just give us platitudes.

I had the same thing happen recently with a bug I filed about the way wildcard behavior impedes matching file-names with square brackets in them in PowerShell. They told me this was by design, and that I could use the -LiteralPath parameter. Well, if any of you have tried this, you already know what I’m going to say: it’s broken.


## This works if the file already exists
## But fails completely if it doesn't exist
set-content -LiteralPath "logs [www.example.com].txt" -Value " help "
 

And yet, I was initially told it was supposed to be this way. Now, in this case, I happened to have the email address of the software architect, and they’ve reopened my bug after I sent him an email with lots of examples of how this bug defied the behavior that a user expects.

We software developers need to be very careful about saying “that’s by design” ... because it sometimes makes us sound stupid. When a user says “this is broken,” and your reply is “that’s by design,” what the user hears is “we broke it on purpose.” We should not be willing to excuse bad design.

Listen up: If you want to be a successful software developer, you need to learn this, and learn it well: the fact that it was DESIGNED WRONG is NOT AN EXCUSE for shipping broken software. Regardless of whether it’s your design, or someone else’s, even if it was designed this way by your manager’s boss. When you create software that doesn’t behave the way the user expects it to, you need to consider the possibility that you’re doing it wrong.

Imagine if architectural engineers were to behave in a similar manner … Suppose the original architect of the golden gate bridge had left a gap in the middle of the bridge, with a little ramp: you could drive up the bridge, but you couldn’t get across unless you were comfortable jumping your car across a four foot opening.

When you complained about it, the engineers would say: it’s by design — if you don’t like jumping your car (and yes, we know that jumping is bad for maintainability), there is a workaround: just wait for the ferry we put in last year. There are several boats, running continuously, so the wait is at maximum about 20 minutes, and it only takes a little longer to cross by boat than it would on the bridge.

That analogy is obviously not perfect, but the point is: just because someone decided it should be done a certain way doesn’t mean that’s the right thing to do — sometimes the design is just wrong. Perhaps the designer and architects overlooked something, or perhaps the circumstances have changed, but in any case, if the software doesn’t work the way people expect it to work, or requires different workarounds depending on the situation … you need to question the design.

All I’m asking is this: don’t turn your brain off: when someone complains about the way something works (or doesn’t work), think about what they’re asking, and if the complaint makes sense, don’t say “this misbehavior is by design” until you’ve reconsidered the design.

4 Responses to “Rage Against the Design”

  • Paul says:

    What’s worse is I’m assuming the reason they don’t parse the – as an operator is because the dash can denote a parameter. But even that doesn’t work!

    PS > function test-numericparam ($42) { “$42” }
    PS > test-numericparam -42
    -42
    PS > test-numericparam -42 Foo
    -42

  • Roman Kuzmin says:

    Thank you for posting this, I do agree with everything you say. I wish more people criticize PowerShell design or whatever they call design. I love PowerShell very much because other alternatives are even worse. Other alternatives do not fit to .NET well enough for what I do. Fortunately .NET is not developed by The Team.

    There are too many exclamation signs everywhere about PowerShell. The technology itself is awesome, but implementation quality and responsibility for what is done is low too often. Meantime one has to be a rocket scientist to able to use this shell for file system or registry operations. I am talking about real jobs, not trivial demos that work sometimes.

    Thanks,
    Roman Kuzmin

    • Well, let’s be clear, I don’t actually think PowerShell is actually bad — and this isn’t meant to be a criticism of just the PowerShell team.

      When developers claim that bugs are intentional I think it lowers people’s respect for them, and for all software developers, and lowers expectations for software (which is saying something). How about if I put it this way: it’s one thing to say “we could not find a way to make that case work and still handle everything else we need to handle,” or even: “we didn’t have time to finish that yet, and we’ve prioritized other things” ... but it’s another thing to say “we meant to do that.”

      Declaring something to be “by design” sounds like “we meant to do that” and we really need to avoid it unless we can provide an explanation that will convince the user that our design is better than what they are asking for.

  • Why don’t you tell us how you really feel? :)

    I agree with the fact that the “by design” excuse is abused. However, because loose typing is often the cause of many frustrating bugs, and because typing the argument as Int32 does work as intended, I’d say the issue isn’t that bad. The bottom line is, when you don’t specify types, life is like a box of chocolates…you never know what you’re gonna git.