When I was growing up I used to occasionally hear the saying “a Moped is just fast enough to get you into trouble, but not fast enough to get you out of trouble.” I have no idea where it came from, and never saw a single Moped until my twenties, but it’s an ideal way to describe something I was feeling this week. We’re trying to do some language oriented programming in our new project with C# 3, and that generally means Fluent Interfaces. We’re getting some real benefits out of our approach, but the fluent interface code itself can become completely opaque when it devolves into “generics hell” like this:
public abstract class LayoutExpression<THIS, MODEL, ELEM, EXPR> where ELEM : IScreenElement
and
public class TextboxLayoutExpression<MODEL> : LayoutExpression<TextboxLayoutExpression<MODEL>, MODEL, TextboxElement, TextEditingElementExpression>
and
public abstract class ControlDefinition<T, ELEM> : IElementSource<ELEM> where T : Control, new() where ELEM : IScreenElement
The API using this code is okay and generally pretty usable, but pain accrues when it’s time to extend the Fluent Interface.
C# 3 is great, and I’m glad to have it, but the new language features apparently have their limitations. You can drive out more code reuse with generics and lambda expressions, but the readability eventually collapses when you push it too hard. We’re backing up and writing more lines of explicit code instead of trying so hard with generics.
A couple years back there was a blog meme floating around called Is Ruby an Acceptable Lisp? When C# 3 came out, there was some quiet discussion in ALT.NET circles that maybe the new language features (the “var” keyword, better type inference, lambdas) would be enough to satisfy us in regards to Language Oriented Programming and keep us from clamoring for Ruby. The answer for me after three months of hands on C# 3 is that C# 3 is NOT an acceptable Ruby. Simply having Duck Typing (or maybe the super type inference that OCaml and other exotic languages have) would have made what we were trying to do easier to code and easier to read. Some of the Fluent Interface work helps to boil down code into a much smaller surface area, but there’s still too many extraneous angle brackets, squiggley brackets, and semicolons floating around to make it really readable the same way that a Ruby or Python internal DSL can be. Maybe my entire point here is that C# is simply not Ruby and we shouldn’t try so hard to use C# like Ruby.
So, anybody know any new news on IronRuby?