Since writing this post a few weeks ago – which now seems ridiculously naive when I read it back – I set off on a journey to discover the motivations behind the features of Linq. Eventually I cottoned on to the magic work: monad.
Once you know to add monad to your Google search terms, it’s like an undocumented modifier that makes the search results about 38 times as interesting as they would otherwise be.
It turns out that lots of people have been raving about monads for years, and meanwhile I’ve been thinking about them without knowing what to call them (apparently quite a common experience).
Since C# 3.0 we’ve had a similar facility in C#. This means an opportunity for another war.
I’ve started to see little object initialisation trees appearing in my code, and they start to look like a declarative internal DSL. I should post a real example some time. Anyway, this can only mean one thing: we need a snappy name for these things.
I don’t think there’s anything in LINQ that will do this, though I expect I’m wrong – I have a tendency to write my own extension method to do something and then discover that LINQ already provides a general version of it. But in the mean time, here’s my Chain method:
I complain to anyone who will listen about the poor language support in C# for the IDisposable interface. Yeah, we’ve got the using statement, and that’s fine as far as it goes.
But compare that to what C++/CLI has: the most complete support of any .NET language. Not just the equivalent of the using statement, but also automatic implementation of IDisposable that takes care of disposing of nested owned objects, including inherited ones, like magic (relatively speaking, unless you’re a C++ programmer in which case you’ve taken it for granted for a decade or two).
The relationship between deterministic clean-up (i.e. destructors) and garbage collection (i.e. finalizers) was quite vaguely understood until Herb Sutter clarified as part of his work on C++/CLI. But now it’s all very clear how it should work – the only problem is, there doesn’t seem to be any movement towards fixing it in any future version of C#.
About three years ago I experimented with internal DSLs in C++. I didn’t know to call it that at the time (I’m not sure when the term was coined). It really means twisting the features of an existing language to make what feels like a new language.
The purpose of my DSL was to allow C++ programmers to naturally express database queries that would be executed against an RDBMS as standard SQL queries. In other words, it had exactly the same aim as LINQ, although again I wasn’t to know that at the time.
The starting point was a couple of template classes called column and table, which serve the purpose of making the names of tables and columns visible within the C++ type system.
What does this bit of code do?
var result = from n in 5 where (n == 5) select (n + 1);
It looks completely hopeless. How can you loop through the contents of the number 5? The C# language reference says of the from clause:
The data source referenced in the from clause must have a type of IEnumerable, IEnumerable<T>, or a derived type such as IQueryable<T>.
But that is a lie!
The above code is translated into this:
var result = 5.Where(n => n == 5).Select(n => n + 1);
So in fact it is not necessary for the data source (the thing after the in keyword) to be enumerable at all. The only thing it must have is methods (or extension methods) called Where and Select. So let’s define them for all types:
When the dynamic typing proposal for C# came out, my feedback was basically that you can already do it in the language today:
The justification for adding dynamic is that it gets rid of a lot of ugly reflection. But delegates and indexers mean that the language already has almost enough expressiveness to hide those details entirely.
Now the proposal is getting a lot firmer and there’s a CTP available, more people are voicing their concerns. I remain pretty unconvinced of the value of it. One good point made by several people now is that it ought to be possible to use an interface to describe the set of operations that an object must support. The object wouldn’t have to genuinely implement the interface – the IDE would just use the interface’s members to offer up auto-completion in the usual way. The compiler would then simply generate dynamic calls, so the interface would be irrelevant at runtime.