The Future Of C#, Part Five

The Future Of C#, Part Five

Rate This
  • Comments 74

When we're designing a new version of the language, something we think about a lot is whether the proposed new features "hang together". Having a consistent "theme" to a release makes it easier for us to prioritize and organize proposals, it makes it easier for our marketing and user education people to effectively communicate with customers, it's just all-around goodness.

If you look at C# 2.0, it was a bit of a grab-bag. The big features were clustered around the notion of enabling rich, typesafe programming with abstract data types that represent collections of data -- and thus generic types and iterator blocks. But there was a whole lot of other stuff in there as well: implementing anonymous methods was a major feature that doesn't fit well with this theme. And there were other more minor features as well: partial classes, improvements to properties, and so on.

With C# 3.0, the theme was very clear: language-integrated query. Anything that did not directly support LINQ was immediately made lower priority. It is rather amazing to me that partial methods and auto-implemented properties got in at all; that they were relatively easy features to design, implement, test and document was what saved them.

What then is the theme of C# 4.0? Again, it seems like rather a grab-bag: covariance and contravariance, improved interop with dynamic languages, improved interop with legacy COM object models, named and optional parameters. It also seems like a pretty small set of new features compared to generics or query comprehensions.

That was deliberate. Some feedback that we received loud and clear throught the C# 3.0 ship cycle was "this is awesome, we need these language features immediately!" and, somewhat contradictorily, "please stop fundamentally changing the way I think about programming every couple years!" Rather than trying to find some way to yet again radically increase the expressiveness and power of the language, we decided to spend a cycle on making what we already have work better with the other stuff in our programming platform infrastructure.

"Now actually works the way you'd expect it to" is not really a theme that gets people excited, but sometimes you've got to stop running forward at full speed and take some time to fix the existing stuff that is annoying a lot of people. (When I was on the VSTO team I petitioned the C# team to please, please make ref parameters optional on calls to legacy COM object models, but they were too busy with designing LINQ; I'm delighted that we've finally gotten that in.)

We also want to make sure that we are anticipating the problems that people are about to face and mitigate them now. We know that dynamic languages and object models designed with dynamism in mind are becoming increasingly popular. Given that there will be stronger demand for statically typed C# to interoperate with them in the future, let's get dynamic programming interoperability in there proactively, rather than be reactive about it later.

