Files
popcyclical-blog-archive/posts/2010-03-23-programming-language-misuse.md
T

70 lines
3.6 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: "Programming Language Misuse"
date: 2010-03-23T20:06:11.401-05:00
slug: programming-language-misuse
published: true
---
Im feeling a bit guilty about some code I wrote:
```
using (new OperationTimer("MyOperation", this))
{
// ... complete operation
}
```
This innocent looking C# snippet is hiding a tricky secret - the `using` statement is being misused (no pun intended).  The [documentation defines the intended usage clearly](http://msdn.microsoft.com/en-us/library/yh598w02%28VS.80%29.aspx):
using Statement
Defines a scope, outside of which an object or objects will be disposed.
The problem?  The notion of “object disposal” is being hijacked!  In your garden variety [`IDisposable`](http://msdn.microsoft.com/en-us/library/system.idisposable.aspx) implementation, youd be dealing with an [external resource that needs to be released](http://msdn.microsoft.com/en-us/library/fs2xkftw.aspx) before the object can be removed from memory.  Instead, Im using it to time a block of code like so:
```
class OperationTimer : IDisposable
{
private readonly string _operationName;
private readonly ITimable _obj;
private readonly Stopwatch _stopwatch;
public OperationTimer(string operationName, ITimable obj)
{
_operationName = operationName;
_obj = obj;
_stopwatch = new Stopwatch();
_stopwatch.Start();
}
public void Dispose()
{
_stopwatch.Stop();
_obj.OnOperationCompleted(_operationName, _stopwatch.Elapsed);
}
}
```
The constructor starts a timer and the `Dispose()` method stops it and reports the elapsed time.  (*aside: if youre interested in how Im using the timer, check out my previous article *[*Simplified Performance Counters*](http://popcyclical.com/2010/03/21/SimplifiedPerformanceCountersInNET.aspx)) There are certainly other ways to accomplish this same behavior, but they lack the elegance of a neatly scoped code block.  Its arguably an acceptable way to repurpose the language.  In fact, the ASP.NET MVC authors saw fit to use it in a similar fashion with the [BeginForm helper](http://msdn.microsoft.com/en-us/library/dd410596.aspx).  The only “resource” it disposes of is to render a closing `</form>` tag.
My question is: **When does repurposing language constructs turn from “acceptable language use” to a “dirty trick”, or worse, “illegible line noise”**?
It seems like a slippery slope.  One instance that I dont care for is controlling execution flow by-way-of logical operator precedence in most C-like languages:
```
expression1 && expression2 || expression3
```
Which is equivalent to:
```
if (expression1)
expression2
else
expression3
```
This takes advantage of the order of evaluation in a logical statement it is assumed (correctly) that `expression2` will never be evaluated if `expression1` is evaluated as false, and instead, `expression3` will get to run.  Likewise, if the first two evaluate to true, the truth value is known for the statement and `expression3` is never evaluated. This is clearly not the intended usage which the language designers had in mind, but it works, and it saves any keywords from being written.
Some truly beautiful code has been written by way of hijacking the language.  For instance, [heres a program that will calculate the value of pi using an ascii circle](http://www.cise.ufl.edu/~manuel/obfuscate/pi.c).  Truly neat - but also completely useless from a software development standpoint.
What do you think?  Should I just get over my guilt about repurposing `IDisposable`?  Or, should I be true to the original intent of the language and find another way?