I was a little surprised to read Elliotte Rusty Harold’s recent comments on Groovy, calling it the ‘Edsel of programming languages’.  It’s an amusing comment, but pejorative and challenging enough to motivate a response. 

The past few years have been interesting and fruitful from a programming language perspective: Ruby, Groovy, Scala, F#, and the evolution of C# are those which spring to mind.

Many of these developments have been about finding a way to push functional-programming idioms (lambda expressions, currying) or dynamic language features (type inference, closures) into well-established imperative languages like C# and Java. I think the results have been mixed: imperative languages are essentially assignment-based, not expression-based, so you end up with a hybrid which, from a language syntax point of view, is neither one thing nor another and arguably suffers as a result.  But it’s difficult to argue that these efforts don’t deliver real positive utility.

An example of this is how C# has evolved support for lambda expressions, expression trees and implicit typing. First (in v1) we had simple delegates, then (in v2) we were able to drop the delegate syntax and declare anonymous methods inline, and finally (in v3) we can use a compact lambda syntax which looks a bit like ML. But because all this has been added to what remains fundamentally a statically-typed, compiled language, you still have to put up with all the nasty explicit declaration of types (and type parameters) on the l.h.s. of every assignment, just to keep the compiler happy.  So the final step was to introduce the var keyword and bring implicit typing into the language. Not dynamic typing, just implicit typing: we get to trim away the ugly declarations but keep the compile-time type safety. 

The confluence of these developments enabled things like LINQ: blending a query sublanguage into the primary language syntax. The best exposition of this I have read is by Ian Griffiths, in his excellent post on expression trees: see the example code just over half-way down, under the section ‘Expression Trees, LINQ, Deferred Queries, and Databases’. It’s all so superficially appealing – just look at the motivating use-case in Ian’s post. But still there’s a small, nagging voice in my head saying this isn’t quite right…

It feels as if we’re trying to pretend there’s no boundary (or intermediary) between the program text and the resource we’re querying. This is similar to the way we tried to pretend that remote procedure calls were really local calls in the old (and now largely discredited) distributed programming models such as CORBA and DCOM. Recall the fallacies of distributed computing and the tenets of SOA: these are essentially warnings about the dangers of implicit or flawed assumptions.  Although the tenets have been challenged (and were threatened with retirement) most of what they said is timelessly valid.  In the context of LINQ, I think my nagging voice is pointing to the boundary-crossing in a LINQ query and muttering “private implementation technique, not primitive construct”.

What’s this got to do with my starting point for this piece, which was Harold’s ‘Edsel’ jibe?  I suppose it’s this: whatever we may feel about the virtue of purity in language design, in the end productivity and usability are the bigger drivers, and with skill it is possible to combine language features without creating a monster.

Technorati Tags: ,,

Came across this blog post, while following-up on a semantic-web related Google Code project:

Why I hate Windows Vista (and can’t wait to re-install XP) « The Wandering Glitch 2

I have often wondered: how can the company which brought us C#, the .NET Framework and the CLR possibly be the same company which excreted Vista?

The guy behind the above referenced post is clearly a fan of C# (as I am), but despises Vista (as I do, along with those who made all the colourful comments on his post). I have left Vista on my new laptop, but in a much reduced partition, and have given over the lion’s share of the drive to my copy of XP Professional, which I still think is pretty damn good.

What about the competition? On the desktop, there isn’t much that’s credible. (I’m not considering MacOS because to get that you have to buy the hardware). So I spent (or should that read wasted?) a few hours with some of the latest crop of Linux distros last weekend: Fedora 8, openSUSE 10.3, the latest Mandriva, PCLinuxOS 2007 and probably another one but I can’t be bothered to recall which. None of them impressed me in the least. Only ONE of them (PCLinuxOS) correctly detected all of the important devices on this laptop, including the wireless chipset. Plus they all looked terrible when compared to Windows XP, especially in terms of font rendering, so they couldn’t even seduce me with glamorous graphics.

What really drives me mad is that none of these distros really stands out: they all look virtually the same (Gnome or KDE, plus or minus a colour-scheme and some desktop wallpaper), they all contain more or less the same rag-tag collection of packages, but (and here’s the kicker) they’re all different in irritatingly detailed respects, some of which are downright inconvenient such as package management or filesystem layout! Every year is heralded as ‘the year of Linux on the desktop’, and every year I dutifully have another look, then gratefully boot back into Windows XP and get on with business.

