Use of dynamic causes trust issues between developer and compiler according to anonymous blogger

22 10 2012

I do most of my work in C++ and have a bit of an abusive relationship with my compiler. It yells long error messages at me at the slightest  provocation and I do my best to placate it. In return I gain a sense of security that “If it compiles it’ll (probably) work”[1].

I used to have the same sort of relationship with my C# compiler (only with less error messages) but lately I’m beginning to have some trust issues.

It all started one day when I was refactoring some code to use regular expressions (the types have been changed to protect the guilty).

string pattern = "needle";
/* Snip N lines */
System.Console.WriteLine(haystack.Contains(pattern));

This code needlessly matches “needlessly”, well that’s simple enough to solve, I’ll just replace pattern with a regular expression including word boundaries:

Regex pattern = new Regex("\bneedle\b");
/* Snip N lines */
System.Console.WriteLine(pattern.IsMatch(haystack));

It compiles, ship it!

After all the buildup it should not be awfully surprising that the code in question is not shipping quality. At runtime it throws an exception saying it can’t cast a string to a Regex.

When expanding the N lines in the above code I see this:

if (someCondition)
{
    dynamic obj = GetDynamicObject();
    pattern = string.Format("{0}:{1}", obj.value, pattern);
}

Why the hell does this compile[2]? It’s obvious that String.Format always returns string which is incompatible with Regex!

Well actually it isn’t, String.Format doesn’t always return string. dynamic is contagious, any function that is called with at least one dynamic argument will return dynamic, thus dramatically lowering the value the compiler has as an error detector.

In fact if you’re in the habit of using var whenever possible you may be helping to spread this contagion. Previously we thought that writing type names is redundant and the following lines are equivalent:

string s1 = Path.Combine(directory, file);
var s2 = Path.Combine(directory, file);

Some would even prefer the second line saying it’s redundant to tell the compiler something it already knows, but if one of the variables you send to this (or any other) function is of type dynamic it will infect s2 with its type and so on transitively.


[1] This is hyperbole of course, what I mean is that I expect the compiler to catch all type errors.
[2] In real life it was worse, the string.Format had several arguments only one of which was dynamic and this declared many lines above the offending line.

About these ads

Actions

Information

2 responses

24 10 2012
Matt

I found this post at the end fo Eric Lippert’s blog (http://blogs.msdn.com/b/ericlippert/archive/2012/10/22/a-method-group-of-one.aspx).

I agree with your equating var with an infection and I equate it with Ebola in that regard. Any time I see a var as I’m working on something written by someone else, I swap it out for an actual type; and I avoid it entirely when working on my own stuff.

Great comments (and I love the title of your blog).

25 10 2012
Motti Lanzkron

I don’t think var is an infection, dynamic has the effect of spreading and var facilitates this by creating unexpected dynamic variables.

Actually I’m quite fond of using var in most code, it’s only when an expression you don’t expect to be dynamic but is that there is a problem (IMHO).

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s




Follow

Get every new post delivered to your Inbox.

%d bloggers like this: