Language Envy:
This post is part of
a series
where I wish C# had a particular feature I came to like when working with other programming languages.
It's easy to let a small language feature go unnoticed. The more I spend
time writing JavaScript and Ruby, the more one little detail shows itself
loud and clear when I go back to my trusty C# (well, it shows itself by not being absent,
if that makes any sense.)
The little language detail I'm writing about today is the literal syntax
for hashes. Especially in JavaScript, because all objects are just hashes
on steroids, which makes the literal object syntax become one and the same
with the hash literals.
In JavaScript it's easy as 1-2-3. It's not surprising so many libraries are
adopting hash parameters.
//Prototype.js sample
var elements = { success: 'myDiv', failure: 'errorDiv' };
var ajax = new Ajax.Updater(
elements,
'getData.aspx',
{ method: 'get', onFailure: reportError }
);
//jQuery sample (jQuery UI)
$('#fromDate').datepicker({rangeSelect: true, firstDay: 1});
$("#search").autocomplete("/product/find",
{ autoFill: true, delay: 10, minChars: 3 }
);
Now, I understand that part of the popularity of hashes in JavaScript
and Ruby is due to the loose typing of these languages. But if the syntax
wasn't light, APIs like the above ones would be much more painful to use.
C# 3 does have a hash syntax (or, more accurately, a dictionary one.)
Unfortunately, dictionary initializers, although being a step forward,
still leave noise to be removed.
// hypothetical search API
var books = FindWithCriteria<Product>(
new Dictionary<string,object>
{
{"Category", Category.Books},
{"MinPrice", 33.45},
{"MaxPrice", 50.00},
{"Contains", "asp.net"}
});
Hmmm, no, thanks. Maybe that's the reason we are starting to see some
APIs that use (abuse?) anonymous objects and reflection to create hashes.
// hypothetical search API
var books = FindWithCriteria<Product>(
new {
Category = Category.Books,
MinPrice = 33.45,
MaxPrice = 50.00,
Contains = "asp.net"
});
This last one doesn't look so bad on the surface, but we know what is going on
under the covers so it's like putting lipstick on a pig. If, instead of using reflection at run-time, the compiler had
support for converting the above anonymous object into a
IDictionary<string,object>
, then we would have a more
convenient and efficient way of creating hashes. Maybe it's too late to introduce a feature
like that while maintaining backwards compatibility.
I believe when you add a language feature that is elegantly designed (i.e. clean and unnoticeable,)
it becomes popular more quickly — just like
what is
happening with lambdas .
The existing alternatives for creating hashes in C# 3
are still too noisy or inefficient to be integrated in our code without reducing
the readability or incurring a performance penalty.