I wonder what’s next for Windows? With Microsoft so chock full of truly bright and talented folk, I’m really hoping that we can look forward to the Windows that Vista should have been. And when they do finally release that, why not give away XP? Or, to avoid the inevitable complaints about anti-competitive pricing, make it 50 bucks? Then nobody except the bigots or fundamentalists will need to waste time with Linux. Go on Microsoft, do us all a favour.

I was disappointed to discover that the standard Java regular expression library (java.util.regex) doesn’t support named captures. I’m porting some C# code over to Java, which uses this feature. The best alternative seems to be JRegex, which forces me to depend on a non-standard library.

A porting exercise like this really highlights the differences between Java and C#. I must confess that I prefer C#’s syntax and the slightly cleaner code resulting from the (mostly) very well designed and implemented set of framework libraries. The C# designers of course had two great advantages: (1) being second, and (2) not having to worry over-much about portability.

Advantage (1) is about having a ‘clean slate’: they could take Microsoft’s Java (J++), fix (or improve) awkwardnesses, and clean up the syntax without worrying about compatibility with existing code. Property syntax is a good example; when porting over my C# code, it was a pain having to convert every property to a getXXX() / setXXX(val) method pair. On the other hand, the Java bean convention has a modest advantage when using intellisense or similar in an editor: all the get and set methods appear in a nice list – you don’t have to hunt for the properties.

Advantage (2) may be more debatable. Although it’s true that the Java platform APIs are careful to avoid OS-dependent behaviour, it’s sometimes necessary to be aware of potential differences in the platform beneath the VM: e.g. on a Unix-like system, a file may return false for both File::isDirectory() and File::isFile() (e.g. a block-device). To be fair to .NET, the core libraries provide good support wherever they touch a common native resource such as the filesystem.

Two simple examples where the .NET framework libraries provide an out-of-the-box solution, but Java still depends on third-party support:

1) Intelligently combine path fragments to yield a single, usable pathname, using the correct separator character:

// C#string filePath = Path.Combine(pathFrag1, pathFrag2);  // fragments are strings

// Javaimport org.apache.commons.io.FilenameUtils; // Requires Apache Commons IO library...String filePath = FilenameUtils.concat(pathFrag1, pathFrag2);

2) Read the contents of a file into a string (and ensure the file is closed):

// C#string fileContents = File.ReadAllText(filePath);

// Javaimport org.apache.commons.io.FileUtils;  // Requires Apache Commons IO library...String fileContents = FileUtils.readFileToString(new File(filePath));

Hardly a big deal in either case, but in C# you never have to hunt for the external library and ensure it’s linked. So much of the .NET BCL becomes practically ‘extended syntax’: if only Visual Studio implemented the equivalent of ‘fix imports’ in Netbeans! I do get tired of having to go to the top of the file and add the ‘using …’ lines.

Generics are another matter (and much too large a subject to deal with properly here). It is a simple truth that .NET does generics properly and Java does not. If you don’t like that statement, read both this article and this one, before giving me any grief about it.

Here is the same combination of generic collection and property getter, in both languages:

// C#//List<Segment> m_segments = new List<Segment>();...public Segment[] Segments{  get { return m_segments.ToArray(); }}

// Java//ArrayList<Segment> m_segments = new ArrayList<Segment>();...public Segment[] getSegments(){   return m_segments.toArray(new Segment[m_segments.size()]);}

Again, not a huge difference, but I know which I prefer to look at. The Java toArray implementation requires us to provide the new Segment array as an argument because at runtime Java’s ArrayList doesn’t possess the generic type information to make the copy without the type-hint. The copying is done using System.arraycopy and casts, because ArrayList’s type parameter information is erased and replaced with Object (and casts) at compile-time.

Despite all of that, I’m keen to continue with both languages. If only the Java community would be prepared to go for a ‘breaking change’, a major step release which fixed some of the fundamental problems (e.g. generics implementation) at the expense of JVM back-compatibility, and cleaned up the syntax even further.