Jeremy D. Miller -- The Shade Tree Developer

Sponsors

The Lounge

Syndication

News

Advertisement

Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
C# 3 is like a Moped

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? 


Posted Fri, Mar 14 2008 9:06 AM by Jeremy D. Miller

[Advertisement]

Comments

Edward Ellis wrote re: C# 3 is like a Moped
on Fri, Mar 14 2008 10:30 AM

I haven't seen any posts on why Duck Typing is better than compile time type checking.  Have you written any?

Jeremy D. Miller wrote re: C# 3 is like a Moped
on Fri, Mar 14 2008 10:44 AM

@Edward:  

False dichotomy there a little bit.  You can have "duck" typing and compile time checking simultaneously, and some of the functional languages do this.  It's C#/Java style type systems that are giving me heartburn here.

Readability, Readability, and Readability.  It makes a bigger difference when you try to make internal DSL's and language oriented API's.

Let's see, what else:

* Easier code reuse

* Easier mocking in unit testing

* Less code to write

If you want to see the pro-duck typing arguments, you just need to go outside of the .Net mainstream and find Ruby or Python or Smalltalk blogs.

jdn wrote re: C# 3 is like a Moped
on Fri, Mar 14 2008 11:15 AM

Have you ever tried this:

www.deftflux.net/.../Duck-Typing-Project.aspx

Any value in it?

Whatever wrote re: C# 3 is like a Moped
on Fri, Mar 14 2008 11:20 AM

Have you tried just getting the job done, instead of constantly looking for the the coolest and latest toys? Just a thought....

Dan wrote re: C# 3 is like a Moped
on Fri, Mar 14 2008 11:31 AM

@Whatever (fitting name)

I'm sure it depends on what you mean by "just getting the job done". I hope, I hope, I hope it's not the 'copy/paste' mentality (as your comment implies) 'cause that's definatley not what this blog or discussion is about.

Jeremy D. Miller wrote re: C# 3 is like a Moped
on Fri, Mar 14 2008 11:31 AM

@Whatever,

I'm trying to find better and better ways of doing things with less effort.  "Just get 'r done" often equates to "work hard, not smart."  According to the Standish Chaos report, something like 75%-80% of all software projects fail, so I don't think we can say just "get 'r done" is really working for us.

Neil Mosafi wrote re: C# 3 is like a Moped
on Fri, Mar 14 2008 11:32 AM

Hmm agreed, but i still don't think C# needs duck typing.  it just doesn't feel very C like and there are other languages out there which allow this.

Actually I've always wished that C# had a "typedef" operator, like in C++... it lets you alias any type with another name.  A simple example could be something like this:

namespace MyNamespace {

 typedef StringIntDictionary Dictionary<string, int>;

}

Then you could then just use StringIntDictionary everywhere that the namespace gets imported. It would essentially allow you to alias all the generic arguments so you only have to define them in one place.

Sergio Pereira wrote re: C# 3 is like a Moped
on Fri, Mar 14 2008 11:34 AM

It's hard for me to adopt fluent interfaces in my C# code after having tasted how they are created and used in Ruby. I'm taking a pass on fluent C# APIs for the time being.

Rasmus Kromann-Larsen wrote re: C# 3 is like a Moped
on Fri, Mar 14 2008 11:36 AM

Well you could always use Boo...

http://boo.codehaus.org/

Works like a charm for me.

Sergio Pereira wrote re: C# 3 is like a Moped
on Fri, Mar 14 2008 11:38 AM

@Whatever

Mmm, I thought the name of this site was "Code Better"... Not "Code Again" ...

You may be reading a blog that is not aligned with your priorities, that's understandable, but a waste of your time when you should be getting the job done in the first place. Just a thought.

Mike Moore wrote re: C# 3 is like a Moped
on Fri, Mar 14 2008 11:39 AM

@Edward For me, the difference between duck typing and static compile time checking boils down to this: Static languages (like C#/Java) implement polymorphism though inheritance, while dynamic languages implement polymorphism through composition. In one you have a strict hierarchy, while in the other you don't. Its as simple as that. Besides Jeremy's examples you should definitely look outside the .NET and Java world to see why this is so important.

@Jeremy Hurray! Glad to have you on the side of righteousness! I've been saying the same thing now for a while, although probably not as nicely as you just did. :)

One nit though. Language Oriented Programming, or using Domain Specific Languages (DSL), is alot more than building a library with a fluent interface. I don't consider a library with just a fluent interface to be a DSL.

IronRuby is progressing nicely. The code drop from Mix looks to be pretty good, but it is not a complete Ruby implementation yet. The DLR hosting API should be much more stable moving forward as well. I believe the plan is for a 1.0 release later this year.

Christopher Bennage wrote re: C# 3 is like a Moped
on Fri, Mar 14 2008 11:54 AM

@Jeremym @Moore

What I'd like to read is a "language to task" analysis. By that I mean, what is C# good for? What is Ruby good for? What is Boo good for? Python, OCaml, etc.

If I'm to be a polyglot (and for inexplicable reasons I'm compelled to be), I need to know this.

