New Azure Container Registry Features (June 2017)

I had the privilege of dropping in Mads Torgensen's office to get a sneak peek of what might be coming to C# 8. It did not disappoint! Here are some of the things he covered:
As always, the team would love your feedback!
This way of dealing with nullable refererences is...ingenious. I think. Will need to chew on a bit, but you definitely had a clever idea here. Good work!
He did say 'mad' Torgersen. :D
Never tried to understand explicit interface implementation. Concise explanation by Mads Torgersen!
@Ole Tolshave: This is basically how it's done in Swift, and it's really nice work with.
extension ext extends person { }
Looks more javaish
extension ext : person { }
Looks C# ish
Great work Compiler Team, Specially for Extension class and Default interface implementation.
I think Count() shouldn't be a property at all. I always thought of it as a verb - it has to "count" all the elements one by one, because after all we don't know the count on an IEnumerable, it has to be evaluated - that's not good for a property, which suggests you know it upfront.
And I think it makes sense that you now have a Count property on a List, and then there's the extension method which suggest it has to count everything (I know it probably doesn't if it can cast it to something known), but on other things you don't have a Count property when the size is not known, forcing you to think about what it does and be more efficient and maybe avoid using Count() at all.
Discussing this within our dev team...
We are already effectively using non-nullable reference types using Jetbrains' [NotNull] attribute, which gives similar Intellisense warnings.
Using the new non-nullable reference type option, this is a much simpler, language-integrated way of achieving this.
HOWEVER, how will an external method (e.g. from a third-party Nuget package) with the following signature be interpreted by a C#8 compiler?:
public string GetString() {}
Will this be considered non-nullable? If the answer is "it depends what it was compiled against", how would we know if that third party tool compiled against C#8, just by looking at the DLL/nuget package?
Suggestion: the non-nullable version should be decorated with the equivalent of the [NotNull] attribute to expose the intent to the package consumer.
What about code patching? This is absolutely essential for INotifyPropertyChanged and multiple different scenarios.
On the problem of backwards compatibility and gradual code improvement. What if you allowed a definition of the form:
int! a;
Paralleling the use of the '?' for a nullable type to explicitly indicate a non-nullable type. Then the compiler is free to issue warnings when it detects a possible use of a null value, without requiring the use of the compilation switch which will effect all declarations. This allows gradual code migration.
There could then be a compiler switch which selects whether to assume a 'plain' type should be assumed to be nullable, or not. With the initial release of the 8.0, this would be 'true'. A future release, this could be changed to 'false'.
Thats a lot of work to not say the words "Type classes"
@kcdiaz: He so did! And he's not the first. AND he won't be the last! :)
@vb123: I was deliberately avoiding the `:` syntax, so that we could use that if we ever do the "implement an interface" bit I speculate about at the end.
@david_n_m_bond: That is exactly one of the subtleties we are debating. To what extent should an assembly "opt-in" to being interpreted with non-null intent? If we choose that it should opt in, then the compiler can stick an assembly-level attribute there to that effect.
@Kryptryx: We very deliberately avoid having a syntax for "non-nullable". In the future, good code will mostly have non-nullable in signatures, with a sprinkling (10-20%?) of nullable. At least that's our working assumption. With our current plan, such code will be beautiful. With explicit `!`, that same code will look like it's swearing at you. It's better (we think) to have a beautiful future, and deal with transitional challenges outside of the language syntax.
I think there was a misunderstanding in the discussion about explicitly implemented interface methods.
As far as I checked, you cannot declare an explicit implementation as "private". I think the interviewer was actually thinking about "private" access modifier - while Mad(s) used it as a synonym for an explicit implementation.
I'd expect
extension X : Y { }
not
extension X extends Y { }
that is just add a new keyword like class, interface etc., but called extension
So a default implementation of an interface member doesn't explicitly add it to the implementing class if I heard that correctly. But what if I wanted to expose the default implementation as a public member of the class. How would I let the compiler know that I would want to invoke the default implementation? I hope it doesn't involve casting.
interface IFoo { int Bar() => 1; } class Foo : IFoo { // Bar() is explicitly implemented? // what if I wanted to make it public using the implementation? // will we have to do this? public override int Bar() => ((IFoo)this).Bar(); }
I guess I will have to see how nullable reference types works, for now I don't understand how it will work with existing code in the case when I have "string s"
I don't think checking for null everywhere is good. I really do not want to check for null everywhere.
If a reference becomes null then it's a really unexpected state, and the app will crash, which is OK.
Moreover, sometimes a reference is obtained from database or from a webservice call. In these cases compiler won't be able to figure out.
This look closer to Typescript Flow Control, and also Swift in the String? flag to identify that this variable can be null.
Overall, this is a cool thing.
Interfaces Default Implementation... mehhh, mixed feelings about it; meaning crossing some lines about Design Pattern? - What's the point of an Abstract Class then ? - of course, I understand 1:1 inheritance vs. multiple interfaces implementations within a class.
I am a big fan of C# and overall all this proposed upgrade is a good thing in my opinion. Keep up the great work!
Great work.
I'm not really happy with the new extension syntax though, have you thought of something like specifying full the full typename to extend?
E.g.:
public static class Extensions
{
public int System.String.LengthWithoutSpaces {
get
{
return ...;
}
}
Or just "string.LengthWithoutSpaces"?
I think that would make it more readable and eliminate the use of the extra "this" parameter for existing extension methods.
Also, I think interfaces should either have members that are optional to implement but throw a NotImplementedException, or link to another class to make the interface cleaner.
E.g.:
interface IPerson {
int CalculateAge() => AgeCalculator.CalculateAge
}
static class AgeCalculator : IPerson {
public int CalculateAge() {
return ..;
}
}
Having extension classes implement interfaces would be a great addition to the language. So, what about `for` instead of `extends`, it is already a keyword
```
extension Ext for Person : IEmployee
{
}
```
Guys, explicit interface implementations are not private. Please try to explain it another way. Calling it private creates confusion. The method is not accessible from an instance of the class but this does not make it private. Private access modifier is responsible for encapsulation, protecting invariants and all that jazz. Explicit interface implementation serves to allow two methods with the same name in different interfaces to be implemented separately and also to avoid API pollution with methods that are not needed or named inappropriately (think of Close vs Dispose on some classes where both methods do the same thing)
What was it Anders used to say about starting off each new language feature with a negative score before it could be added? A few of the recent additions in 7/7.1 feel a little bit corner-casey to me, however, I'm confident all four of the above will be really strong additions to C# 8.
Extension everything has been a long time coming, and is probably one of the most requested features since extension methods were introduced, but it looks like it'll be worth the wait to get it done right. I really like the new dedicated syntax for this, and can see a lot of thought has gone into future extensibility of it as well.
I'm also really impressed with the approach to solving the nullable reference problem. It's a tough nut to crack taking into account legacy code, but it definitely feels like the right way to go.
Hi @MadsTorgersen
Great talk and set of features for c# 8 great job guys, but i have one question about the nutshell of async feature that use some state machine to handle the states of the task that is basically an object, why we don't use an implementation of coroutines it i'll be much faster and super light and maybe it remove lot of complexity on how c# compiler handle async operations and maybe opens new perspective.
I'll say moving async as intrinsic for c#.
Can you guys please host a new Lang.NEXT. And let me know when and where so I can come :)
Please allow for state in extension everything. I do this already with System.Runtime.CompilerServices.ConditionalWeakTable<T> but it's really ugly, add some syntactic sugar here or at least tell me why you are punting on this. Is there something I'm missing, this is like a mixin at that point, right?
Examples:
https://www.infoq.com/news/2015/05/CSharp-7-extension-classes
Until I saw interface extensions I wanted duck typing so bad, now structural typing is dead to me :) I want to add interfaces after the fact.
Hi Mads,
Regarding the extension everything syntax; I too would prefer the already familiar notation.
Here my thought process:
The to be extended class is pretty much similar but not equal to an base class, while interfaces extended by the extension are similar to interfaces that get implemented into a concrete class.
So
public sealed class Human : Person, IPersonType
{
bool IPersonType.IsCompany { get; }
}
would be visually align nicely with
public sealed extension Company : Person, IOpeningHours
{
DateTime IOpeningHours.OpenFrom { get; }
}
while adding the next keyword expands seems a little pointless to me.
Where is the Extension Everything proposal on GitHub? I cannot find it anywhere.
Also, for Extension Everything can the 'this' property be null as it currently can for extension methods?
Almost all the features seems really cool, the only point I expect never leave the paper is this Default Interface Implementation.
Interfaces should be a strict contract, Not something that you implement when you want.
If you are planning to bring the concept of multiple inheritance why not implement it using the class inheritance, or multi inheritance of abstract classes and let the interfaces serve their own purpose.
This is all very awesome. Default interface implementations would really clean up code where lots of interface functionality is optional, i.e. have default implementations like:
bool CanWrite { return false; }
Write(byte[] data) { throw new NotSupportedException(); }
PLEAAASE implement the extension everything for the next release and work towards extension interface implementations. I feel like if C# got a few more really awesome features like that it would become exponentially more powerful as a language. The type system needs more flexibility to allow better organization of code in "multiple inheritance" type situations.
One last question that is somewhat related - the framework and languages are almost 20 years old at this point and have evolved so much. Your religious devotion to maintaining backwards compatibility means there are lots of things in the framework kicking around that would have been done differently now that you have all these features available, some "mistakes" that can't be changed, and even things like class/member/interface names that are less than ideal.
Is there any hope of ever having a reboot "clean slate" release of .NET that fixes all these legacy issues and allows the framework to remove legacy cruft and get a makeover based on all the lessons learned up to this point without having to compromise for backwards compatibility sake?
Wow. Expansion Everything is a good feature.
Is wonderful.
Great work compiler team!!!
Really happy to see that new language features are added at a rapid phase than any other programming language , at the same time I am little scared that we are going to add lot of language features that are not going to get used frequently. Go forward compiler team but keep every steps carefully.
I really think that we should keep the keyword count as low as possible.
Think about this two points regarding extension class.
This feature implementation is really inconsistent with class and interface definitions. Please consider the point, before release. Once the language is released then we can't go back.
We are really proud of c#'s implementation of ":" compared to two keywords in Java (extends and implements ). Please try to keep it up.
I really started laughing when Mads said that this was going to help me by breaking my code :-) Might actually be true though.
I would vote for either
await foreach (var x in asyncStream) {...}
or else
foreach (var x in await asyncStream) {...}
It doesn't feel intuitive to me to say
foreach await (var x in asyncStream) { ... }.
Some great stuff here !!
Will we be able to write :
Class! instance;
to invoke the default constructor like in C++?
Also why add a new type syntax if default reference types are already nullable?
Adding a two new T? and T! syntaxes will risk making the plain T syntax obsolete.
Plain vanilla types should never become obsolete in the future, simple syntax should never become redundant over fancy syntax. Haven't we learned from C++. C# would have dodged the pointer bullet just to fall in the nullability trap.
Maybe it would be nice to have at least a compiler switch to enforce either nullability or non-nullablity for plain types in the future.
@vb123:it extends not implements, I think using ":" could be confusing because of it. And as Mads said, looks like this is on early researching phase.
I'm still waiting for multiple return values https://gobyexample.com/multiple-return-values, very handy language feature!
• Nullable References (opt-in)
• Async Stream
• Interfaces with Default Implementations
• Extension Everything
Fabulous!
I worked at a company that had another team with a guy who he (and his team) had a lot of amazing, powerful enhancements to C#. Some of these C#8 features are reminiscent of the work he did, although I'm sure very different. Yay!
They did a lot of other things that may be very suitable for C# and the runtime to consider incorporating. Such as contracts, safe native code, distinction between bugs versus errors (and recoverability), or even more powerful non-nullable references (as errors, not warnings).
The iterations went through names like Spec#, Sing#, and M#. I think those enhancements would be wonderful candidates to make it into mainstream C#. I can send you a link to his blog that discusses their discoveries.
For me, I've switched to F#. But I still think of C# as a powerful ally which has a lot of untapped potential.
The boundary between interfaces and abstract classes seem to be getting blur now. Only differentiation left would be the support of multiple inheritance which abstract classes don't allow.
@vb123: I second you for : in place of extends.
I would also prefer:
extension X : Y { }
over:
extension X extends Y { }
However, if you really need some keyword, how about reusing "for" instead?
extension X for Y { }
BTW. This also reads more naturally, and avoids confusion with Java "extends" keyword.
and in which version do you add anonymous classes?
@Carl Hjerpe
You missed this feature by a couple of years, it's been since C#7:
static (int, int) Boo()
{
return (1, 2);
}
static void Main()
{
var (x, y) = Boo();
Console.WriteLine($"{x}, {y}");
}
I'm with everyone above about using a colon instead of extends for extension classes.
extension PersonExt : Person
{
...
}
But your comment is:
I was deliberately avoiding the `:` syntax, so that we could use that if we ever do the "implement an interface" bit I speculate about at the end.
Why introduce lousy Java-style syntax now for a possibility of adding an additional lousy `implements` keyword in the future?
Why not keep the beautiful, C#-style colon and if - way down the road - you decide to add interface extensions, require the ugly implements keyword?
extension PersonExt : Person implements IEmployee
{
...
}
That way we can have a colon instead of `extends` (better syntax for now) and in C# 9 or 10, we have equivalent syntax when we add the `implements` keyword.
All of those are stupid, you should inherit to extend properties, you should use abstract classes for default implementations, and do I really even have to say anything about the stupid "nullable references"? If the developer is too dumb to check the reference first with the c#6 .? operator, should they really be a developer?
Here's what yoh should do instead:
1. Properties and methods of any null reference return null (make the compiler stick the .? operator after every reference)
2. Fix multiple inheritance of classes.
Don't mind my earlier comment, I saw the video, nullable types are gonna awesome.
Very genius!
Regarding extension what about alternative symbol syntax like:
extension Ext : Class << Interface
{
}
or:
extension Ext of Class : Interface
{
}
or anonymous extensions:
extension Class : Interface
{
}
Etc, etc...
@Carl Hjerpe - Multiple return values are already done in the newest version of C#, have you been asleep? Haha :P
@Rasik - Abstract classes are still quite a bit different than interfaces with default implementations as they are in the inheritance chain and thus can access protected members, override base class functions, etc.
Why not use the existing syntax with extensions, including the interface implementation? So just as...
public class Bob : Alice, IPerson {}
...reads as "Bob extends Alice, implements IPerson"...
extension Bob : Alice, IPerson {}
...would read the same way?
Will the default implementation of interfaces be like Type Classes in Haskell? There is a minimal implementation in Haskell.
interface IComparer<T>
{
Eqaul(T a, T b) { return !DoNotEqual(a,b); }
NotEqual(T a, T b){ return !Equal(a,b); }
}
User is forced to implement one of the methods. The other one will be implemented automatically.
The nullability warning can easily lead to false negatives in a multithreaded application. E.g.
string? s; void SomeMethod() { if (s != null) { // another thread nullifies s, but the compiler does not produce a warning for the next line s.Length; //NRE } }
Default interface implementations are really great, tackling both the multiple inheritance ambiguity problem and the unnecessary code duplication that is now necessary.
Extension interfaces are a genius idea, they are actually a game changer in design patterns implementation.
Keep up the good work!
@Zeleps: Anyone writing multi-threaded code should recognize immediately that the code you posted isn't thread safe. I don't really see that as a nullability issue. The compiler isn't designed to stop you from writing bad MT code that can do all sorts of bad things.
Extension interfaces would be amazing.
Suppose we make int / double implement an INumeric interface? Would using the interface have any impact on performance? Would the compiler be able to avoid boxing?
If extension interfaces worked at compile time, but not runtime (dynamically), that would be good enough for me.
Whats difference between IAsyncEnumerable<T> and List<Task<T>> in foreach case ?
I hate extension properties. They turn the code into a den of lies and scare programmers out of learning how to responsibly edit someone else's code. I will fire anyone who uses them.
The reason why i admire C# so much is, that the people behind it always think about how to support the development process and quality. It's not just "syntactic sugar". NullRefs are the most annoying things in modern languages. It makes you look stupid as a dev although it can be very subtle and hard to find.
Great job!
I throw in a vote for sticking with familiar syntax when considering extension everything:
public extension Employee : Person, INotify
i.e. The only thing that needs to change is "class" to "extension".
Is there a reason why this wasn't part of the discussion? I'm sure that there's a reason why this was rejected during these discussion, but I'm not seeing it.
I'll also be honest: The non-nullable reference proposal made me cringe a little when thinking about all the 3rd party libraries we use suddenly showing warnings. I guess we'll have to wait and see on that one.
Wow, that's really awesome! Especially the nullable referances and the Extension Everything feature! I'm not a big fan of the default interface implementation, but I just hope it won't be used too much in favor of abstracts.
So, C# is on it's way to act and feel more and more like Visual Pascal aka Delphi, but more efficient, elegant, modern and complete.
Thank you both for the nice presentation. Nullable reference types changes is my favorite, I am looking forward to it.
Extension methods by far best of discussed features. One could extend third party class at any point without need to wrap it and replace use with own class in whole project for tiny addition.
Other features not so hot. I still don't see what problem the nonnullable reference types bring. Most data comes from outside such as Db or dynamic sources and can be null. I guess it can be filtered out if must be nonnull but often I see a lot of optional data so now reference type usage will be littled with extra ?!
Default interfaces, feels will be restricted to use what is available in interface declaration, which is good. It can often times be left empty yet allowing to expand the interface without breaking backward compatibility. It is not a feature to be used as truly base implementations, but it will be by evil people))
The async streams, I have still not embraced async idiom fully and prefer to have control over what is going on instead of hoping that async will deal with all parallelism and queuing magically, so I don't see any use for this addition yet.
When you talked about nullable reference types I instantly thought about default values. The default value of `string` used to be `null`. It makes sense to me that the default value of the nullable `string?` would be `null` too. But as a result the default value of `string` should consequently NOT be `null`, but that would break existing code. So is `s` in the line below gonna be `null`? And is it going to give me a compiler warning?<br><br>```<br>string s = default(string);<br>```<br><br>And what type is `s` in the line below? `string` or `string?`<br><br>```<br>var s = default(string);<br>```
I would like to see a foreach distict looping mechanism. For example:
foreach distict (ForeignKey fk in myTable.ForeignKeysOnTable)
Avoid math.pow() create ^ or **