Looking forward, it's not clear what exactly the theme of future (hypothetical!) versions of the language will be. The expected onslaught of cheap hardware parallelism looms large in our minds, so that's a possible theme. Enabling metaprogramming is another possible theme on our minds, thought it is not at all clear how that would happen. (Make C# its own metalanguage? Extend expression trees to statement trees, declaration trees, and so on? Open up the internals of the compiler and provide an object model that lets people generate programs directly? It is hard to say what direction is the right one to go in here.) Fortunately, people way smarter than I am are thinking about these things.

  • Given that BCL guys are introducing DbC ("code contracts") in .NET 4.0, at the library/instrumentation level for now, it would seem logical to me to extend this to full-fledged support on language level (the library-only solution can be rather quirky syntactically - just look at the pains one has to go to write a contract for an interfaec).

  • <i>2. The ability to refer to 'this' in field initializers.  </i>

    That would be very dangerous, as you need to take evaluation order into account. As a matter of fact, I even doubt CLR would admit it... at least, if you implement it as "normal" field initialization (I mean, before calling a base constructor).

    Instead, I should provide fileld-like initialization for automatic properties.

  • Eric, if you are looking for ideas how to enable metaprogramming in C#, you should look at Nemerle where it is already done. See the following links - http://nemerle.org  and http://nemerle.org/Macros

    For example, Nemerle does not have if-else statement, but it defines it as a macro using quotation operator <[ … ]>

    macro @if (cond, e1, e2)

    syntax ("if", "(", cond, ")", e1, Optional (";"), "else", e2)

    {

     <[

       match ($cond) {

         | true => $e1

         | _ => $e2

       }

     ]>

    }

  • You need to take a look at Nemerle language (nemerle.org) for .Net. It's something like

    superset of C# language with minimal core. All other features like foreach, if then else etc

    made with macro-system. Its something like right Lisp for .Net :) This language now actively

    supported by RSDN community. I hope that you fill find new fresh ideas about how to add

    metaprogramming at C#.

  • While I'm sure that a meta-programming solution specifically designed for the purpose could be "better" than C++ templates, I would hope that the design would be such that it would be possible to transfer some of the years of community and personal experience from C++ into C#, given the relatively close relationship of the languages.

  • I'd just like to add to Jesper's plea (and Jay's, indirectly) - readonly autoprops would be a significant win from my point of view, *and* give us at least an *easier* route to immutability. I can't see that it would be very hard, either - although I'm aware that what seems simple often isn't, and *any* change requires design work, etc.

    Basically I'd just like to extend automatic properties such that:

    public string Foo { get; readonly set; }

    expanded to:

    private readonly string <>_Foo;

    public string Foo { get { return <>_Foo; } }

    and any assignments to the property within the constructor (the only place they'd be legal) were transformed into assignments to the variable.

    That, combined with the named parameters of C# 4 would make creating immutable types a lot easier. I'm happy to wait for really good support of immutability complete with a declarative syntax and compile-time checking - just help us this one little bit :)

    (I suspect C# 4 is too locked down to allow anything new in at this point, but if there's the slightest chance of getting readonly autoprops, I'm happy to campaign hard for them :)

  • Jon,

    agreed, but there's more: one of the useful feature combination for C#3 was the ability to create simple classes with automatic properties only, without special constructors only using object initializer syntax for instantiation. Now can we have object initializers for immutable objects too, please? I know I'm borderlining the impossible here, because object initializers are just property assignments _after_ the default ctor has been executed. (But in case of a generated default constructor, would that make any difference? OK, maybe it would, because the class might have base classes, and depending on their being auto-generated would be a mess.) But still, getting object initializer syntax for immutable objects would do a lot to reduce code for trivial types _and_ promote immutability.

    How bad would it be to have "readonly" in automatic properties mean "write only via initializers, ctors or object initializers"?

    In some cases this might result in bad things, but how important is it to support the concise automatic property syntax with the proposed readonly extension for those cases? shouldn't simple things be simple, and hard ones merely possible?

    But then again, this might be too surprising for average C# users who don't make it their hobby to study language specs. Just an idea, not thought through.

    Stefan

  • stefan: With optional and named parameters, you can get object initializer *style* instantiation just with a constructor. The nice thing about object initializers is that they're just translated into standard property accesses - it's pure syntactic sugar. When you break that connection, it becomes tricky.

    I have other suggestions around immutability and object initializers, using builder objects, but that's a different matter (and Eric's already got that suggestion somewhere in his inbox - I'm neither expecting nor requesting any movement on that front).

    I'm hoping that the less we ask for, the more likely we are to get it :)

  • John: you're right, you can get the syntax, but if you include the class definition into the calculation, it won't be nearly as concise. Declaring an immutable class with n properties in n+1 lines (not counting curly braces) would be just great. Yes, this might still be a bad idea in the end, but without seriously discussing it we will never know. I did not ask for it though, it's just an idea.

  • I wonder when

    var c = Click;

    if (c != null) c(this, EventArgs.Empty);

    will be fixed.

  • You haven't said what's broken.

  • To make my life simpler, I initialize my events like this:

       event EventHandler Click = delegate {};

    Now I don't have to worry about null checks & temporary local copies.  Just

      Click(this, EventArgs.Empty);

  • *Please* Dont change the way everything works every year. .Net 1.1 to .Net 2.0 was absolutely OK since the basics were almost the same and it was a smooth transition. .Net to .Net 3.0 is a bit painful for the small scale windows applications developer (Based on WPF and not on windows forms) Yeah I know there is a whole lot more functionality to it and its very very powerful , so OK.

    But please dont change the internal architecture every year, everytiume you do that you looses developers and it is hard to keep up with all the technologies.

    I think including specialized development tools for targetted developers would be a better idea than to change the architecture totally. I am a fan of microsoft development tools and have been using them since 6 years and I only have admiration for them which started with VC++ 5 to .Net 3.5 .

    But I do realize now that things are moving way to fast and my concepts are shaken up REALLY SHAKEN UP with every new release. Things are not the way they used to be !! I think we really need to stabilize a bit + have the support for previous architectures as well (As we dont get the chance to develope with the latest all the time due to client restrictions , hardware restrictions e.t.c. )

    I hope I was able to present my point of view !! I really love development and Microsoft but doesnt want C# to become "Ruby on Rails" . So please dont take all the code away and leave it to configurations, configuring is a whole new language for the developer which is difficult to understand without the underlying architecture which is changing all the time.

  • @Jay: Nice hack. I've forgotten that one.

    @Erik: The whole observer pattern is broken. The whole point with this pattern is to broadcast information to anyone interested, without knowing how many they are.

    The way events are implemented we have to resort to hacks, as Jay suggests, or we have to check if anyone is really there.

    The much needed null check proves the abstraction is leaky. The need for a temporary variable proves it's not safe.

    All the repetitive code we have to write should have been done by the framework.

  • @Asad: very few of the changes to C# and the BCL are breaking changes. There's no rule that says you have to use WPF, or LINQ, or any of the (incredibly cool) new things that have been added over the last 7 years. And you can pick and choose the ones you do use; my project is still on Windows Forms but makes extensive use of LINQ.

    The fact of the matter is that the software development world is moving very fast at the moment, and C#, as a leading citizen of that world, is obliged to at least try and keep up. Hence the dynamic support in C# 4.0, PFX and Contracts in .NET 4.0, and meta-programming coming in a later C#.

    Personally, I've found that the new models, patterns and capabilities in each version of C# have made me a better programmer by changing the way I think about the way my code.

    As the saying goes, it's better to have something and not need it than to need something and not have it.

Page 2 of 5 (74 items) 12345