I've heard things like, but they are still too vague for me:

OCaml is good for writing compilers.  Boo is good for crafting DSL's. C# is good for enterprisey things (whatever that means). F# is good for analysis (or the same things as OCaml). Ruby is just good.

I'm currently learning Ruby and Boo, but I don't know enough yet to answer these questions for myself. Maybe in a few months...

Mike Moore wrote re: C# 3 is like a Moped
on Fri, Mar 14 2008 12:13 PM

@Christopher A language-to-task analysis is a great idea for a blog post. I'll add it to the pile of things I want to do but am behind on. :)

Justin Etheredge wrote re: C# 3 is like a Moped
on Fri, Mar 14 2008 1:22 PM

@Jeremy Miller - John Lam said at Mix that they wanted to have a non-trivial Rails app running on IronRuby by RubyConf (which is pretty soon, so I have no idea of that is going to happen), but that they expected to hit 1.0 in about a year. It was actually pretty interesting to hear him talking about the challenges of developing the DLR version of a language that has no spec, and how much testing and prodding they are having to do in order to fish out the runtime behavior of performing certain tasks. Hopefully IronRuby will be something that Microsoft will pursue whole heartily, as there certainly are a lot of tasks that Ruby is much better suited for than C#, and vice versa.

wekempf wrote re: C# 3 is like a Moped
on Fri, Mar 14 2008 2:09 PM

@Neil

C# does have that feature.

using StringIntDictionary = System.Collections.Generic.Dictionary<string, int>;

Neil Mosafi wrote re: C# 3 is like a Moped
on Fri, Mar 14 2008 2:20 PM

Hey wekempf good point - I didn't know you write using aliases with generic types, that is quite useful, thanks.

It's not quite the same as with a typedef in C++, where you are actually exposing the type through the usage of your class/namespace to other classes which may use it.  still good

Edward J. Stembler wrote re: C# 3 is like a Moped
on Fri, Mar 14 2008 2:28 PM

It seems C# is slowing evolving into a hybrid language.  However, I cannot help but to wonder:  At what point is it better to consider a different approach?

For instance, while it's true you can hack your way around many of C#'s language-imposed limitations (i.e. IoC, DI, Providers, plugins, duck typing et. al.).  Those types of solutions usually work against the gain of the original intent of the (C#) language.  They also add additional complexities and dependencies to your code base.  Whereas they are usually non-issues in dynamic languages such as Python or Ruby.  I'm not suggesting that dynamic languages are the end-all-be-all solution for everyone's needs.  However they are less prone to certain (static) design issues, and more conducive to flexibility.

In any case, I think a few years from now we'll see a convergance of sorts.  We'll be able to benefit from both worlds.  There won't be discussions about dynamic vs. static, or compiled vs. interperted...

Mike Moore wrote re: C# 3 is like a Moped
on Fri, Mar 14 2008 2:46 PM

@Edward You raise an interesting point about C#'s evolution to a hybrid language. I agree we will see the lines blur between languages, but not in the ways we might always want. I actually had a somewhat viral blog conversation about this.

First, Chad Myers wrote an interesting article called "Dynamic-like Typing using Anonymous Delegates in C#"

chadmyers.com/.../dynamic-like-typing-using-anonymous-delegates-in-c.aspx

I commented on the article on his blog, and Chad followed up with "Moore on the Anonymous Delegate Approach"

chadmyers.com/.../moore-on-the-anonymous-delegate-approach.aspx

I replied on my blog with "The Rubification of C#"

blowmage.com/.../the-rubification-of-csharp

Bertrand Le Roy left a comment on my blog, which I replied to in "The Failure of Static Languages"

blowmage.com/.../static-languages-are-fail

So, you know, FYI. Apologies for the self-promotion. :)

Mike Moore wrote re: C# 3 is like a Moped
on Fri, Mar 14 2008 2:50 PM

@Edward More to your point about language convergance: I think we won't see languages converge as much as we see different languages cooperate well together. This is the promise of putting the DLR on top of the CLR, and adding new languages to the JVM.

