C# vNext: Take 2

A couple months ago I made a post called What do you want in C# vNext? that outlined what *I* wanted out of C# 4.0.  I have to say that it’s the first time I’ve ever been flat out angry about the comments on one of my blog posts.  I think in retrospect I wasn’t clear about why I wanted this stuff.  To review, my original list was:

  1. Mixin’s. I found myself really wanting this for a framework I have in my current project.  Extension methods are okay, but I’d rather make it all the way to Mixin’s.  Obj C can do it as a static typed language so it’s definitely possible.  Heck, you can kind of do it in JavaScript.  I really want to do this dynamically or at least declaratively.  Inheritance tricks don’t count.  The solution presented here for C# 3.0 falls a bit short of what I’d like to have (but it’s better than nothing).  Real mixin’s would give you the ability to mimic “multiple inheritance” in one wave of the hand, and reuse the Mixin code over multiple classes.  Extension methods by themselves are nice, but fall well short of mixin’s.  Of all the things that I asked for, this seems the easiest to do.
  2. Symbols.  Reflection based solutions could be so much easier with Symbols.  I’d love to have compiler safe equivalents to Ruby SymbolsActually, what I wanted this for is somewhat possible in C# 3.0 with lambda expressions.  It’s ugly compared to its Ruby counterpart, but I think we’ll get a lot of usage out of it.  All I really wanted was to say something like “map :propertyName to “nodeName” where “:propertyName” would basically be a pointer to a property.  I was looking to do declarative mappings (class to Xml, domain model class to DTO, WinForms control to Model class, etc.) in a compiler safe kinda way.  Interned strings aren’t an equivalent to what I wanted here.
  3. Make hashes a language feature.  I keep bumping into frameworks that really want to pass around hashtables.  If you absolutely have to do that, I wanna do var hash = :key => “red”, :key2 => “green” in one line of code.  Somebody recently commented that object initializers might be a decent compromise.  Yes, I do know that there is such a thing as Dictionary<T,V> in .Net.  I’m not an idiot, I just want a syntax for building hashes in less code.  Take a look at the new MVC framework or the Workflow Foundation and all of the hashtables that they sling around.  Wouldn’t it be nice to write less code here?  All I really want is some syntactic sugar here.  It’d also make something in StructureMap nicer too, and that should obviously be MS’s priority.
  4. Automatic delegation ala Ruby or Objective C.  No, this isn’t the exact same thing as a Mixin.  I was thinking about having an equivalent of Forwardable in Ruby.  There are a lot of places where you’re explicitly setting up forwarding from the public method of one class to an inner field held by that class just to avoid Law of Demeter chaining and protect encapsulation.  Ruby’s Forwardable makes that ridiculously simple.  C# has to be done explicitly with more noise code.
  5. Metaprogramming!  Method Missing magic!  I’m not holding my breathe on this one because it sounds like a bridge too far for me.  Give me metaprogramming and mixins and I think we can do AOP like things with less effort.  Simply a bridge too far with a static typed language.  In 2002 I was building a large system in VB6 and looking longingly at Java wishing I had the fullblown OOP toolkit.  I feel the same way today about C# coding and watching the Ruby guys shrink their codebases with metaprogramming.
  6. Everything is virtual by default to make mocking easier.  The sealed by default rule that Anders picked for performance is annoying.  I’ll grant you that it isn’t nearly as annoying as checked exceptions in Java though.  I know the TypeMock enthusiasts like to crow about being able to mock anything, but doesn’t it bother you that they had to resort to IL injection techniques just to make a freaking test seam?
  7. If I’d been thinking, I would have said the most important little request was getting Map/Reduce in a little bit smoother than the Array.Find methods.  That’s a can do with extension methods.

 

Do we need C# 4 at all?

After a lot of conversations about the future of C# at DevTeach and on whatever the altnetconf list is called now, I’ve somewhat changed my mind.  If you look in my list above, I’m wanting C# to be more like Ruby or Python.  More functional programming would be nice too, but Anders and co. seem to have that covered a bit in 3.0.  Doing the things that I want makes it into an entirely different language.  Maybe that’s just plain wrong.

