IanG on Tap

Ian Griffiths in Weblog Form (RSS 2.0)

Blog Navigation

April (2018)

(1 item)

August (2014)

(1 item)

July (2014)

(5 items)

April (2014)

(1 item)

March (2014)

(1 item)

January (2014)

(2 items)

November (2013)

(2 items)

July (2013)

(4 items)

April (2013)

(1 item)

February (2013)

(6 items)

September (2011)

(2 items)

November (2010)

(4 items)

September (2010)

(1 item)

August (2010)

(4 items)

July (2010)

(2 items)

September (2009)

(1 item)

June (2009)

(1 item)

April (2009)

(1 item)

November (2008)

(1 item)

October (2008)

(1 item)

September (2008)

(1 item)

July (2008)

(1 item)

June (2008)

(1 item)

May (2008)

(2 items)

April (2008)

(2 items)

March (2008)

(5 items)

January (2008)

(3 items)

December (2007)

(1 item)

November (2007)

(1 item)

October (2007)

(1 item)

September (2007)

(3 items)

August (2007)

(1 item)

July (2007)

(1 item)

June (2007)

(2 items)

May (2007)

(8 items)

April (2007)

(2 items)

March (2007)

(7 items)

February (2007)

(2 items)

January (2007)

(2 items)

November (2006)

(1 item)

October (2006)

(2 items)

September (2006)

(1 item)

June (2006)

(2 items)

May (2006)

(4 items)

April (2006)

(1 item)

March (2006)

(5 items)

January (2006)

(1 item)

December (2005)

(3 items)

November (2005)

(2 items)

October (2005)

(2 items)

September (2005)

(8 items)

August (2005)

(7 items)

June (2005)

(3 items)

May (2005)

(7 items)

April (2005)

(6 items)

March (2005)

(1 item)

February (2005)

(2 items)

January (2005)

(5 items)

December (2004)

(5 items)

November (2004)

(7 items)

October (2004)

(3 items)

September (2004)

(7 items)

August (2004)

(16 items)

July (2004)

(10 items)

June (2004)

(27 items)

May (2004)

(15 items)

April (2004)

(15 items)

March (2004)

(13 items)

February (2004)

(16 items)

January (2004)

(15 items)

Blog Home

RSS 2.0

Writing

Programming C# 5.0

Programming WPF

Other Sites

Interact Software

Cartesian Products Closing Thoughts

Sunday 8 August, 2010, 05:17 PM

This is the final part of a series of six blogs:

Part 6 – Closing Thoughts

Back at the start of this series, I started with a simple, specialized Cartesian product where I knew the number of sets in advance. Anonymous types made this easy, but I had to move away from those to get a more general-purpose solution. This seems to happen quite a lot with anonymous types—they’re handy for very well-contained scenarios, but I often find myself getting rid of them as my code grows more complicated.

I think this is an example of a broader issue. LINQ works really well in monolithic applications—if you can get everything you need in a single method, or better yet a single query, it does a great deal of very useful work for you. But as soon as you want to start splitting things up, life gets harder. You might want to reuse parts of a query, or perhaps you just want to decompose your code into smaller chunks to improve readability, testability, and maintainability. Either way, dismantling a LINQ query into its component parts is possible, but rarely straightforward. I saw a similar step up in complexity here—I started with something that was easy, using small, specialized LINQ queries, but generalizing it was a lot more work.

However, although the general solution was significantly less convenient than the specialized one, it was still reasonably compact. I had been expecting to see a bigger difference between the C# code and the examples from geekier languages such as Clojure, F# and Haskell. But the results are surprisingly similar, I think. The biggest difference I can see is that Haskell’s type system makes it easier to define functions capable of operating over any monadic type—the examples for all other languages only work on lists.

The next biggest difference is that the C# code has more explicit typing—I’ve had to say a lot about the argument and return types of the CartesianProduct method. You’re allowed to state this stuff explicitly in Haskell if you want, but you’re not required to. This brings me onto my final point: ceremony.

An Unfashionable Defence of Ceremony

It has recently become fashionable to attack some languages for requiring more “ceremony” than others. Apparently, “ceremony” is anything you have to write because it's formally required, but which doesn’t directly say anything about what your program does. The need for explicit type declarations in C# is one example. With Haskell I was able to write just the essence, whereas with C#, I had to say more about what I was doing before I could do it. (Haskell is very much a statically typed language, by the way. It’s just that you can leave its type inference system to do a lot of the work.)

I hold an unfashionable view: I’m not convinced that absence of ceremony is intrinsically a good thing—in this particular case I suspect it makes it easier for someone reading the code. I don’t want to have to perform complicated type inference in my head when reading source code—I’d rather the code was explicit about the types it’s using because a) that saves time when I’m reading it and b) removes doubt over whether the author wrote what he or she meant to write.

In what little Haskell I’ve done, I’ve found it much easier to write explicit type declarations even in cases where the compiler doesn’t need them. The ceremony’s not for the compiler—it’s for my benefit. Just to be clear: I don't think that ceremony is intrinsically good either. Pointless verbosity helps nobody. I’m just saying that sometimes, making things explicit can improve readability.

Copyright © 2002-2024, Interact Software Ltd. Content by Ian Griffiths. Please direct all Web site inquiries to webmaster@interact-sw.co.uk