The future of the C# language


PDC is coming up soon, and the session list has been posted.


One thing i wanted to point out was the abstract for a session that the C# team will be giving on version 3.0 of the language:



C#: Future Directions in Language Innovation from Anders Hejlsberg


Join Anders Hejlsberg, Distinguished Engineer and chief architect of the C# language, for an in-depth walkthrough of the new language features in C# 3.0. Understand how features like extension methods, lambda expressions, type inference, and anonymous types make it possible to create powerful APIs for expressing queries and interacting with objects, XML, and databases in a strongly typed, natural way.

Session Level(s): 300

Track(s): Tools & Languages

I’m trying my best to get to go to PDC, but after the JavaOne oppurtunity i don’t know if i’ll have time to do another round of conferences.  But do really want to see your reaction to what we’ve been thinking about and if you’ll like it or not.


Of course, i can’t really delve in deep into any of this, but after (or during) PDC i’ll be sure to cover all the interesting stuff that’s listed above like:



  1. Extension methods
  2. Lambda expressions
  3. Type inference and implicit types
  4. Anonymous types, (no, not anonymous inner classes).
  5. Expression Trees (my favorite)

Other’s like Matt will probably cover the above *and* the interesting subjects of XML and DB interaction.


These might seem like a lot of changes, but i think everyone will see how they build so naturally on C# 2.0.  Who knows… will C# become a language that draws me away from OCaml?  It just might.


I’m excited.  Are you? 🙂