There’s no possible way that MS can make everybody happy with one single language.  *I* think the type inference added in C# 3 is great for understandibility because it reduces code noise.  Other people want even more type inference like some of the functional languages (Haskell or Scala).  Even other people think that is a horrible idea because they think it degrades the understandibility of the code (some people apparently remember the VB days before Option Explicit).  I want more dynamicism but other people want even more ways to explicitly express contracts in the code instead.  That’s a significant difference in direction.  We can’t all be happy with one language unless it grows immensely — which would probably degrade C# until a drive starts to replace it with a simpler language and start the whole cycle over again.  Instead, let’s embrace polyglot programming and use more than one language.  F# is a nice addition to the .Net family and I’ve got a side project lined up to give it a go soon.  Give me my IronRuby (or Ruby.Net).  Keep C# a static typed mainstream language.  Do whatever you want with VB.Net.

Let’s call C# done and move on to other languages.  Maybe add spec# because that seems pretty cool, but otherwise, let’s basically seal the deal.  MS only has so many people and resources to go around.  Instead of stretching C# farther, how about they move some people onto IronRuby and speed up it’s schedule?  The initial excitement about the new MVC.Net framework seems to be fading because it isn’t quite Ruby on Rails.  Fine.  Move IronRuby along faster and we’ll just use Rails running  on the CLR (with acceptable performance) and be happy.  Invest the time in better tooling around Ruby to simulate compile time checks and other forms of code analysis.  Give them their due, if anybody could do a great intellisense for Ruby it’s the Visual Studio team.

 

Improving the Language or Improving the Libraries

A lot of people are either upset with the idea of Microsoft making changes in C#, or simply want to see that energy go into better or at least more libraries or frameworks instead.  My perspective is that more frameworks or libraries represents artefacts that may or may not be useful to me.  Better programming languages enable me to more readily build my own code that serves exactly my needs.  A more expressive programming language can reduce maintenance costs by making the code more intention revealing.  Given a choice, I’ll take the better language because of it’s greater applicability.

 

D

A couple commenters said “why not just use D?”  Um, because it’s a fringe language that isn’t mature yet?  If you haven’t heard of it, the D language is being positioned as the Subversion to C++’s CVS.  I talked to some folks about this recently and our collective opinion about D was that it would have been the bomb if it could have rolled out 10 years ago. 

For that matter, a lot of what I wanted is already in Objective C.  That might be worth checking out.  The handful of times I’ve had to read Obj C code I thought it was incomprehensible, but that’s probably just unfamiliarity. 

About Jeremy Miller

