@Stilgar: We won't do something that feels like a breaking change. If that's the best we can do, we won't do it. I'm not hell bent on the nullability feature. I'm determined on chasing it all the way to the best we can possibly do. If that's not good enough, then we'll put the feature to rest knowing that it just doesn't have a place in C#.
@PurityControl: It's a great idea to allow functions with out parameters to be called as if they were tuple-returning, having the compiler do the magic like in F#. Another possible convenience is allowing a tuple to be passed to a function that can take the individual members of the tuple as arguments.
@N2Cheval: Sounds like a big feature. We'd probably need to see a somewhat more fleshed out proposal to understand what you are getting at. But I have to say that reifying more metadata at runtime is not the direction I see us going. On the contrary, with native compilation we are challenged by the ubiquitous access to even the metadata that is there today. But maybe I'm misunderstanding the proposal.
@Alex: I don't think it's borrowing from Swift as much as borrowing from the same places that Swift is borrowing from. :) However, I see Swift doing something we've also often done, which is to take concepts from less widely adopted languages and pulling them into the mainstream. Option types (or "optional types" as the Swift guys call them, which irks me because that used to mean something else) are a well known pattern from functional languages that Swift has - rather successfully I think - integrated into a more imperative setting, and found a way to blend with the legacy Objective-C libraries. That integration depends heavily on pattern matching to do the null checking (like in the functional languages it comes from). I don't think we have that option (no pun intended), because we already have established ways of checking for null in C#. Any feature we do here would have to recognize when folks are checking for null, rather than force them to do it in a new way. That would be a disaster!
@Stilgar: Those are our worries too, and one of the reasons we haven't done this in the past. I agree that '!' everywhere is ugly. I'd rather not have the feature than recommend that! Here's the way that I think about it:
I think nullable reference types is the most important part of the feature. Since this is new (and uncontroversial) syntax, it doesn't break anyone's existing code in and of itself - not even with a warning. They way we would make it work is, that if you dereference one of those - say a "string?" - we would give you a warning only if we can't see you checking for null. We will do a flow analysis similar to definite assignment, and if for instance you are inside an if-statement and have just checked that the thing is not null, then we're happy to let you dereference without warning.
This means that if you add '?' to any member, for instance, you will get warnings in the places where that member is dereferenced without first being checked for null. You can then go and insert null checks, and we will probably also have syntax to let you easily override if you know it is not null. (In fact we would probably use '!' for that - as in 'p!.Name', where 'p!' means p assumed to be non-null. (I suspect it will be known as the "dammit!' operator).
Non-null reference types are actually less important I think. They prevent fewer mistakes: they prevent assigning null into something. Ok. And they would prevent forgetting to initialize a member that's supposed to be non-null (but whose initial value is null) in a constructor. I don't think this warrants its own new syntax, especially due to the damage it would do to the beauty of code.
I think a number of people will want to say: well I marked all my nullable types, I think. Can you please check that I use the rest in a non-nullable manner? If I don't, I may have forgotten to mark some, or I may have found a bug.
I'm quite open to that check being opt-in - maybe it's even a Roslyn analyzer, not something the compiler does.
There's a lot more subtlety still. The design notes etc. on GitHub, however messy and as-you-go, are the best source of the full discussion we've had.
@aarondandy: this is a great observation. We've had a lot of design discussion around interaction between existing code (compiled without the new null feature) and new code, and we have some ideas for how to avoid situations like you describe. The main idea is that operations involving existing types (which are in a sense both nullable and non-nullable) do not generate warnings. Your program above would not yield a warning on the assignment you indicate.
This means that when it comes to interacting between todays null-unsafe code and tomorrow's somewhat-less-unsafe code we would sacrifice safety rather than yield spurious warnings.
@electricninja33: Yes, the pattern version of the "is" operator is another way to introduce a variable inside an expression. We need to figure out all the same things as we did for "declaration expressions", such as what is the scope for the variables etc. They are not exactly the same feature, though, and I can actually imagine us adding both.
@electricninja33: Some caution is warranted around unsafe and iterators/async. We may have erred too far on the side of caution, though, and blocking valid useful scenarios. Can you raise an issue with a bit more detail on github.com/dotnet/roslyn and maybe post the issue# back here to close the loop? Thanks a ton in advance!
@dcuccia: whoa, wanna save some good stuff for C# 8, right? ;)
@VivekRagunathan: glad you liked the duality bit. This has actually been a target of academic study for decades. Some good references may be found in this paper, written by some weirdo professor type I knew once.
@mjjj: We didn't initially realize the utility of this for invoking delegates or void returning methods, and our first prototype didn't allow it. We started out calling it the "null propagating" operator, so if there was nowhere to propagate to, what would be the use? :). Luckily we got our minds on the right track, thanks in large part to community discussion on CodePlex, and tweaked the feature in the direction of "null conditional".
@T_D: Yes, ArraySegment<T> is that. It is barely being used, and we wonder why. We want something that is a little more general and efficient, and can for instance serve as a window onto unmanaged memory. We may or may not add language syntax for the type, or for the slicing operation. We'll see when our thoughts are a little further along.
@JohnLudlow: Great example! Especially when you think about writing the async version, right? At that point out parameters go from a bad option to not an option at all.
@r2dnb: we are actually excited about adding better nullability checking to the compiler. If you check us out on GitHub, you can see some of our thoughts on that.
It's not an easy thing, though, to add to a language that's out in its v6 already. It takes a lot of work for us to get it right, and that work takes time. But we are trying, and hopefully by C# 7 or C# 8 we will have worked it out and put it in the language!
We implemented await in catch and finally for C# first. It was exceedingly complicated, and the truth is we ran out of time to do it with high confidence in VB, just as some features also had to be dropped from C# at the last minute for lack of runway to do it well. I expect us to want to do it in the next version of VB.
For the record, a lot of the VB 14 features actually reduce the gap between VB and C#. Please check out the feature list on GitHub. Many of the new VB features were already in C#.
Whether to stay with VB or move to C# is ultimately a business decision you'll have to make based on the sum of factors affecting your specific situation. I can say that the value added to VB in VS 2015 is simply astounding: Lots of new language features, completely revamped IDE with refactorings, Roslyn analyzers and fixes, greatly improved debugging, etc., etc. From the core language experience point of view, this is the biggest renewal of VB in a long time.
You are right, the slides are broken. I've started to ask around to see if we can get it fixed.
The "good" news is that there isn't a lot in the slides. Almost the whole session is demo. The only slides with anything interesting in them occur before we start demoing, in the first few minutes of the talk, so you can just watch a few minutes of the video to see them.
I'll post back here if/when I learn that the slides are fixed.
Hey, I fully understand the concern that new short hands can lead to more convoluted code. There are many short hands we could consider adding to C#. We are extremely careful to only add ones that we think lead to more clarity in common code.
With any new opportunity to compact code, there's going to be people eager to overuse it. It's a bit of an organizational challenge to establish what good code looks like, and how these new features can be used responsibly, in a way that fits the culture of the company.
That said, we don't feel we have a choice but to evolve the language to improve developers' productivity and better meet new challenges. We try to take a balanced approach, so that C# can keep growing for a long time without collapsing under its own weight. But grow it will.
Thanks for all the wonderful comments, both good and bad ones!