I think there _will_ continue to be discussions about dynamic vs. static, and compiled vs. interpreted, but those will be discussions about _which_ language to use to solve the problems in a particular "tier" of the application. This is the Polyglot Programming model.

Edward J. Stembler wrote re: C# 3 is like a Moped
on Fri, Mar 14 2008 3:00 PM

@ Mike:  I agree, we'll likely see a polyglot phase before and on the way towards the ultimate convergance.

Jeremy D. Miller wrote re: C# 3 is like a Moped
on Fri, Mar 14 2008 3:05 PM

@Edward,

I don't see convergence as a good idea.  Let's do polyglot programming and have languages that are simpler to do one thing very well instead of one size fits none languages.  Do you really think a language with both fullblown, compiler enforced Design By Contract *and* dynamic typing/open classes/metaprogramming is possible without collapsing under its own weight?  

Edward J. Stembler wrote re: C# 3 is like a Moped
on Fri, Mar 14 2008 3:22 PM

@Jeremy:  I think convergance is simply the natural progression here.  Recently, we saw C# 3.0 gain some features traditionally found in dynamic languages.  The next version, 4.0, is gaining dynamic lookup.

It's not difficult to imagine a language/compiler combination, in the not too distant future, which could gracefully embrace both worlds.  Granted, this environment should be architected from from the ground-up.  Not something which is added on as an after thought to an existing system with existing limitations.

Ayende Rahien wrote re: C# 3 is like a Moped
on Fri, Mar 14 2008 11:53 PM

Jeremy,

This is not the first time you stated that you are waiting for IronRuby.

Is there a reason for this?

Boo is here, stable, and has more language oriented features than Ruby.

And reason you are not exploring that?

lisp wrote lisp
on Sat, Mar 15 2008 1:02 AM

Pingback from  lisp

Csaba wrote re: C# 3 is like a Moped
on Sat, Mar 15 2008 6:54 AM

Hi,

You should look at  the Cobra language.

Best of Pyton with static and duck typing in .NET and more!!!!!

For an overview see: cobra-language.com/.../Cobra-Lang.NET-2008-Slides.pdf

For more info, see in cobra-language.com/.../why

Regards

Csaba

Jeremy D. Miller wrote re: C# 3 is like a Moped
on Sat, Mar 15 2008 10:06 AM

@Ayende,

I knew you'd pop in here sooner or later.  I think that Ruby has a far richer existing ecosystem and a bigger community than Boo.  I know that you really like Boo, but it's basically Ayende on one side versus hundreds of other people for Ruby.  Boo is interesting, but I think I don't think it ever makes the mainstream if IronRuby really takes off.  Besides, I'm already using Ruby for little tasks and like the language.

And I think you're getting it backwards in terms of language oriented features, which is what I'm really wanting here.  From the examples and literature I've seen Boo is not as expressive as Ruby and doesn't have nearly the same metaprogramming abilities.  

Mark Brackett wrote re: C# 3 is like a Moped
on Sat, Mar 15 2008 9:40 PM

@Neil Mosafi (re: typedef)

In C#, that's written as:

class StringIntDictionary : Dictionary<int, string> { }

Problem solved.

Dew Drop - March 15, 2008 | Alvin Ashcraft's Morning Dew wrote Dew Drop - March 15, 2008 | Alvin Ashcraft's Morning Dew
on Sat, Mar 15 2008 11:08 PM

Pingback from  Dew Drop - March 15, 2008 | Alvin Ashcraft's Morning Dew

John Rusk wrote re: C# 3 is like a Moped
on Mon, Mar 17 2008 1:57 AM

I've found it helpful to take a slightly different tack regarding fluent interfaces.  By leveraging a few C# features, the amount of method chaining can be reduced, which makes the API easier to construct.  Some details here: dotnet.agilekiwi.com/.../shorthand-interfaces.html

Joshua Flanagan wrote re: C# 3 is like a Moped
on Mon, Mar 17 2008 11:09 AM

If you haven't yet, spend at least a weekend programming in Boo. For someone that has been "thinking C#" for a few years, I think it is much easier to jump into and be immediately productive with Boo as compared to Ruby.

Ayende Rahien wrote re: C# 3 is like a Moped
on Tue, Mar 18 2008 12:21 PM

I can't argue that Ruby is more popular than Boo, but I can't think of something that I can do in Ruby that i can't in Boo, and I can certainly think about it the other way around.

Do you have any concrete example?

Add a Comment

(required)  
(optional)
(required)  
Remember Me?