Jeremy is the Chief Software Architect at Dovetail Software, the coolest ISV in Austin. Jeremy began his IT career writing "Shadow IT" applications to automate his engineering documentation, then wandered into software development because it looked like more fun. Jeremy is the author of the open source StructureMap tool for Dependency Injection with .Net, StoryTeller for supercharged acceptance testing in .Net, and one of the principal developers behind FubuMVC. Jeremy's thoughts on all things software can be found at The Shade Tree Developer at http://codebetter.com/jeremymiller.
This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://dotnet.agilekiwi.com/blog/2008/04/only-4-new-features-in-c-vnext.html John Rusk

    Microsoft have announced that there will only be 4 new features in C# vNext…

  • http://16randombytes.blogspot.com Bill Barry

    for #3:
    did you see Andrey Shchekin’s Dictionary creation method:
    http://blog.bittercoder.com/PermaLink,guid,206e64d1-29ae-4362-874b-83f5b103727f.aspx

    It would let you at least do this:
    Dictionary items = Hash(Name => “alex”, Age => “10″, Height => “20″);

  • http://keithhill.spaces.live.com Keith Hill

    I don’t agree that they should stick a fork in C# 3.0 and call it done. I would like to see more flexibility with generic constraints and I would really love to see compile-time metaprogramming ala Lisp’s defmacro or like the Converge programming language. I’m glad that C# did *not* carry forward the C/C++ macro substitution feature because text substitution is fraught with problems. However we did lose some ability to follow DRY in C# because of this. For instance, while automatic properties in C# are great in terms of reducing line noise it is only a small step. It only covers one common use case and there are plenty of other common, boiler-plate uses cases. Take INotifyPropertyChanged property impls:

    public string PersonName
    {
    get { return name; }
    set
    {
    name = value;
    // Call OnPropertyChanged whenever the property is updated
    OnPropertyChanged(“PersonName”);
    }
    }

    Totally boiler plate, even worse it uses a literal string to reference the member name. You just know that this code will get copy/pasted and someone will forget to change the string arg to OnPropertyChanged. And the compiler won’t catch that error! It would be cool if I could do something like this in C# 4.0:

    #defmacro Type T NotifyPropertyChangedProperty Identifier N := $< $T $N
    {
    get { return m_$N; }
    set
    {
    m_$N = value;
    OnPropertyChanged($N);
    }
    }
    >

    The syntax is crap and completely pulled out of my behind but I hope you get the idea that this:

    public string NotifyPropertyChangedProperty PersonName;

    would get compiled to an AST (think Expression) that get’s spliced into the resulting code. So it is not text substitution. In the case above, it is almost like we created our own, new keyword.

    Heck, just having the infoof() operator they toyed with for C# 3.0 (or was it 2.0) would be nice to let the compiler do more checking e.g.:

    public void Foo(string name) {
    if (name == null) { throw new ArgumentNullException(infoof(param[0])); }
    }

  • http://http:/tech.norabble.com Ryan Baker

    @Jeremy

    Maybe sometimes true, but in this case, Select and Where were well established in the SQL vocabulary so it’s not like MS was inventing them out of thin air. All things considered, I expect more developers have used Select/Where than Filter/Map, though on the opposite side, I’m sure it’s more difficult to find the type of usage examples your thinking of under the LINQ terms since SQL was never used as heavily in hardcore mathematics and algorithm as dynamic languages have been.

  • http://www.tavaresstudios.com/Blog Chris Tavares

    I don’t think it’s as simple as “if you don’t want feature X, don’t use it.” You will often be forced to, as libraries will start using these features as well. Lambdas, for example, are a much easier way to create and pass delegates. Most .NET libraries didn’t use “naked” delegates that much because they were a pain to create and use. But with lambdas, they suddenly become a lot easier to use, and as a result I expect to see lots more libraries taking or returning delegates in the future.

    Should the library writers restrict themselves to only using and exposing C# 1.0 in their API’s?

  • Gil Zilberfeld

    I’m not sure about closing a language. I like the fact that it is evolving. I’ve gone off the idea that you have to know a language in all bits pieces and keywords in order to actually know awhile back.

    Is C# cumbersome because it has lambda expressions? Not really. Most people won’t use it. Those who will probably need it. So it’s a wider tool belt. I think that C++ went wrong with the “you can do everything with me”. And I think C# should not try to trespass into the dynamic pastures. This would make it comparable to C++ and the “everything” theme. By the way, sometimes language changes don’t stick – remember the MS C++ extensions for managed code? So the “language” was changed again.

    I would like to see more libraries rather than keywords though. Syntactic sugar is not bad though. Make the language expressive. But for more freedom, learn a more dynamic language.

    And as tools go, you should use the best you got. Typemock does the work where other tools don’t. And if you have the tools, it is possible to let the language express what the developer meant: I’m not giving you the right to mess my work by deriving a subclass.

  • http://codebetter.com/blogs/jeremy.miller Jeremy D. Miller

    @Florian,

    Now that brings up a minor pet peeve I have with MS. They have to make up their own names and terms for everything instead of just using the same terminology as the rest of the industry. If they’d called it Map/Filter/Reduce, any old .Net developer could google those methods and find articles representing years of experience with the techniques. But, no. MS has to give it its own name as if they invented it.

  • http://www.planet-xaml.net Florian Krüsch

    Map and Filter are called Where and Select ;)
    I share your feelings about C# 4. You can only stretch a language so far.

  • http://theruntime.com/blogs/devprime/default.aspx DevPrime

    @Dan

    Disabling type checking at the CLR doesn’t really lead to something like missing_method. That’s more of a invocation rule. Disabling type checking would really cause the entire CLR to be completely re-written, and in essence would not be a good idea for many, many reasons. However, every dynamic language is really driven by static code under the covers (that becomes really apparent with something like the DLR, for example). So in order to get something like missing_method, the best approach is to get a parse tree and node invocation that is capable of doing that, which also happens to sit on top of the CLR… and that’s basically DLR :-)

    What are you looking for in terms of overriding the policy for locating assemblies? That capability does exist.

  • Dan

    Syntactic sugar is okay, but I want to see new things at the IL/CLR level:
    - Code coverage without profiling API
    - The option to disable type checking at CLR level and work like Ruby missing_method. Boo does it at the compiler level.
    - A way to override the policy for locating assemblies

    And a System.Ide.Intellisense type with ComVisible as true for getting Intellisense in Notepad++ and others :)

  • http://ironruby.blogspot.com IronRuby

    Hi,

    First of all, i think MSFT should stop working more on C# 3.1 or 4.0 currently.

    I totally agree with Jeremy. MSFT should move more hands to the DLR. The progress on DLR and IronRuby and IronPython is dead slow.

    The announcement of DLR was made at MIX 2007 in March 2007. The next MIX 2008 is round the corner starting from 5th March 2008. Even after one year the current stage of IronRuby is alpha stage only. No news on the IDE and no special section on forums to discuss DLR or Dynamic languages.

    Ruby as an Dynamic language has tremendous potential and IronRuby can serve far better than C# 3.0 or C# 4.0 easily. It would nice forgetting C# 3.1 or C# 4.0 currently, and immediately shift a team of developers to the IronRuby camp. Its the time producing few starter kits in Dynamic languages that can be compared with Static languages starter kits.

    Plus….. rather than dragging everyone to Asp.Net MVC, it would be great if they release Ruby on Rails for IronRuby, since it is a proven MVC framework and much popular and easy to understand. IronRuby on rails shall offer chance to host the website on windows hosting platform since there is only apache as a solution currently.

    MSFT should realize that Dynamic Languages are more popular and the perfect way to go. Rather than getting glued to the old thoughts of static languages, they should march ahead fast with DLR.

    The most surprising part is ….. Even after taking a smart decision of implementing DLR and Dynamic languages, MSFT is making a dead slow progress on DLR and Dynamic languages.

    Thanks

  • http://theruntime.com/blogs/devprime/ DevPrime

    @Oren:

    I recently blogged about variance in generics here: http://theruntime.com/blogs/devprime/archive/2007/11/29/4217.aspx
    I’ve been pleading with MS for a year now about that, so I know your pain.

    Having said that, yes, there are no IL changes necessary, but the CLR/JIT/and language compilers do need to change. In essence, most of the support is there and it’s more a matter of having the CLR/JIT/and Compilers “allow” it to just happen. But that’s actually articulating it a little more simplistically than it truly is. What makes it a problem is that generic-derrived classes are constructed at runtime, so the calling of a method that doesn’t exist yet needs to somehow be acknowledged and allowed by the compiler and then executed (properly) by the CLR. The first part isn’t hard because that’s sort of what happens with Interfaces today. The second part needs more attention from the CLR, although IL has all the semantics necessary for conveying the proper thing today.

  • ted

    C# is largely done as a language. Piling on new features will make it as messy as C++. Been there, done that with C++ where just about every language feature was used on a large project.

    Keep the language simple.

    Allow me to turn off/flag with compiler warnings language features I do not want to be used on a project (i.e., all use of delegates outside of Visual Studio generated code) should be approved by the lead developer. In other words, a one-off 3 line delegate created so that you can sort a list inside of a loop is much less desirable than just putting the 3 lines inside the loop.

    This is the anti-spaghetti code quality rule which is largely not followed by .NET developers resulting in bad code smell, un-maintainable code and poor quality products.

  • http://weblogs.asp.net/gbarnett Granville Barnett

    Apologies I’ve not read your post just skimmed it but I would say that C# 4.0 will see an increased investment in LINQ hence LINQ 2.0 and other functional constructs that make internal decomposition of tasks simpler for the compiler to party on and take advantage of multi-core processors. I’m not sure what new language features would be required for that, maybe a more flexible way to write functions – C# 3.0 syntax for functions is a little cumbersome in my opinion.

    My 2 cents :-)

  • Oren Novotny

    I think one feature that will make C# “almost done” is better co/contravariance on generic interfaces like Eric Lippert hinted at.

    Those would make working with generics much easier. There’s nothing in the IL that even needs to change, it’s purely a language feature.

  • http://codebetter.com/blogs/jeremy.miller Jeremy D. Miller

    @Mike,

    Not a problem, I’m reading the comments too

  • http://blowmage.com/ Mike Moore

    @Scott I feel like we’re hijacking Jeremy’s blog. Perhaps we should move this to twitter. :D

    Ola Bini says that Scala may be a better language than Java for the “stable layer” on the JVM. I don’t think I’m at the point where I think C# needs to be replaced for that layer on the CLR. I certainly don’t think C# needs additional features like type inference. I’m mostly saying that we need to move off that layer as much as possible, because we don’t need to be there.

    (I(will(resist(Lisp(as(long(as(I(can)))))))))

  • http://lazycoder.com Scott

    @MikeM ObjectveC.NET? Well, they’ve got Python and IronRuby on the DLR. Boo is up and running. Some guy got a Smalltalk interpreter running in Silverlight. Why not ObjC?

    ((Eventually) we’ll all end up at Lisp though)

  • Kaveh Shahbazian

    I totally agree with you on calling C# done. We just need at most C# 3.1 with everywhere type inference ind anonymous ones.
    But I hope there be a Lisp dialect; Goo, Dylan or Scheme; but not Common LISP. As time passes Lisp appears to me as a more and more practically useful language.

    Happy new year!
    Cheers!

  • http://blowmage.com/ blowmage

    @Scott Great points. Now that Objective-C 2.0 is garbage collected, perhaps we should just get it on .NET and call it good!

  • http://lazycoder.com Scott

    “The handful of times I’ve had to read Obj C code I thought it was incomprehensible, but that’s probably just unfamiliarity. ”

    When I first started playing around with objC and Cocoa, I had no idea what was going on. Couldn’t make heads or tails of the method signatures.Now I get confused when I look at plain C#/C++/C code. The big difference for me: named parameters. Even if the weird ([self init];) brackets around everything without parens is different, being able to tell explicitly what parameter has what value w/o looking through the rest of the code helps out with the understandability. Your request for symbols would go a long way towards increasing the readability of C#VB.NET code and I think named parameters would be a great addition also.

    For those who aren’t familiar with named parameters:
    http://en.wikipedia.org/wiki/Keyword_argument

  • http://codebetter.com/blogs/jeremy.miller Jeremy D. Miller

    Mike,

    I don’t know if it’s a matter of changing my mind so much as an admission of reality.

    I don’t want an either/or choice between a lean, expressive, dynamic language like Ruby or awesome tooling ala ReSharper. I want it all!

  • http://blowmage.com/ Mike Moore

    Hey Jeremy, I’m really surprised that you changed your mind about C# vNext. I’m also ready to call C# done and move on to “polyglot programming” where you are encouraged to use the right language for the right problem. I blogged about this and caught a tiny bit of heat.

    http://blowmage.com/2007/12/18/the-rubification-of-csharp
    http://blowmage.com/2007/12/19/static-languages-are-fail

    Coincidentally, Ola Bini (of JRuby fame) posted something similar this morning. http://ola-bini.blogspot.com/2008/01/language-explorations.html He embraces the idea of polyglot programming on the JVM consiting of three layers: stable, dynamic, and domain. The static language is your low level/stable layer, and dynamic language is your dynamic layer, and your DSL (typically an internal DSL within the dynamic language) is your domain layer. I really like this approach and as good as the JVM is, I think .NET has a number of advantages here. I wish the Alt.NET crowd was less focused on Resharper and more focused on stuff like this.

  • shawn

    It’s interesting that you bring up objective c. I read a comment on reddit about 4 months ago that inspired me to shoot off an amazon order for a couple of books on cocoa and objective c, and it’s really been something of a relevation, even though i don’t intend on professionally using either technology. Their core os framework has had MVC built in since day 1! There are lots of fantastic ideas there, and some of this stuff goes back to the next step days, so it’s hard to say it’s immature or unproven.

    Objective C definitely has some readability issues, but it’s not like it makes sense once you understand the foundations of the syntax.