Comments (45)

  1. smartkid says:

    I am sad, because of another long time waiting starts 🙂

  2. loc says:

    If only I could attend the Heljsberg session without paying 1,700 bucks for the whole thing. That’s selling knowledge, and I believe it’s a privilege, a benefit, and a duty to give knowledge to people.

  3. Hasani says:

    How goes the fight for covariant parameters and return types?

  4. DrPizza says:

    I hope you mean contravariant parameters. Covariance is for return types, unless you don’t give a fuck about subtyping.

    Which may well be a legitimate position to take, but for the most part, it’s not the position C# (or .NET, even) takes.

  5. Yes, we need covariant return types, and it would also be neat if C# would expose the CLR’s underlying support for covariance and contravariance in generics.

    Are there any plans to try to recover from the nullable types train wreck in 3.0? All the "nullable types suck" bugs in the product feedback center have now been closed as "by design" (some of them with comments to the effect that there’s not enough time to do the work) so it seems there’s no plan to fix them in 2.0. As far as I can see it’ll be very difficult to fix them in a backward-compatible way, but you guys have some very smart people working on language design, and if there’s any way to pull it off, I’m sure you can find it. Please try! 😉

  6. II's Musings says:

    Cyrus Blather has in his blog a post about the upcoming PDC session

    on the future of C#. Among the things…

  7. Josh says:

    Sounds cool. Of course, this is going to get everyone hyped and excited about C# 3.0… 2 months before C# 2.0 is released! Seems like a good way to dampen excitement for the latest product.

    Of course I understand anyone that will be attending PDC will have already been using C# 2.0 for at least a year. But think of all the press the new feature announcements will generate for the general public to consume. "And pretty soon, you’ll be able to buy a new C#, that does NOT have these features." Frustration?

    Not a complaint – I love all the preview stuff. But I wonder if this kind of issue was considered.

  8. Aren’t lambda expressions just anonymous delegates as found in 2.0?

    What’s the difference between lispish "(lambda (x) (+ x 2))" and whidbeyish "delegate(int x) {return x + 2;}"?

    I suppose one difference is that the compiler has to be able to infer the delegate type of the latter, but that’s more a difference between static and dynamic typing. And "anonymous types" and "type inference" make it sound as if that requirement is *already* lifted in 3.0.

  9. Shawn B. says:

    I remember hearing about all the new features of 2.0 a year ago when so much of that energy could have been focused on what you can do with 1.1. Our organization where I work currently uses version 1.0 and has not upgraded to 1.1 because of all the anticipation for 2.0 that we heard about everywhere.

    Just imagine, 2.0 is not released and now we start hearing the 3.0 hype. I wonder, if our company will wait for that because 2.0 isn’t good enough or because you can do all these wonderful things in 3.0 in 2 years from now that you can’t do in 2.0.

    This is rediculous nonsense. First, create the illusion that you believe in the current release and that others should do, focus on it, exploit it, and when another release do close to being due, discuss it.

    All that said, I’m waiting for the news on 4.0… Hmm… I predict we’ll be hearing it about the time of 3.0 beta 1. Great.

    Thanks,

    Shawn

  10. CyrusN says:

    To all of those posting about the strangeness of announcing future C# work when C# 2.0 hasn’t even be released:

    Yes, this was something that we thought a whole lot about and we considered the points that you would be making.

    *however*, we feel that the C# future that we are working on will make C# 2.0 even more attractive.

    I mentioned in the posting: "These might seem like a lot of changes, but i think everyone will see how they build so naturally on C# 2.0."

    The idea behind a lot of the stuff we’re doing is that if you start adopting and embracing C# 2.0, then the future C# stuff will work effortlessly with the new code you have. However, if you avoid 2.0 because you’re waqiting for the future you’re going to have a whole lot of work to do when that eventually rolls around.

  11. CyrusN says:

    Loc: After PDC this information is usually made available rather quickly. We’ll also be presenting information on the C# website as well as blogs.

    You don’t need to go to PDC to learn abou all this stuff (just like with C# 2.0)

  12. CyrusN says:

    Stuart: The Nullable issue is being actively investigated. I can’t say yet what the final release will look like though.

  13. CyrusN says:

    Stuart: "Aren’t lambda expressions just anonymous delegates as found in 2.0? "

    I can’t tell you yet 🙂

    "but that’s more a difference between static and dynamic typing. "

    No, it’s not related to dynamic typing at all.

  14. CyrusN says:

    Shawn: "I remember hearing about all the new features of 2.0 a year ago when so much of that energy could have been focused on what you can do with 1.1. Our organization where I work currently uses version 1.0 and has not upgraded to 1.1 because of all the anticipation for 2.0 that we heard about everywhere."

    Pity. 1.1 fixed a lot of bugs and made a lot of things easier. We’re not going to stop thinking about the future for the very simple reason that there’s so much amazing stuff we can do, and these things can make developers’ lives so much easier. However, we can’t do it all at once because we wouldn’t have enough time and we’d never ship. Do you not buy a computer because in a year there will be better computers out there?

    "Just imagine, 2.0 is not released and now we start hearing the 3.0 hype. I wonder, if our company will wait for that because 2.0 isn’t good enough or because you can do all these wonderful things in 3.0 in 2 years from now that you can’t do in 2.0. "

    Perhaps. But we’ll be showing how that is a very bad idea, and how embracing 2.0 asap will provide you an amazing level of benefit when the future C# arrives. If you hold off, then you might have a whole lot of work ahead of you.

    "This is rediculous nonsense. First, create the illusion that you believe in the current release and that others should do, focus on it, exploit it, and when another release do close to being due, discuss it. "

    We do believe in the current release. And I, personally, think it’s unbelieveable important and fantastic. But that doesn’t mean i’m going to stop thinking about hte future. About better ways the language and tools can progress. And i’m going to tell you about them because i want to communicate with teh community so that we can build a better future for eachother.

    "All that said, I’m waiting for the news on 4.0… Hmm… I predict we’ll be hearing it about the time of 3.0 beta 1. Great. "

    That’s quite possible. Who knows.

    I’d rather be open and honest about our plans, rather than keeping all of this secret and just dumping it on you with a new release every couple of years.

  15. CyrusN says:

    Loc: "That’s selling knowledge, and I believe it’s a privilege, a benefit, and a duty to give knowledge to people"

    We will be giving this knowledge to people in every way we know how. However, you have to deal with the fact that this is a convention center and it costs and enormous amount of money to book something like for a week. People need to get paid. Things like unnlimited food is provided. Rooms are rented, screens are purchased, etc. etc. etc.

  16. Ooh!

    It’s really interesting to try to guess what all these features actually mean by their names, but based on interviews, reading about Cw, and this list of features, I have a funny feeling we’re going to get something just as good as multiple return values from a single method.

    On the other hand I’m sure Cyrus isn’t allowed to confirm or deny that…

  17. As Brad and Cyrus point out, we have officially listed a lot of the PDC sessions. Check out…

  18. DrPizza says:

    How about get rid of the nullable types abomination and start over from scratch.

  19. DrPizza says:

    How that abominable "feature" ever made it into the finished product is beyond me. It should have been shouted down as a retarded piece of idiocy right from the start. It’s like they actively set out to avoid a consistent orthogonal design.

  20. CyrusN says:

    DrPizza: "How about get rid of the nullable types abomination and start over from scratch. "

    " It’s like they actively set out to avoid a consistent orthogonal design"

    Starting from scratch isn’t an option. C# is here, and its’ here to stay. The next language we do will have the benefit of being able to "start from scratch" learning from all the mistakes we made.

    And sometimes even if you can’t add something taht’s completely perfect it’s still ok to add it if the benefit is substantial enough the common case of how users will use it.

    I started out vehemently angry with Nullable. Then i saw how people were using it and how it made thigns so much easier for people, and i’m much happier with how it’s going to ship.

    I also feel that it will integrate well with the future of C# and that having it in place now so that people can start using it in thier apps/systems is essential.

  21. CyrusN says:

    Stuart: Nope. Until PDC i can’t confirm or deny anything. I can say that we pay attention to the development and evolution of many languages (including C-omega), and we’re always thinking about how we can utilize research to make our own language better.

    And by all means, go ahead and start thinking about this stuff. You might get a kick out of what possiblities it opens up.

  22. damien morton says:

    Will the release of C# 3.0 be tied to the release of new versions of Visual Studio and/or SQL Server as this release has? Or will C# 3.0 be able to be released as a new compiler and some patches for VS.2005

  23. DrPizza says:

    "Starting from scratch isn’t an option. C# is here, and its’ here to stay."

    C makes breaking changes. C++ makes breaking changes. VB makes breaking changes (god, does VB make breaking changes…). Java makes breaking changes. All of these languages have considerably more LOC than C# and all of them have made breaking changes in their development. What the hell is so special about C# that means it can’t do the same?

    "I started out vehemently angry with Nullable. Then i saw how people were using it and how it made thigns so much easier for people, and i’m much happier with how it’s going to ship. "

    That’s odd; I’ve not seen a single demonstration of why nullable types as implemented in C# 2 are even remotely useful or desirable. Their syntax is inconsistent, and their null preservation in arithmetic is surprising at best, useless at worst. And to what end? To provide arithmetic like it happens in badly-designed databases (because well-designed databases don’t contain nulls)? Arithmetic that most people don’t actually understand anyway? Whoopty do. The useful aspect of nullable types could have been provided consistently and clearly with simple reference type wrappers (like Java). This would provide consistent syntax and consistent semantics.

    And even if people *are* asking for something, that doesn’t make giving it to them the right thing to do.

    "I also feel that it will integrate well with the future of C# and that having it in place now so that people can start using it in thier apps/systems is essential. "

    So you mean C# in the future is going to gain even more incompatible syntaxes and boneheaded features? Well that’s sure something to look forward to. Uh huh.

  24. CyrusN says:

    DrPizza: I never said that C# couldn’t make breaking changes. However, that doesn’t mean we can start from scratch and break everything.

    "The useful aspect of nullable types could have been provided consistently and clearly with simple reference type wrappers (like Java)."

    And this was rejected by customers because of performance issues. A simple reference wrapper is 2.5x times larger on 32 bit platforms, and even larger on 64 bit platforms. You often also see people transferring millions of these from the DB to the programming environment and the value type implementation performs decidely better.

    "And even if people *are* asking for something, that doesn’t make giving it to them the right thing to do. "

    Of course. And i never implies otherwise.

    However, it doesn’t mean that we can’t provide it.

    "So you mean C# in the future is going to gain even more incompatible syntaxes and boneheaded features? Well that’s sure something to look forward to. Uh huh. "

    Trolling is appreciated.

    I fail to see how the syntax is incompatible. And, as for "boneheaded" or not: if it’s not useful to you, then don’t use it. there are a surprising number of users for whom it will be useful and for whom we’ve gotten quite positive feedback from. Not all language features will benefit everyone.

    ANd yes, troll aside, it’s quite possiblet that the future stuff we’re looking at is stuff that you will not care for. c’est la vie. if our language isn’t for you but does work out well for a good majority of our users, then i’ll be quite happy. And, rather then jumping the gun and making premature assumptions about the future, i woudl recommend that you wait until actual information is made available.

  25. DrPizza says:

    "And this was rejected by customers because of performance issues."

    Sounds specious. It works for Java. And there’s a hell of a lot more enterprise systems using Java than .NET. The "performance" issues clearly aren’t an issue. And why would they be? It’s not like you’re going to be creating big arrays of nullable types; you’ll read them row by row, and so only create them one at a time. Assuming, of course, you let your database contain nulls, which, of course, you shouldn’t do anyway.

    "I fail to see how the syntax is incompatible."

    For value types "foo x" is non-nullable. For reference types "foo x" is nullable. Same syntax doing two very different things.

    "And, as for "boneheaded" or not: if it’s not useful to you, then don’t use it. there are a surprising number of users for whom it will be useful and for whom we’ve gotten quite positive feedback from."

    But you [should] have got the same positive feedback if you’d done things Java style, as it solves the same problem, just in a way that’s consistent with what’s already there. Of course, Java never had such problems in the first place, because Java never made the fundamental mistake of confusing between value and reference types. Their approach may not be perfect, but it’s better.

    IIRC you said in another post about nullable types how developers shouldn’t have to care about whether their objects are on the heap or on the stack. But that missed the point. Developers *should* have to care about whether they have value semantics or reference semantics. Because they’re not the same; values can’t be null, values use value equality, values don’t have a concept of identity distinct from their value. References can be null, references use reference equality, and so have a concept of identity that’s distinct from their value.

    C++ (amongst other languages) makes this distinction clear. If you want reference semantics you declare something as a pointer (no, pointers do not mean "stored on the heap/free store"; they mean "reference semantics"); if you want value semantics, you don’t (and likewise, this implies nothing about the storage). The distinction here is explicit and unambigious, and every type that can be constructed can be constructed with either set of semantics, depending on what’s appropriate.

    Java is not quite so clear, but because of restrictions it imposes, is not too problematic either; "primitives" always have value semantics, "classes" always have reference semantics, and there’s no way to interchange between the two. To promote a primitive to something with reference-like semantics you must create an instance of a reference type. It’s not quite so clear just because they look to most intents and purposes the same.

    It was decided, for some unfathomable reason, that .NET should blur the line between these things. Reference types could arbitrarily offer value comparison and so lose their sense of identity (with no indication of this apparent to the user) and value types could flit between reference-like and value semantics automatically. If the value vs. reference dichotomy were clearly and strictly enforced (as Java) then we’d simply user wrappers and there’d be no problem. If the value vs. reference dichotomy were non-existant (as C++, Smalltalk, et al.) then we’d either create references explicitly (as C++) or only ever have references anyway (as Smalltalk) and there’d be no problem. But C#’s "part time" reference types cause the confusion. They’re not reference types because they can’t be null… but they can be reference types because you can form references to them.

  26. DrPizza, I agree with much of what you say, although not all of it. One part I do have to take issue with though is your claim that a well-designed database would never contain nulls.

    In one very obvious (and common!) situation, forbidding nulls requires you to violate data integrity in other ways. Representing any kind of hierarchy in a database requires a parent_id field, which is a foreign key to the id field of the same table. If this field is NOT NULL, you can’t put that foreign key in place, because it’s impossible to represent the roots of the hierarchy.

    In general, trying to avoid nulls entirely will only lead you to introduce other special values – empty string, 0, -1, 9999, whatever – to represent the fact that there is no real value present. Using this kind of special value introduces far more problems than null does. For example, if you accidentally attempt to use a null value as if it weren’t null, you’ll get an exception, but if you try to use a special value, your code will generally continue working and probably do something that makes no sense.

    It would certainly be possible for C# to do nullability *better* (making nullability and notnullability always explicit would be an improvement over the current implicit situation, and even better would be if explicitly-nullable types weren’t utterly broken as they are in 2.0) but claiming that "nulls are bad, period" – in coding OR database design – seems overly dogmatic. Nulls are bad if – and only if – a value is truly required in a particular situation. That’s a common case, but it’s far from always true.

  27. DrPizza says:

    "In one very obvious (and common!) situation, forbidding nulls requires you to violate data integrity in other ways. Representing any kind of hierarchy in a database requires a parent_id field, which is a foreign key to the id field of the same table. If this field is NOT NULL, you can’t put that foreign key in place, because it’s impossible to represent the roots of the hierarchy. "

    Then don’t represent your hierarchy that way. Represent it using nested sets instead of an adjacency list. Nested sets don’t require nulls.

  28. DrPizza: I’m unfamiliar with the concept of "nested sets" in the sense you’re describing.

    Can you explain what the "nested set" equivalent would be of a simple hierarchical structure like this:

    (

    id int identity not null,

    parent_id int null,

    name nvarchar(20) not null,

    sort_order int not null

    )

    with a foreign key constraint from parent_id to id on the same table?

  29. DrPizza says:

    Take a look at this article, for example:

    http://www.intelligententerprise.com/001020/celko1_1.jhtml

    Instead of storing the tree as a series of edge definitions (the {identity, parent_id} pair defining the edge between the two nodes) you perform a pre-order traversal of the tree, storing at each node its position in the traversal.

  30. That seems all nice and theoretically sound, but it makes some potentially common operations very expensive. Inserting and removing nodes in the usual representation requires only updating that record (and perhaps fixing up the sort orders of other records with the same parent id), but in a nested set representation it requires modifyng the lft and rgt columns of potentially the *entire table*.

    I work on a CMS that represents the page structure of the site as a hierarchy, and also supports eCommerce with a product category hierarchy – we’ve had customers already that have pushed both these tables into the thousands of records, and there’s no reason in theory why it shouldn’t be much bigger.

    I’m not about to implement an architecture which requires updating 5000 records just to add a new page or category.

    That’s even ignoring the fact that IMO the nested set representation is much harder to understand and reason about. If I saw that table in somebody’s code I’d never understand it without a link to an article which explains the representation. But anyone with any relational DB experience at all would understand the representation I use.

  31. DrPizza says:

    "That seems all nice and theoretically sound, but it makes some potentially common operations very expensive."

    It also makes some incredibly cheap, unlike the adjacency list. For example, if your hierarchy represents a parts list, the nested sets make it very easy to see the total cost of a part including all its constituent parts. Adjacency lists don’t.

    "Inserting and removing nodes in the usual representation requires only updating that record (and perhaps fixing up the sort orders of other records with the same parent id), but in a nested set representation it requires modifyng the lft and rgt columns of potentially the *entire table*. "

    Unless your hierarchy is huge and updated often (which for things like a traditional hierarchical product catalogue isn’t usually the case) that’s not a problem worth fretting over.

    "That’s even ignoring the fact that IMO the nested set representation is much harder to understand and reason about."

    It’s much easier to reason about, not least because it uses a set-oriented language (SQL) to perform set operations.

    "If I saw that table in somebody’s code I’d never understand it without a link to an article which explains the representation. But anyone with any relational DB experience at all would understand the representation I use. "

    If I ever saw the code you wrote to traverse your tree (for example, to sum all the children to tell me how much something costs) I’d probably say the same.

    Even if you insist on using an adjacency list, there are ways to store it which don’t need nulls; storing nodes and edges separately, for example.

  32. CyrusN says:

    Damien: "Will the release of C# 3.0 be tied to the release of new versions of Visual Studio and/or SQL Server as this release has? Or will C# 3.0 be able to be released as a new compiler and some patches for VS.2005"

    That information will be made public at PDC.

  33. AdamM says:

    I have to agree with DrPizza on the nested sets. We use them for our categorization on our site. While inserts and updates may be slightly more expensive than a traditional hierarchy; selecting out the data you need is far easier and much cheaper. Our admins our doing the inserts and updates, so performance isn’t a huge issue (although we’ve never had a problem with it anyhow). It’s our customers and users that are viewing the data. With that model, the nested sets make perfect sense.

  34. Another question about nested sets (since I really am curious about whether these could improve matters in my code – I have quite a few hierarchies in there).

    Even when selecting the data, the most common operation I do is probably selecting the direct children of a particular node. In the adjacency list representation, this is an easy "select * from page where parent_id = @whatever".

    Since the parent_id field is indexed, this is extremely efficient.

    What would be the equivalent in a nested set representation? I can see the way to get "all descendants all the way down" (although that still seems to need a join if all you have is the *id* of the parent) but not a way to limit it to direct children only.

  35. DrPizza says:

    "What would be the equivalent in a nested set representation? I can see the way to get "all descendants all the way down" (although that still seems to need a join if all you have is the *id* of the parent) but not a way to limit it to direct children only. "

    Perhaps do something such as Select subordinates whose indentation level is one greater then your current level.

  36. Keith J. Farmer says:

    Extension Methods.. we located this reference, in a paper by Lutz Roeder.

    http://www.old.netobjectdays.org/mirrors/stja.cd/GCSE99_Young/abstracts/Lutz_Roeder_gcseYR99.doc

    If this has *anything* to do with what Cyrus has mentioned, oh my god..

    (and insert the obligatory plug for MC# — moveable methods are too cool)

  37. kfarmer says:

    Actually, Extension Methods, as Lutz’s paper describe, seem a lot like the new ASP.NET expression builders. Well, expression builders on steroids…

    Fun, if true.

  38. damien morton says:

    Wow – looks like extension methods might be something akin to lisp macros and allow the user to define new syntax for their domain. Very cool.

  39. Keith J. Farmer says:

    So going on the theory that Extension Methods are a way to create a Domain-Specific Language (something MS is already experimenting with), that leaves Lambda Expressions and Expression Trees. Lambda Expressions sound like their Python equivalent. Expression *TREES*, however, sound like Lightweight Expression Generation. Essentially, declaring a non-compiled parse tree, and being able to pass it around or manipulate it, then using it as a template for evaluation. Something right out of my RPL days.

    If we consider Whidbey as an introduction to declarative programming (ASP.NET 2 DataSources, Generics, Avalon CTP, etc). Orcas could be taking it to intentional programming, as I understand it (creation of code generators, [hopefully] Cw query functionality).

    It makes me wonder what Hawaii’s going to be about. Again, I’ll insert the plug for MC#: the ability of the runtime to coordinate with other instances of the runtime on other machines, to act more or less seamlessly as a grid, would be a next-logical-step in .NET.

    For that matter, it makes me wonder what will succeed C#n, after they’ve had the chance to do the post-mortem on the first 2-3 versions.

  40. DrPizza says:

    What the hell’s MC#?

  41. Fede says:

    lim(version->oo) C# = ML