_From @jherby2k on March 7, 2018 19:35_
I can't find any information about a .net standard 2.1.
I really want to use the new Span-ified methods like Stream.Read in my class libraries, but it looks like that stuff isn't in System.Memory but rather the .net core 2.1 SDK. Any other way to get these APIs, or do I have to wait for .net standard 2.1. And is there any ETA on that?
_Copied from original issue: dotnet/coreclr#16806_
_From @danmosemsft on March 8, 2018 0:0_
@ahsonkhan are these in OOB packages?
_From @ahsonkhan on March 8, 2018 0:15_
I really want to use the new Span-ified methods like Stream.Read in my class libraries, but it looks like that stuff isn't in System.Memory but rather the .net core 2.1 SDK. Any other way to get these APIs, or do I have to wait for .net standard 2.1. And is there any ETA on that?
You do not have to wait for them to be added to .net standard 2.1 if your applications can target .NET Core 2.1.
are these in OOB packages?
The System.Memory package (which contains Span/Memory/etc) is available OOB (for full framework and older version of .net core (like 2.0), and it complies with netstandard1.1 so can be used on any of the platforms that meet netstandard1.1+ spec.
The new overloads being added throughout the BCL, like the Stream methods, as part of the "Spanification," are only available starting on .NET Core 2.1, as far as I know. So those ones are not in OOB packages.
I can't find any information about a .net standard 2.1.
Can you help address this, especially if I missed something?
cc @terrajobst, @KrzysztofCwalina, @stephentoub
_From @jherby2k on March 8, 2018 3:39_
But i'm writing a class library, not an application, and targeting .net standard as per Microsoft's recommendation. So if i want access to these Stream APIs (my library does a ton of file IO and parsing) i'm pretty much going to have to wait indefinitely, or target .net core 2.1 and forgo netfx support? Disappointing.
_From @Joe4evr on March 8, 2018 7:3_
But i'm writing a class library, not an application, and targeting .net standard as per Microsoft's recommendation.
Yes, I've been wondering myself why there are methods in netcoreapp that aren't available in the equivalent netstandard TFM. Basic things like ConcurrentQueue<T>.Clear() not being available in any .NET Standard (while ConcurrentStack<T>.Clear() is available everywhere) is what boggles my mind the most.
Even if there was a netstandard 2.1 the only thing that would implement it on day one would be .NET Core. It takes time for new standards to be implemented so regardless so I’m not 100% sure what your nuget package was going to run on in the short term anyways.
Well, yes. Another way of phrasing my question would be “when will spanified APIs make their way to full framework?” It sounds like there is no plan to do so, which is very disappointing given the enthusiasm Microsoft displayed when announcing this stuff.
@jherby2k Right now we're focused on successfully delivering .NET Core 2.1 (including the Span work). So while it may be fair to say that "there is no plan" it's more that "no plan has been made" (as opposed to "we plan to not do it"). So I'd amend the statement to be "there is no plan yet".
Link to related mono project issue mono/mono#6845
Most people would assume that new stuff that goes in .Net Core will also get put in .Net Standard and that the version numbers are in sync, so that new stuff in .Net Core 2.1 will go in .Net Standard 2.1. This is just so natural that it would be a working assumption of .Net users, and presumably also of people working on other .Net platforms and on .Net Core itself. Please tell us if that's not the case. If it is the case then it's a de facto plan already, just awaiting official confirmation and scheduling.
While the only implementation that supports the Span APIs is .NET Core, it doesn't make sense to have them as part of any standard. As soon as another implementation adds support, whether that be .NET, Mono, Xamarin or whatever, then there is a need for a Standard profile to cover it.
The counter to that, I suppose, is that since other implementations adding Span support is pretty much a given, it's annoying that we're currently publishing NuGet packages tied to netcoreapp2.1 and will have to republish when netstandard2.1 becomes available.
Having watched a couple of API reviews over streams, though, I do understand why the work needed to add them to a Standard is being deferred until Core 2.1 is released :trollface:
Are the new APIs available on UWP (6.1 or whatever version)? If they are, it is a good reason for a .net standard 2.1. If not, its very disappointing.
I know that .NET standard was kind of retrofitted over the current frameworks, but going forward, shouldn't the standard be established first? I mean, if its truly a specification, shouldn't the specification be agreed upon prior to implementation? It would also give non-MS implementations (i.e. mono) something concrete to target for their future releases.
Same issue for me, but looking for System.Runtime.Caching (ported to core2.1, dotnet/corefx#14529) for extending tagets supported by a library (nhibernate/NHibernate-Caches#38). I would rather add a netstandard2.1 target than a netcoreapp2.1 target, even if at first only .Net Core will implement it.
This issue makes for a very sobering read.
I dare say that the new Span<T> and Memory<T> APIs are going to be deal breakers for many people in many circumstances.
If they are only available in .NET Core for any extended period, then quite frankly what's the point in using .NET Standard, or the .NET Framework for that matter, any longer? These types are fast becoming a cornerstone for high-performance code, and I for one want to use them in my libraries. Hence I'm forced to target just netcore2.x in order to do so.
Alternatively, I won't use these new types in my code at all (just by themselves, without supporting APIs, they are about as useless as ArraySegment<T> was) and continue to use .NET Standard to automatically multi-target my libraries to several platforms. (That for me is the more preferable goal, over putting performance first.)
But there's no viable third way in my opinion. What I expressly don't want to do is to go back to manually multi-targeting different platforms, sprinkling #if FEATURE_SPAN_APIs across my whole code bases (libraries), and writing alternate code in the #else using traditional APIs in order to support Span-less platforms. .NET Standard (esp. version 2) was supposed to rescue us from having to maintain this kind of mess.
The new types, along with the C# 7.2 language enhancements, the JIT improvements, and the new APIs are hugely promising for performance and have been clearly advertised as such. Also, the barrier to entry was made to appear appealingly low by having the System.Memory package target .NET Standard 1.1. This alone suggested that JIT improvements and APIs would soon be added to the .NET Framework, too.
And now all of a sudden the word is that these new APIs are .NET Core 2.1 only for the foreseeable future?
That strikes me as either bad communication, or a very dissapointing decision.
@fredericDelaporte said:
I would rather add a netstandard2.1 target than a netcoreapp2.1 target, even if at first only .Net Core will implement it.
Exactly, doing so means that library authors don't have to go back, add more targets, and recompile once more platforms support the feature / API. A library will just magically support more platforms once they catch up and implement the given .NET Standard API.
That's a huge benefit to library authors, and the reason why Span and Memory APIs should become part of .NET Standard soon.
System.Runtime.Caching may not be a good example, as it appears to be already available for netstandard2.0 as an additional preview dependency. Same for Span<T> indeed. So even if they will not be in the standard, they should still ends up usable in libraries targeting the standard, provided they take some additional dependencies.
Any update on when .NET Standard 2.1 would come out? Also what features will it have that .NET Core 2.1 has? Specifically I'm looking forward to the HttpClientFactory and new Status Codes. If they aren't going to be a part of .NET Standard then I might as well switch over to .NET Core 2.1 now for the class library I'm working on.
Thanks
To add, it makes more sense to first agree on a standard and then follow that up by implementations.
Also, it's confusing to download dotnet sdk 2.1.200 but it doesn't support .net core 2.1 (just 2.0). One has to get dotnet sdk 2.1.300 to get .net core 2.1.
dotnet versioning is getting more complicated than it really needs to be.
@sidshetye see the version proposal at https://github.com/dotnet/designs/pull/29/files?short_path=579bdc1#diff-579bdc17733868e490e711c1245bb183
TL;DR the switchover to 2.1.* for the SDK happened and it's impossible to go back in time now. In the future, major nad minor version numbers of the SDK are going to match the .NET Core runtime version. So the first SDK supporting .NET Core 2.2.0 will be 2.2.100.
With the release of .NET Core 2.1 I went looking for info about .NET Standard 2.1. I didn't expect to find this.
"While the only implementation that supports the Span APIs is .NET Core, it doesn't make sense to have them as part of any standard. As soon as another implementation adds support, whether that be .NET, Mono, Xamarin or whatever, then there is a need for a Standard profile to cover it."
That is not how I expected .NET Standard to work. I expected it to lead the implementations (or probably to stay in sync with .NET Core since that seems to be the "primary" .NET implementation these days). This makes me feel a little like I'm reading .NET Standard's tombstone. I now fear it's always going to be a little neglected.
It certainly means Microsoft's recommendation that libraries target .NET Standard is no longer correct.
It certainly means Microsoft's recommendation that libraries target .NET Standard is no longer correct.
How is that the conclusion here?
How is that the conclusion here?
Well it means that libraries have to target .NET Core specifically instead of .NET Standard if they want to use these new APIs, right?
That's correct. If you want to use APIs that are only available in .NET Core then you have to target .NET Core. Span/Memory etc work in .NET Standard 2.0 applications though so they can be exposed without targeting .NET Core.
Now I agree to take full advantage of them you need to cross target to .NET Core 2.1 but I think the only difference here right now is that you have to cross compile for ns2.0 and netcoreapp2.1 if you want to expose APIs with Core APIs with Span in them (like a custom Stream) or use the netcoreapp2.1 APIs in your package implementation (this doesn't really bleed out).
ASP.NET does this today. We use Span and memory in a bunch of implementation and we also expose it in some tactical places where it improves the performance. You can absolutely expose first class APIs without yourself being cross compiled though.
@davidfowl but what is current perspective on this? Is .NET Standard 2.1 something possible after Mono will pair with .Net Core codebase? Or more realistic is to wait for .NET Standard 3.0?
@davidfowl My previous understanding went something like this: .NET Standard represents .NET. If you want to target .NET, then target .NET Standard. The latest version of .NET Standard represents the latest and greatest .NET. It does NOT represent the lowest common denominator. (Lowest common denominator would be the version of .NET Standard you need to target to get on to all the platforms you want to get on to).
But this thread makes it sound like the latest version of .NET Standard does indeed represent the lowest common denominator. .NET Standard isn't .NET. Rather, .NET Core is .NET and if you want to use the latest greatest .NET you have to target .NET Core. .NET Standard will stumble along behind somewhere perpetually out of date.
Doesn't this take us away from the idea of One .NET (.NET Standard) and many implementations of it back to one the old days of One .NET (.NET Core, or in the old days .NET Framework) and some weird out of date offshoots.
But why? Why not take these nice new APIs and Types, tie a bow around them, and call them .NET Standard 2.1? That's what I thought was going to happen.
If we rev the standard at the pace of the fastest platform, doesn't that defeat the purpose?
I don't think so. Like others have pointed out, releasing the standard first means we can continue to target only NET Standard and not any particular runtime for our class libraries, as well as firmly establishing the targets that other platforms need to achieve to "catch up" with the fastest platform.
Those are some of the advantages. I don't see any disadvantages in releasing a standard that only one platform initially implements. My expectation would be for .NET Standard 2.1 to be released concurrently with .NET Core 2.1 and then eventually some future .NET Framework version comes along that implements .NET Standard 2.1 as well.
I think a lot of the disagreement here boils down to a fundamental confusion about .NET Standard and .NET Core. Up until .NET Standard 2.0, Core was a limiting factor. Its API footprint was so small that the cross-target API had to basically conform to what Core provided. What you're seeing now is Core maturing and taking on it's own development arc. Just as .NET Framework, Xamarin, Unity, etc. can all add their own unique APIs that .NET Standard doesn't necessarily need to support, Core too can do it's own thing. If you want something in Core only, then you must target Core. This is no different than any of the other frameworks. If you want something that only exists in Unity, is it correct to complain that it's not part of .NET Standard? No, of course not.
Long and short, if you want to target .NET Standard, then you must accept that you can only use those APIs that exists everywhere. If you need something specific, then target what you need.
(Warning: This is going off a bit on a tangent. I don't think the discussion should go in the direction I'm taking here, but I'd nevertheless like to mention this as another possible implication of the present issue.)
@chrisdpratt: Well said. I do agree, but the thing is that ever since the ascent of .NET Core, the classic .NET Framework has been neglected. Sure, .NET Core can do its own thing and that's fine... but .NET Framework doesn't appear to go anywhere anymore these days. All the innovation is now appening on .NET Core. What I am worring about is that this innovation is not going to trickle back to the .NET Framework at a useful rate, and especially now that UI desktop framework support has been announced for .NET Core 3.0, I can see how the full Framework has begun its slow death march. The apparent unwillingness to add major new APIs to .NET Standard appears to confirm that this is indeed happening, and it's actively accelerating this development by pushing people away from supporting .NET Framework. (Advancing .NET Standard, OTOH, would be a cue that there's a plan to implement the new APIs on different implementations. And that cue is missing right now.)
My view here is of course very limited. There are other .NET implementations besides .NET Core and .NET Framework, TBH I simply don't know them well enough to make a more general statement.
@davidfowl As I understand it, one of the points of .Net Standard is to make writing libraries easier. The idea is that you just target the "right" version of .Net Standard based the APIs you need and target frameworks you need to support. But if I want to use an API that's in .Net Core now and will be in .Net Framework in the future, there is no version of .Net Standard I can target.
Instead, I have to target .Net Core 2.1 now, presumably multitarget .Net Core 2.1 and .Net Framework vNext some time later and finally switch to targeting .Net Standard vNext after that.
I think this approach is not making the life of library developers easier. It's effectively discouraging them from adopting new features.
Also, it doesn't necessarily have to be as fast as the fastest platform. But I think that being slower than the slowest platform is not the right pace either.
@chrisdpratt This is not about APIs that are .Net Core-specific. It's about APIs that are currently only in .Net Core, but will be included in other frameworks in the future. I think it makes sense to include such APIs in a new version of .Net Standard, even if those other frameworks don't support the APIs just yet.
So, if I understand this correctly, and based on this article. Are you saying that .NET Core 2.1 uses .NET Standard 2.0 as its foundation and just implements additional features beyond what is in .NET Standard 2.0?
So for example, I'm looking to use the new HttpClientFactory. I figured it would be in .NET Standard 2.1 since the shared common library I was creating targets .NET Standard 2.0 and that seemed to be the move Microsoft was pushing for us to do. Instead though HttpClientFactory is just going to be a feature of .NET Core 2.1, but it was built off of what was in .NET Standard 2.0? So really, I should having my shared library targetting .NET Core 2.1 instead of .NET Standard. Is that correct? I imagine the same thing will go for the new Http Status Codes being added.
Another question based off this page. What would the table on that page look like after .NET Core 2.1 is released? I also noticed the paragraph under the .NET Standard Versioning Rules header for the Immutable bullet point. Probably worth reading for everyone in this discussion that what David mentioned has been their intent for .NET Standard for a while.
@gehnster I don't think the table changes. The table says that .NET Standard 2.0 is supported in .NET Core 2.0 and higher. The table says the version for each platform where a specific version of .NET Standard support was added.
@svick:
Instead, I have to target .Net Core 2.1 now, presumably multitarget .Net Core 2.1 and .Net Framework vNext some time later and finally switch to targeting .Net Standard vNext after that.
Exactly. And as a library author, you can't actually afford to target only .NET Core initially. So either you don't use the new APIs until they're more widely available, or you write code twice and have lots of #if FEATURE_X stuff.
@stakx I feel the same way. That's why I called this ".Net Standard's tombstone". Microsoft never announces the end of something. They just ignore it until it goes away (moment of silence for Silverlight, XNA, and .NET Framework). You often have to read between the lines. That's what this feels like. Maybe .NET Standard was just a way to smooth over the migration from Framework to Core and will be neglected and eventually forgotten about. The changes in .NET Core 2.1 that we're talking about here seem like no-brainers for inclusion in Standard (we've already got these cool new memory types, lets update some APIs to actually use them). If Standard was healthy they'd have a 2.1 ready to go already. Even a 'it's coming soon be patient' would be something. I did not expect 'just target Core'. My Microsoft spidey sense is tingling.
@gehnster As far as I can tell, HttpClientFactory is an ASP.NET Core feature, which means it's supported on .Net Framework.
Specifically, the Microsoft.Extensions.Http package targets .Net Standard 2.0. And the primary sample in the HttpClientFactory repo targets .Net Framework 4.6.1.
My Microsoft spidey sense is tingling.
I couldn't have said it any better. 🤣
@stakx Maybe I'm writing a brand new library and I'm okay with only supporting .Net Core for now, but would like to support .Net Framework once it gets the APIs I'm relying on.
Or, if I am multi-targeting, I would like to muti-target versions of .Net Standard, to make my targets easier to manage. I don't want to keep switching which frameworks I target when the APIs I'm using don't change, only their support in frameworks. Also, I'd prefer to have a linear set of NETSTANDARD_x.y_OR_NEWER defines, instead of having to maintain a number of FEATURE_x defines.
I think we should consider developing an adaptive NuGet package with set of adapters/helpers that would allow people to write portable code, and then slowly transition to Net Standard when these new APIs become available there. For example, if you want to call Stream.Read(System.Span<byte> buffer), you would have to temporarily call:
```c#
// pseudocode
public static class SpanApiAdapters {
public static int ReadAdapter(this Stream stream, Span
#if CORE
return stream.Read(buffer);
#else
byte[] pooled = ArrayPool
int read = stream.Read(pooled);
pooled.AsSpan(0, read).CopyTo(buffer);
ArrayPool
return read;
#endif
}
}
IMO we shouldn't be making a new standard until platform owners agree on what goes into it.
@KrzysztofCwalina that doesn't work for all things. There are static methods that were added.
For static methods we would do:
```c#
public class SomeTypeAdapter {
public static ReturnType SomeMethod(...);
}
instead of calling
```c#
public class SomeType {
public static ReturnType SomeMethod(...);
}
or something like that. The point is that we would write the ugly #if deffed code once in a helper package ass opposed to everybody having to sprinkle their code with the if defs.
@svick: That may be the plan, i.e. adding these new .NET Core features into .NET Standard, but it's important to realize that each of these things has it's own development timelines. If Microsoft goes ahead and release .NET Standard 2.1 with support for a bunch of .NET Core 2.1 new features, it may seem like it doesn't affect anything because people can just keep targeting .NET Standard 2.0 for other situations. However, now, everything must eventually release these features before they can become .NET Standard 2.1 compliant. If that's impossible or not feasible for certain other frameworks, then either they get permanently stalled at 2.0 or you'd have to rollback the support of that feature in 2.1 (which you can't really do at that point because there's dependencies). In other words, Microsoft must be very choosy about what goes into a .NET Standard release, and generally, that means waiting until features are already universally supported. That's in fact how every release of .NET Standard has proceeded thus far, and I don't see that changing.
@BowserKingKoopa: That's not the situation at all. For one, .NET Standard is relatively new, so I find it highly doubtful that Microsoft is already considering changing course. Second, they're still actively promoting using .NET Standard, which they would not do if they had intentions on moving away. Again, this the result of a misunderstanding of its purpose. The development timeline is intentionally slow and deliberate. There should only be a new release when all the Microsoft frameworks push forward. It's all about targeting the least common denominator of functionality. You're trading bleeding edge for compatibility. You can just as easily choose bleeding edge and target something like .NET Core, but if you want the compatibility, then you must adjust your expectations accordingly.
In other words, Microsoft must be very choosy about what goes into a .NET Standard release, and generally, that means waiting until features are already universally supported.
As a consequence, library authors who want to leverage .NET Standard must also be very choosy about what new features they use, and generally, that means waiting until features are universally supported.
So why the big early fanfare (blog posts, magazine articles, etc.) about Span and Memory when these aren't ready for widespread use? If Microsoft wants people to adopt the new features, (IMHO) they should implement it in more platforms than just .NET Core... and only then start the fanfare.
I'll keep in mind from now on that .NET Standard is best better seen as the lowest common denominator of .NET implementations, instead of seeing it as their specification. I suppose this will prevent further disappointments in the future.
(I do not want to appear ungrateful. Span and Memory are great, no question about it. And for those people who are restricted to .NET Core for whatever reason, it's a great new tool available now. But for others, the current situation is potentially frustrating. It's a pity that Microsoft doesn't make a more concerted effort about the whole .NET ecosystem. Things are so fragmented these days, no wonder people are confused and misunderstand. This really could have been communicated better.)
P.S.: Here's the definiton for .NET Standard from https://docs.microsoft.com/en-us/dotnet/standard/net-standard. I see now that it's actually very accurate, but it's too easy to only read the first part and gloss over the second (emphasis added by me):
The .NET Standard is a formal specification of .NET APIs that are intended to be available on all .NET implementations.
(Obviously, that intention can change over time, so while it is a specification, it's not meant to be one that necessarily has to precede the implementations.)
"I'll keep in mind from now on that .NET Standard is best seen as the lowest common denominator of .NET implementations, instead of seeing it as their specification. "
Here lies .NET Standard. We hardly knew you.
IMHO, .net standard should have been built on CLR capabilities, not the extent of BCL implementation. Then new compiler and BCL features would just declare required level and single implementations could be used on all platforms.
This is not straight forward for library authors. The fact that .NET standard/core/framework/sdk are managed by different teams should be abstracted away from the eco-system. We're underway porting to .NET Standard but now, to borrow from above, our spidey senses are tingling :(
To me a standard is a specification or blueprint. So now ...

@gulshan can you elaborate? How would that work? How does that fix any of the mentioned problems?
@sidshetye the problem isn’t possible to make things “simple” things will always leak to library authors.
One of .NET’s major strengths is what also makes it hard for library authors. We have many implementations .NET and we don’t control the deployment of all of them. The .NET team also doesn’t control the pace at which each of the frameworks within our control ship (for e.g UWP ships on Windows). .NET standard tries to remedy that by picking a core set of APIs that must exist everywhere.
The more we change existing types within the standard, the more we have to rev it. The higher the standard you support in your library the less platforms you’ll run on, that’s why the guidance is usually to target the lowest standard (though I would recommend everyone pivot to netstandard 2.0 as the new baseline). This is also why we generally avoid adding things to the standard willy nilly. The more things that exist in the standard the harder it is to push everywhere.
Of course the other extreme to that is to freeze the standard and ship everything new as packages on top but that isn’t the plan of record either, we think there’s a middle ground.
Would you rather us just put out standards that didn’t run anywhere but .net core for however long that ended up being the case and things end up in other platforms when they get there?
I have a idea of this , but I don't know if it is possible.
current .net standard is just a api surface standard( this is good), I'm kinda agree @gulshan .net standard should have been built on CLR capabilities , but it may still not enough for library authors (CLR capabilities might can be simulate).
luckly for us, anything in .net is nuget package now, why can't we take advantage of this, make the .net standard indeed the api surface of the core dotnet , but not limited by the framework implement, if the framework has the lower version of an assembly ,then the application will download the newest assembly/package from nuget and use the newer version, and .net standard can keep update , library authors can only target the latest .net standard, and anything still work for older framework (this may make FDD became the SCD if the standard too ahead than the framework, for example if a lib target .net standard 5, and your app target .net core 2.0 , the FDD might produce same ouput than SCD, any assembly will from .net standard 5) , and this can solve the Span<T> and Stream.Read/Write problem , and the only problem will be : how to design NETStandard.Library
I can’t even begin to explain why this is much much more complicated than doing just that. I actually don’t know what you mean when you say that .net standard should be built on CLR capabilities. Can you clarify what that means concretely?
I think what you’lll find if you dig into specifics it falls apart quickly if you look at how .NET works.
The amount of bugs that we end up having to deal with because we have components that are packages on one platform but are “built in” to another platform is extremely high. Each runtime has their own different set of versioning and binding rules(see the chaos caused by ValueTuple and HttpClient). On top of that you end up in situations where referencing a random 3rd party library has now hoisted your blessed, well tested shared framework into your application’s bin folder (see .NET Core 1.x)
What I think .net standard built on CLR capabilities is, there would be several standards of CLR, each being subset of the later, like current .net standard for BCL. There can be a tiny CLR with no reflection, ref counting gc and other reduced capabilities. There can be separate CLR standards focusing on IoT devices, phones, desktop/laptops, servers/cloud, browser/wasm, bootstrapping etc. In compiler, language features then have to target a specific CLR standard. And BCL APIs also have to target a specific CLR standard. Then new language features and BCL APIs can be developed targeting existing CLR standards and all these new codes using these new language/BCL features will run on existing CLR implementations without any problem. When some language feature will need new CLR feature, it will be coded in a new version of CLR standard. All the platform interfacing like file system, networking, UI will be based on CLR standards. Then coreCLR, mono and other CLR implementations will just implement CLR standards and same Roslyn and coreFX will work on top of them. And when this Span is not working on Xamarin or UWP, it's because the CLR standard is not implemented there. Not because it is not yet implemented in their BCL.
My idea of .net ecosystem is kind of superficial. This is just how I feel it should be. And I may be wrong.
I can't believe that the code duplication between .NET Core, .Net Framework and Xamarin's frameworks can be justified any longer.
I believe that the following scenario gains extra points, after the .NET Core 3.0 announcement
The next "standard" will revolve around .NET Core 3.0.
Any IoT devices, phones (Android, iOS), desktop/laptops, servers/cloud will be different builds (flavors) of .NET Core 3.0
Libraries can target to one or more flavor
.NET Framework and Xamarins will collapse to nuget packages (to provide any platform specific code) supporting a specific .NET Core 3.0 flavor
@gulshan the idea is very pure but unrealistic. People need libraries to code against not intangible abstractions. Using nuget packages for also has terrible side effects and doesn't scale very well when talking about platforms. ASP.NET Core 1.0 had around ~300 packages in the 1.0 days and it comes with downsides and baggage that the majority of consumers do not like (slow startup because nothing is ngened, applications that are too big because of the deployment size etc).
We constantly question ourselves about what makes up the platform and it's not just GC and runtime features. Heck, it's not even OS features. A line has to be drawn somewhere and that line is arbitrary. The more things in the standard, the harder is it to push it everywhere (especially in the highly compatible .NET Framework). The smaller it is the less useful it is and the more nuget packages are required to even get a simple hello world working (see nodejs and left pad). There's a balance here and drawing the "correct" line is more art and less science.
The other thing I wanted to mention was that everything invented needs to be retrofitted on top of .NET Framework which is extremely easy to break. That's one of the many complications taken into consideration when designing something like .NET Standard.
Would you rather us just put out standards that didn’t run anywhere but .net core for however long that ended up being the case and things end up in other platforms when they get there?
Yes.
everything invented needs to be retrofitted on top of .NET Framework which is extremely easy to break.
.NET Framework could stop at .NET Standard 2.0. I didn't think any new features were going to be added to it anyway.
Also need a Standard 2.1 for Mono/Unity/Xamarin otherwise to use the new Spanified Stream apis etc when they are available your lib would need to target all the top level TFMs e.g. netcoreapp2.1, MonoAndroid, Xamarin.iOS, Tizen, Xamarin.iOS, Xamarin.Mac, Xamarin.tvOS, Xamarin.watchOS, ...
Lots of good back and forth on Twitter here, but needs to land here. @benaadams makes the point above of how many TFMs there are: tons. Here's my view as a library author, that wants to use many of these APIs:
If each of them start implementing the new APIs, we'd have to add those TFMs for those versions as they're added. Or users don't get our APIs (or the performant versions of them) on those platforms. How many do we add before it's unreasonable? 1, 2, 5? Every library author that wants to do their best has to rev the library (and version) for each TFM that comes on board. Let's go through the story:
Span<T> against a Stream (just as an example...new API usage)netstandard2.0 + netcoreapp2.1 TFM to use these APIsnetstandard2.0, netcoreapp2.1, uap10.1netstandard2.0, netcoreapp2.1, uap10.1, net48netstandard2.1 is created, adds the AIs we neednetstandard2.0, netstandard2.1It's a mess. Library authors need to wait for the platforms to add support, target each, bloat package size for n DLLs, and figure out testing. It means libraries lag behind each platform, they're not ready to go when it implements a standard. Then they need to clean up when a standard arrives. Is this a breaking change? Do they all need to rev a major version to do so?
Now, compare to netstandard2.1, if it existed: library authors compile against this. They could push to NuGet today. When a platform supports netstandard2.1, it just works. There's no cascading time table of dependencies, package bloat, or testing explosion (someone not implementing the standard correctly is a bug in the platform, not the lib). .NET Core 2.1 would be the easy-to-install testing target for most.
The lack of a new netstandard (at any point in time new APIs exist) will create the PCL problem again, the degree of which scales to how long we're in an intermediate state of awesome new APIs (really, great work - I want them), and the inability to have a consistent not-per-platform target.
I get the flip side: creating a standard too early without multi-platform buy-in is hard, if not impossible. It's a trade-off, a hard one, either way. But the ecosystem cost of waiting, just as we've gotten a ton of people moved to netstandard, may be substantial.
So the fundamental question here is - does .NET Standard, from here on out - lead, or lag? Suppose with N TFMs, only N-1 will implement some API, does that other TFM get left behind, effectively Windows Phone'd? What's the process to propose a new standard? Does it require buy-in, perhaps with timelines, or do APIs need to be implemented first?
Is there a subset of TFMs that would be considered "enough" to rev a new version? Or if it's not a number, reach? Or if not reach, growth? Say .NET Framework won't get Span, will that mean it's never in the standard? Or do you say - only the APIs that evolve and grow participate in new standards, but some lag, with gaps?
Has anyone given this any thought before now? Or are we at a happy accident because .NET Core 2.x added so many APIs?
or do APIs need to be implemented first?
Something would need to implement them first and be released (e.g. as .NET Core 2.1 has) as up to that point the apis may change due to understanding gained through implementation - whereas post release they are generally fixed in stone. However, that wouldn't rule out a simultaneous release.
My 2c. Its very expensive to maintain and even more expensive to update multiple versions of dotnet - Mono, full framework and core with all its operating system and platform variants. Just makes sense that MS focuses on one eventually and rationalizes the effort so everyone can get more done in dotnet core and spend less time supporting old stuff. netstandard2.0 was a great way to allow core to leverage all the existing libraries, now focus on the future?
Legacy libraries like System.Windows.Forms are being ported over and will run under core on Windows so we get a super fast core framework that is cross platform but can also replace the full framework everywhere else.
A bit of short term pain (encourage everyone to switch to core to get the new libraries) vs long term gain (a great foundation for the future).
A bit of short term pain (encourage everyone to switch to core to get the new libraries) vs long term gain (a great foundation for the future).
And what happens to iOS, tvOS, watchOS, Android, PlayStation 4, XboxOne, BSD in the meantime? They can't use any of the new apis until .NET Core supports them? What time period is that?
And there are still plenty of APIs in full .NET that .NET Core doesn't support. Why not WCF in .NET Standard? These are even APIs on the radar for support in Core, too.
Why would WCF be in the standard? It runs on top. The bigger the standard the harder it is to implement.
I think netstandard should lead us forward. My vote is for a netstandard2.1.
2 days ago Reply Jerome
Thank you Rich. I talked to you at the Microsoft Build and asked about a new LTS. I am very happy to see it announced today. Regarding the new features of .NET Core 2.1, such as the Span, I am wondering if there is plan to update the Net Standard to include them? I don’t see any mention of a plan for NET Standard 2.1. If I understand correctly, I can’t use today the new type Span inside a library targeting NetStandard.
1 day ago Reply Rich Lander [MSFT]
Correct. This will come but not with this release. You need to target netcoreapp2.1 in order to use span.
Thanks for stopping by the booth!
https://blogs.msdn.microsoft.com/dotnet/2018/05/30/announcing-net-core-2-1/#comments
And there are still plenty of APIs in full .NET that .NET Core doesn't support. Why not WCF in .NET Standard?
Presumably WCF could go over the .NET Standard, rather than be in it; unless there is something specific in .NET Standard missing that it requires and cannot be implemented on top of it? In which case it should be the smallest bit that enables it, rather than the whole shebang (as then everything needs to implement WCF itself rather than just pulling it from nuget and it being done for everything)
If I understand correctly, I can’t use today the new type Span inside a library targeting NetStandard.
You can use Span and Memory from .NETStandard 1.1 onwards by including the System.Memory nuget package.
However, you cannot call methods on BCL types (Stream, Encoding, etc) as a .NET Standard library; but you can use it for your own types.
I think netstandard should lead us forward. My vote is for a netstandard2.1.
Nobody here can define what netstandard2.1 should be, because you need to get some rough consensus of what the major platforms (desktop, UWP, Mono, and Core) are capable of and interested in implementing. It's not simply a matter of saying "everything from netcoreapp2.1 goes into netstandard2.1".
I think standard should focus on enabler bits, as @benaadams said regarding WCF.
If I was writing a framework that had to follow a particular API, I would define the API in an interface. Then my implementation would implement said interface.
I've not looked at how the .Net Standard is defined (it may or may not be an actual Interface) but why not? This might be a totally naive view, but I know if I was implementing Interface X from such a framework (say for the sake of my explanation there is an Interface for X in the .net standard) then I literally can't compile my implementation unless the Interface has been defined. Sure I can always throw "Not implemented exceptions" where I don't support those calls, but technically it would still be .Net Standard.
So I would love to see a .Net Standard 2.1 Interface. If .Net Core 2.1 implements it then it is a great starting point. My point is, there should be a contract that defines what .Net Standard is.
Looking at the .Net Standard chart, I note that .Net Core 2.1 is not listed there. Does .Net Core 2.1 implement .Net Standard 2.0? (Given that .Net Standard 2.1 does not yet officially exist).
I will go and research this now (and probably realise I have embarrassed myself).
As a concrete example; there is now these overloads for DeflateStream that is not usable by netstandard or netfx:
namespace System.IO.Compression
{
public partial class DeflateStream
{
public override int Read(Span<byte> buffer);
public override ValueTask<int> ReadAsync(Memory<byte> buffer, CancellationToken cancellationToken = default(CancellationToken))
}
}
If netstandard2.1 existed (with the Stream overrides) and it targeted that rather than netcoreapp2.1 then any runtime could have these overrides enabled for DeflateStream by using the nuget package
System.IO.Compression as soon as they implemented netstandard2.1?
CoreClr would have to implement netstandard2.1 as part of netcoreapp2.1 as obviously it is the first consumer of these apis.
I’m going to compare this situation to browsers.
-moz-** extensions. .net core 2.1+ can experiment bleeding edge here. My point is it’s a working model that can be adopted here.
I think @bradwilson's comment sums it all. The standard should lag behind i.e. be the least common denominator.
For now, let's assume the standard should lead on:
I have come to understand that .NET Standard must indeed lag behind early implementations in order to not be a potential block for adopting any future versions. Thanks @bradwilson and @gldraphael for making this crystal clear.
I agree with @gulshan that a more "partially overlapping API sets" approach (instead of .NET Standard's purely additive-only, "onion layer model") could theoretically have prevented this very discussion. ECMA 335 defined something called "profiles" (the kernel profile, the reflection profile etc), the API extent of which was documented using XML files. It is a pity that no mechanism was defined to better formalize this principle and tie it in closer to IL metadata. It would be nice if a .NET assembly had a way of stating in IL metadata, "I require the Kernel, Span, and Networking profiles versions so-and-so" and each runtime would be free to implement whatever profiles they can. You'd then have reference libraries per profile. I guess it would have been possible to solve the "partial type" problem along the way that has led .NET Standard to include certain methods that then throw NotImplementedExceptions on some .NET Standard implementations. (That is, different reference libraries should have a way of additively defining different aspects of the same type. Think partial type / member forwarding.)
That approach (or something similar) IMHO would've been superior to .NET Standard's additive onion model (which enforces "catch up or die" feature consistency across runtimes in the long run) but it is not what we have today, so "lag behind" it must be for .NET Standard.
Let’s just drop support for everything, netcoreapp runs all things everywhere. Xamarin now uses netcoreapp for iOS and android. Delete mono, delete .NET4.6.whatever. Fixed.
@stakx ah that’s the purist view that .net standard should be a set of core primitives and everything else should be a nuget package. That doesn’t scale either.
I would expect NS 2.1 to lead - to own the programming interface I use when writing libraries and applications. Knowing that NS 2.1 is a standard, and an interface, I would know that concrete platform implementations of this particular version are behind (to some degree, however with .NET Core expected to be the early / immediate adopter).
Targetting NS 2.1 then becomes a matter of verifying with a central registry whether the standard is supported on the required platforms. As the standard leads, I might be forced to target NS 2.0 until the platform of choice advances to NS 2.1.
Reading the comments, I think everybody can agree that NS 2.1 is not about adopting each and every API in Net Core 2.1. However, adopting critical types like Span<T> and essential API overloads where e.g. Span<T> has become a first class citizen is fair to expect.
Would you rather us just put out standards that didn’t run anywhere but .net core for however long that ended up being the case and things end up in other platforms when they get there?
I wouldn't necessarily expect the standard to lead, but perhaps follow the release cadence of .NET Core (as it seems the standard sources from .NET Core).
It's an interesting debate and I certainly empathize with both sides. I've spent the last 2 years championing NetStandard at my job; all our current libraries are 2.0. We have libraries in production now that work on Xamarin Android, Xamarin Forms, Net Framework and Net Core. We love it. Personally I think it's one of the best things MS has done for .NET ever.
But on Monday if one of my devs said they wanted to use Span they would have to go against our policy of using NetStandard2.0. We have to support NetFramework for about two years or so, so what do we do?
Indeed the standard has to lag behind, simply because that's how .NET in all its flavors is currently structured, i.e. there's not 1 overall .NET team, but a couple of them, and from the outside it looks like they have blocked each other on every communication channel available so reaching consensus is apparently difficult.
In theory I think it would be great if there's indeed a standard API which is implemented by all frameworks going forward, besides specific APIs outside this standard which only make sense for that particular framework.
In practice this currently doesn't work (as far as I can see) as Microsoft refuses to organize the .NET teams in such a way that it makes sense: .NET full is part of Windows, .NET core is a separate team, Mono is a separate team, UWP is a separate team and you have a couple of others too. So it's very hard to get a standard defined in a single place that the rest obeys to: they're separate kingdoms and likely want to keep it that way. You can simply forget this will change till Microsoft makes the internal changes, if ever.
So the only practical thing to do here is to have a lagging standard and this has the side effect that if a series of APIs is released in one of the standard implementing platforms (e.g. .NET core 2.1) you have to target that platform specifically as the APIs aren't in the current standard (as it lags behind). So a lagging standard has the consequence of a period of time where people like me and a lot of others can't utilize these new APIs because there's no standard to target which contains them. This gives a lot of friction (like the aformentioned #ifdef mess) and it's basically the same as before netstandard2.0.
This is a problem, but not without a series of solutions. It's also not a new problem that only occurs here. Anyone who ever wrote any OpenGL code knows about the dreaded extension system they have so driver writers like NVidia or AMD can offer specific features of their underlying hardware through extensions to the OpenGL standard so a developer can utilize them if present. This is a bit like the #ifdef workaround, you as the API consumer have to do all the work. I can assure you, it sucks.
Another solution to it might be the polyfill stopgap solution used in the JS world, where they need to program against a single API but are in reality faced with a myriad of browsers who all lag behind a standard somehow (sounds familiar? ;)). This might solve it till the standard is there. So in short, Microsoft could supply a .NETStandard2.0 compatibility pack which contains polyfill extension methods (one was proposed earlier in the thread) so you can target .NET standard 2.0 in your library, and you as the api consumer have a single codebase without #ifdef crap: that's delegated to the extension methods which fall back to regular code if the API isn't possible.
Dunno if this has to be in the form of an extension method library or a sourcecode only repo you can include. But it definitely could ease the development of libraries against newer APIs if the library has to target old frameworks which barely change like .NET full.
The other thing I wanted to mention was that everything invented needs to be retrofitted on top of .NET Framework which is extremely easy to break.
@davidfowl: Can you elaborate on this? Is this a backwards compatibility thing or are there more factors to consider?
(I can imagine larger applications like Visual Studio can benefit from the new memory APIs)
Dunno if this has to be in the form of an extension method library or a sourcecode only repo you can include.
I believe the C# compiler uses the defined method over de extension method, so when compiling against .NET Core the extension method is skipped. Still, any library should still contain #ifdefs because if you compile against netstandard you will always end up calling the extension method.
So it's very hard to get a standard defined in a single place that the rest obeys to: they're separate kingdoms and likely want to keep it that way.
Yes, there are seperate kingdoms, but don't forget the .NET implementations you mentioned are not the only .NET implementations.
The overarching question (in my oppinion) is, when are we going to see Span<T> and related overloads being adopted in NS 2.1? What's the release schedule for NS 2.1?
As it seems the standard sources interfaces and types from .NET Core, the team responsible for writing the standard (NS) could provide the community with a guidance for the adoption cadence (like a SLA). Also, and probably more important, the NS team could provide early guidance to the community about which APIs are planned for adoption (if any - a minor release of NET Core doesn't necessarily result in a minor release of NS).
This would help the community with a planning timeline for when to expect NS 2.1 after the release of NET Core 2.1. Once NS advances, it's like that only NET Core supports that standard with remaining platforms adopting at their own pace.
Let me emphasize that the comments I've made are correlating NS 2.1 and NET Core 2.1 to state an example; I realize that a minor revision of NET Core doesn't necessarily change the NS.
Is there a point of a NS 2.1 that has the "Spanification" of system types, if neither of .NET Framework and Xamarin going to implement them ?
Keep in mind that neither of those platforms support the fast Span type yet and their is no announcement that is going to be supported in the foreseeable future.
@DamienDennehy that's great to hear!
But on Monday if one of my devs said they wanted to use Span they would have to go against our policy of using NetStandard2.0. We have to support NetFramework for about two years or so, so what do we do?
To nitpick a little, you can use span, you cannot use all of the APIs that take Span which severely limits it's usefulness but not completely depending on what you're doing. BTW this choice has always been the same as a library author. The newer the APIs you want to use, the less places your library runs. At some point in the past the API you wanted required a higher version of .NET Framework and your clients were stuck on the lower version (remember, LINQ required 3.5 and async required .NET 4.5?). The choice is no different here. Assume we had a 2.1 with Span goodness, you have 3 choices.
@FransBouma as much as I disagree with your sentiment, that's not completely incorrect (the specific team layout is). Don't think of it just as different .NET owners though, think of it as different platforms that embed .NET. They are all on their own timeline because they are different products. I can't tell if you're suggesting we tie the ship schedules of unrelated products together but that's a non starter.
Another solution to it might be the polyfill stopgap solution used in the JS world
Polyfils would help a bunch but they wouldn't get to take advantage of Span, they are just there to remove the ifdefs. They could actually be much less efficient that the ifdef depending on what the implementation looked like. Here's an example (https://github.com/dotnet/coreclr/blob/e7ad6110bfc1b888aceba9e0abbcbaae475517a8/src/System.Private.CoreLib/shared/System/IO/Stream.cs#L724). If you had an API that took a byte[] and you wanted to change it to Span<byte> to support native memory, you would be taking a slight performance hit on platforms that didn't have this implemented as you would incur this copy. You're better off using the array overload on platforms that don't support Span.
Still, it's an interesting thing to consider. It means netstandard 2.0 libraries that want to use Span carry this baggage of APIs around. Maybe shared source code is better than a compiled library (that way it's not another thing that needs to be versioned).
@Sebazzz
@davidfowl: Can you elaborate on this? Is this a backwards compatibility thing or are there more factors to consider?
(I can imagine larger applications like Visual Studio can benefit from the new memory APIs)
Everyone can always benefit from new APIs but the compatibility requirements on .NET Framework is extremely high. It's at a point where adding almost anything can break an existing application. That's mostly because of forced in-place updates but I rather not get into specifics there... The gist is that we break applications whenever we fix anything. We're at that point now (we've been there a for a few years).
@andersborum it's a fair question, and I don't have the answer. We should provide a roadmap for netstandard in general. That could help the with settling some of the angst.
I think @FransBouma's description of the situation is important - the current .NET fragmentation seems to be first and foremost a mirror of the organizational situation inside Microsoft, where each platform is managed separately and you need to get everyone's buy-in for any addition to .NET Standard.
@davidfowl,
@FransBouma as much as I disagree with your sentiment, that's not completely incorrect (the specific team layout is). Don't think of it just as different .NET owners though, think of it as different platforms that embed .NET. They are all on their own timeline because they are different products. I can't tell if you're suggesting we tie the ship schedules of unrelated products together but that's a non starter.
I think it's not a problem of scheduling or shipping dates - it's fine for different platforms to support different versions of the standard at different moments. The question is about getting sign-off on what goes into the standard, and getting that early.
The question is whether there are technical justifications for a certain platform not including a certain API: does it make sense for UWP to reject some proposed new .NET Standard API with an actual justification (aside from budget/priority/etc.)? It's hard for me to imagine that, although I may not have the entire picture. If it's not a technical discussion but just scheduling/priority/budget, then I think that ideally .NET Standard 2.1 would be agreed upon early across all platforms, released, and then each platform would implement at its leisure.
@davidfowl
@FransBouma https://github.com/FransBouma as much as I disagree with your sentiment, that's not
completely incorrect (the specific team layout is). Don't think of it just as different .NET owners
though, think of it as different platforms that embed .NET. They are all on their own timeline because
they are different products. I can't tell if you're suggesting we tie the ship schedules of unrelated
products together but that's a non starter.
No I was suggesting that MS should define a single team which defines .NET and all .NET implementations follow that / are part of it. Now every .NET implementation does what it feels right for itself, which is great if you as an outsider and consumer of their stuff only use that implementation. It sucks bigtime if you have to target multiple implementations. .NET Standard 2.0 helps with that, and now in the situation where it's lagging it again doesn't (as it's not leading but lagging).
Frankly I don't care how I have to think about how .NET is structured within Microsoft, whether it's a product or whether it's embedded, the end result matters, namely I as a developer of libraries have to target them so my users can use these libs on those platforms. With .netstandard 2.0 it was OK but now again it's not. I know I can embed Span<T> in my own code to make it faster but can't utilize .NET core's APIs around Span<T> so the effect is greatly mitigated.
So, whatever the perception is of .NET within Microsoft, it's irrelevant for people outside Microsoft as the people outside Microsoft have to work with what they got, however it is clear what they got is less ideal. Now Microsoft can give us a long list of mitigating factors, and sorry to say it, but you do that too, they don't change the fact the current situation is less ideal and above all, it feels like an artificial problem: Due to the fragmentation of the .NET teams and their own goals/agendas, there's no concensus about what '.NET' and the '.NET API' is, so every team adds their own stuff and we as outsiders have to hope in the end there's some sort of generic form of these additions that we can target instead of a list of platforms we have to #ifdef around.
FTR, I truly don't like how Microsoft organises .NET framework development at the moment, where the Windows team is in charge of a framework that is basically dead (as there is barely any change merged into it but many people depend on it). So devs who have to target .NET full are basically stuck in a situation where it's either staying put in the past or add a lot of #ifdefs or plan for abandoning .NET framework altogether. Yes, not your concern, but it is a concern for us.
Another solution to it might be the polyfill stopgap solution used in the JS world
Polyfils would help a bunch but they wouldn't get to take advantage of Span, they are just there to
remove the ifdefs. They could actually be much less efficient that the ifdef depending on what the
implementation looked like. Here's an example
(https://github.com/dotnet/coreclr/blob/e7ad6110bfc1b888aceba9e0abbcbaae475517a8/src/System.Private.Co
reLib/shared/System/IO/Stream.cs#L724). If you had an API that took a byte[] and you wanted to change
it to Spanto support native memory, you would be taking a slight performance hit on platforms
that didn't have this implemented as you would incur this copy. You're better off using the array
overload on platforms that don't support Span.
Hmm. The polyfills I had in mind were basically implementations with the #ifdef, so
public static void Foo(this OriginalFooOwner o, Span<byte> input)
{
#ifdef NETCOREAPP2.1
// code with span, so this simply calls the o.Foo(input) method.
#else
// code without span, the code you'd write on .NET standard 2.0
#endif
}
Us mere mortals then could use this extension method on our instances of OriginalFooOwner and on .NET core 2.1 this is compiled to use the code with span, on .net full it's not. So it helps avoid #ifdef bloat in ever codebase out there. Basically the same solution to the TypeInfo mess with the helper package so you could port code over easily without a call to the method to get TypeInfo everywhere.
Still, it's an interesting thing to consider. It means netstandard 2.0 libraries that want to use Span
carry this baggage of APIs around. Maybe shared source code is better than a compiled library (that
way it's not another thing that needs to be versioned).
I hope MS considers this, it would adapting the APIs more straightforward.
One thing I really have a hard time understanding is whether it matters to talk about how difficult things are and if that matters to anyone on this thread. I see a lot of “you are Microsoft you can do magic” sort of replies which are fair and maybe we shouldn’t talk about the tradeoffs in the decisions we make because they may be unsatisfactory for a number of people.
My goal here was to educate people and get feedback to help in our decision making. I hoped that by shedding light on why things are in the current state it would help people understand and potentially even help you help us think about things differently.
@FransBouma I know nobody cares about internal Microsoft structure and you shouldn’t but it doesn’t change the fact that .NET Framework is hard to update and that’s not because the Windows team owns it. I don’t want to bog you down with specifics on why some things are harder to port than others, and why the compatibility bar is so high for framework but it does fundamentally change how we think about things.
I guess the question I have is, if you don’t care to get bogged down with details about why things are hard, would you rather just see us make the decision and not talk about why?
Also the point about polyfills (in this specific case for span) is that the code can end up being more inefficient than not using Span.
@davidfowl - I do appreciate your explanations, and I understand that folks at Microsoft do not have magic wands to solve certain technical constraints. But they could certainly communicate better.
Let's remind ourselves how this whole discussion got started: Someone asked for Span-based APIs in .NET Standard. Span et al. are seen by many as a major addition to .NET, and yet noone from Microsoft has so far confirmed, or made an official commitment, that they will be added to .NET Standard and the .NET Framework. Instead, we're having this huge back-and-forth discussion. (It's a good discussion btw. but that's beside the point.)
Microsoft's apparent unwillingness / silence / non-commitment around adding them to .NET Standard or to the .NET Framework is a cue that Microsoft (however organized internally) has not yet considered adding them to CLI implementations other than .NET Core, hasn't figured out how to do it, or even worse, doesn't plan to do so (for whatever reasons). And given that the Span stuff is a major new feature, this is quite shocking.
Please, Microsoft, if you're going to add Span-based APIs to the .NET Framework and/or other CLI implementations, just say so and give the rest of us at least a rough timeline, so we know whether & when widespread adoption of the feature will make sense, or whether those still on NETFX should just start jumping ship now and migrate to .NET Core for good.
Btw. regarding a polyfill, it seems a little strange given that Span is all about performance: If every call to a Span API has to go through a polyfill (wrapper method) first, won't that just counteract to some degree the benefits of using Span in the first place? Sure, the Span benefits may vastly outweigh an additional call indirection that the JIT may even be able to inline, but Span + wrapper lib still seems like a weird combination.
Netstandard leads
Pros
Cons
Netstandard lags
Pros
netstandard will mean the library works everywhereCons
Based on these I believe there should be a hybrid approach:
1) When changes in netstandardX are closed, netstandardX++ draft should be opened
2) Innovators (typically .NET Core) submit patches that are discussed with other implementers
3) Around the time when driving implementer goes RTM the standard should stop accepting new features and possibly next draft opened
4) When most (or ideally ALL) implementers have working implementation the spec is marked as finalized
5) Only at this point new SDK with new netstandard TFM is published
This approach would basically mean that we throw library developers under the bus, but they are the minority and should be people that know more about the ecosystem than consumers (people just writing the apps). We should push them towards writing highly compatible code, so current recommendation of targeting netstandard2.0 is good. For those cases when people would like to take advantage of new APIs when available I'd recommend documenting multitarget approach by enabling optimized parts of code with feature #ifdefs:
<TargetFrameworks>netstandard2.0;netcoreapp2.1</TargetFrameworks>
<DefineConstants Condition="'$(TargetFramework)' == 'netcoreapp2.1'">$(DefineConstants);PLATFORM_HAS_SPAN</DefineConstants>
#ifdef PLATFORM_HAS_SPAN
// code with span
#else
// code without span
#endif
This approach sounds very reasonable to me, because even if netstandard2.1 was published at this point most libraries couldn't use it without multitargeting and ifdefs anyway since you'd drop support to all platforms but netcoreapp2.1.
@davidfowl,
One thing I really have a hard time understanding is whether it matters to talk about how difficult things are and if that matters to anyone on this thread.
I personally do find it relevant and interesting to understand why things are the way they are, including the organizational aspects - it does seem important to this thread (even if it shouldn't be important to outside consumers). I also think this discussion is critical so that Microsoft get proper community feedback and go down the right route. I definitely don't expect Microsoft to do magic and I realize how complicated things must be internally with so many stakeholders etc., as well as the very high compatibility bar with .NET Framework (even if I'm not super knowledgeable about the details and am not sure why an additional new API such as Span support would be so risky, assuming it doesn't touch existing APIs). We're all technical people so we tend to treat budget/organization/marketing aspects with a bit of disdain but they're very important.
I agree with the above comments that Microsoft should communicate better on a long-term vision for .NET - but of course that requires that vision to exist within Microsoft and be validated across the different units. It's true that nobody knows yet whether the Span APIs will one day arrive to .NET Framework (or the other platforms), and the general future status of .NET Framework is unclear - is it basically now in maintenance mode only, like how Entity Framework 6 is to Entity Framework Core? It would be good to have this visibility outside Microsoft.
@davidfowl
@FransBouma https://github.com/FransBouma I know nobody cares about internal Microsoft structure
and you shouldn’t but it doesn’t change the fact that .NET Framework is hard to update and that’s not
because the Windows team owns it. I don’t want to bog you down with specifics on why some things are
harder to port than others, and why the compatibility bar is so high for framework but it does
fundamentally change how we think about things.
That's fair, and I know backwards compatibility / don't break things in .NET Full is a major goal for it and limits things greatly. However it doesn't make things impossible nor does it make it an excuse to accept the current state of affairs how things are organized. What I meant with the remark regarding how things are organized is that if there's a central '.NET team' which basically dictates what .NET is (the BCL etc.) and all other frameworks take their slice of that, it also makes things possible like defining .NET standard ahead of implementing it. It's now up to the direction of the wind what's going to happen, if there's ever something going to happen.
One of the reasons .NET core was created was precisely because there was little to nothing possible in .NET framework, if I'm not mistaken. All these years later and we're basically at a Python 2 / Python 3 point in time, where supporting .NET Full is actually a burden and will hold you back a LOT, if not today then definitely tomorrow.
I'm not trying to imply you personally are the reason this is the case nor can change it with a simply action, it's the organization 'Microsoft' that can do so and whether they will is anyone's guess. What I'm trying to say here is basically we as lib devs are currently again facing a choice we don't want to make but soon have to make and IMHO it will hurt everyone: us devs but also our users. If we don't move forward, we'll take a hit because customers will demand we will support the new stuff. If we do move forward we abandon our users who need to stay on the old framework / APIs. So this forces us to basically maintain 2 forks of our libraries: one for .NET standard2.0 and one for .NET Core 2.1.
I don't have to tell you that _that_ is a sucky situation and I truly wonder why Microsoft made this happen. But whatever the reason, I'd rather see that this gets resolved without us devs having to maintain 2 forks of our work, but just 1.
I guess the question I have is, if you don’t care to get bogged down with details about why things are
hard, would you rather just see us make the decision and not talk about why?
I'm developing software for the Microsoft platform since 1996, and one thing I've learned is that all the explanations of 'why' things are the way they are have no effect on finding a solution for the particular situation. It's not up to us what will happen, you (as in: Microsoft) know what problems we're facing now and it's up to Microsoft to find solutions for that in the .NET space as Microsoft alone controls who decides what and when wrt .NET APIs, net standard etc.
Microsoft will make a decision (or not taking a decision) and what the reasons for that decsions will be is IMHO irrelevant: whether we know that or not won't change it.
I think unfortunately the dotnet ecosystem here is suffering from the effects of a problem that is likely impossible to unroll, and that is the fact that each platform is extremely wide instead of being relatively narrow.
In the strictest sense, while the new Stream APIs that take Span<T> aren't themselves yet part of a standard, the code that implements them is totally or very nearly netstandard11 compliant, since Span<T> is part of that standard. So, technically, these APIs could run on any of the platforms, _if_ the platforms hadn't already implemented a Stream type. But they do, so here we are. This idea that each platform tends to specify its own implementation makes the JS idea of polyfills extremely problematic, and in the CLR world you don't have prototypal inheritance to help with monkey patching existing types like you do in JS (which is, frankly, a good thing).
Sure, looking at just this single set of APIs, it may seem very important to rev to netstandard21 to include them, and let every other platform catch up. But it isn't that easy, because these are not the only new APIs in netcoreapp21. Do you include them all? What does that mean for each platform's schedule or goals? From a management perspective one platform can't dictate that through strongarming the ecosystem by pushing a new netstandard.
I'm not 100% sure I get the confusion here, but I've also been writing against netstandard since the 1.x days, and it was made very clear then that the standards were a subset (not a superset) of APIs _that already exist_ that are available on a number of platforms greater than just one. Therefore, the standard by it's very nature has to be behind the bleeding edge. That's why it's the bleeding edge.
This is grim. I thought by calling this thread "Standard's tombstone" maybe we could save it. Like how Scrooge sees his own grave and decides to take a different direction in life. But this is grim.
Was there no vision for how Standard might progress beyond 2.0? Maybe it really was just a short term compatibility thing for bridging the gap between Framework and Core. There are probably tough decisions to be made about what goes into Standard, but this isn't one of them. New APIs that make use of Types we already have sound like a perfect little Standard 2.1 (or 2.0.1, something that keeps Standard alive).
Now i'm having my own vision of the future. I see myself targeting .NET Core going forward. ifdef'ing for compatibility. And one day, a few years from now, I'll stumble upon a blog post about how .NET Standard has been cancelled and I'll think to myself 'That sounds familiar, what was that again? Oh nevermind.'
And one day, a few years from now, I'll stumble upon a blog post about how .NET Standard has been cancelled and I'll think to myself 'That sounds familiar, what was that again? Oh nevermind.'
I think we need to take a step back and take stock of just how much progress the Core team and contributors have made with 2.1. Just because the shiny new APIs everybody wants aren't yet in a standard (that is supposed to represent a widely deployable spec) doesn't mean that netstandard is at all dead.
I think some of these comments tread very close to a sense of entitlement about these issues, and are not taking a realistic view of how large scale multi product collaboration works.
.Net Standard has _never_ been about having the latest and greatest. It has always been about having the most platform compatibility.
.NET Standard 2.0 was a great step forward, but it was rooted on APIs that were already old when the process started, it lacks any of the modern APIs that developers would like to use and this causes the problem articulated by many above - this is not a theoretical problem, it is an ecosystem fragmenting problem and we live this every day when we work with third parties that need to build code for multiple runtimes.
In an ideal world, we would define the set of APIs that would be on .NET Standard 2.1, and these would into Mono (these days we are picking up a lot of the work for free from sharing code with CoreFX, some we have to do) and by extension those would flow into both Unity and Xamarin with minor work - this leaves the question about what to do about the Desktop framework, and that is a question for someone else to answer.
One thing that we should consider is whether .NET Core Libraries 2.1 is just the .NET Standard API we want, and embrace that. What this means is that Mono would get the surface area of .NET Core Libraries 2.1 and then those would flow into Unity and Xamarin.
As @DamienDennehy described his pov, here is mine from an enterprise dev perspective and that one is simple, pretty much everyone I work with, ignored .NET Standard as much as possible. Either target a specific framework or multi target, the reasons are multitude but boil down more or less to the following two main ones:
Maybe this view changes if you target more than .net core and .net fx, but for shared libraries for multiple enterprise programs, I had way less problems multi-targeting.
This is by no means criticism of .NET standard, but sometimes it's hard to forget the bad experience of .net standard 2.0 with .netfx.
One thing that we should consider is whether .NET Core Libraries 2.1 is just the .NET Standard API we want, and embrace that.
So .NET Core is the .NET standard? Maybe that's right. Maybe that was inevitable. .NET Standard is dead. Long live .NET standard.
I want it mention something that I keep mentioning above as a reality check. As a library author, you CANNOT willy nilly use new APIs and drop older platforms in the wink of an eye. You will ALWAYS have to cross compile to take advantage of new features. This is NOT new.
As a library author, you’ve hopefully already been doing this (it’s whg JSON.NET stil supports .NET20 for some strange reason).
That’s just to say when we add a new standard, you’ll be able to cross compile to a generic standard instead of a specific platform which is better but that’s the only difference...
You will ALWAYS have to cross compile to take advantage of new features.
And again: This statement is only true because .NET Standard does not lead, but lags behind the leading implementation. (But that's what has been questioned here so you're really just making an argument that this is how is has to be.) If it did not lag behind, it would actually be possible to use new features without cross-compiling. Your library just wouldn't be supported on platforms that don't yet implement the newest standard. But once they do, your library automatically runs on them. No #ifs required. (Of course, once you want to be nice to users and support the old platforms they still use, you start multi-targeting and #if-ing.)
I don't think David is saying that you can't _technically_ do it. He's saying that as a library author it's irresponsible to just drop platforms by going to an unsupported standard.
What if something widely used, like Dapper, decided to use this proposed new netstandard that only works on netcoreapp, and not multi-target? That would not be a responsible move as a library maintainer.
Everyone can always benefit from new APIs but the compatibility requirements on .NET Framework is extremely high. It's at a point where adding almost anything can break an existing application.
Not really worried about Framework; as its kind of its own standard (as Mono and Unity support net46x) - but its also the laggard.
So there is netcore2.1 which is ahead and netstandard2.0 and net461 which are at the same level. If netstandard revs at the same rate as Framework it adds nothing; but also leaves a big time hole between netcore moving forward and the standard moving forward.
What do platforms that rev faster than .NET Framework do?
Do they then additionally adopt the netcore TFM (making netstandard irrelevant, but also forcing them to always take every api in netcore); do they just advance for their own TFM - putting the cognitive load back on lib authors or do they wait for the next Framework release off in the mists of time...
You multi-target netstandard 2.0 and netstandard2.1 and ifdef where you want to use the new APIs
Don't see that as a problem; the problem is having to target every platform directly and then ifdef them all and also workout what is in each platform and what is not for every ifdef.
@benaadams
Don't see that as a problem; the problem is having to target every platform directly and then ifdef them all and also workout what is in each platform and what is not for every ifdef.
By defining and allowing use of netstandard2.1 you just transfer the need of knowledge of platform capabilities from library authors to consumers. I believe seeing netstandard supported by library should mean I can very likely run it on any _current_ platform.
By defining and allowing use of netstandard2.1 you just transfer the need of knowledge of platform capabilities from library authors to consumers.
The consumer directly targets a platform, they do not target the standard.
I believe seeing netstandard supported by library should mean I can very likely run it on any current platform.
Which is true. However, if that library additionally supported a later standard it would mean the library could automatically use newer apis if and when the platform targeted by the consumer supported that standard.
I take full responsibility for starting this thread. My original question was simply what was the ETA for .NET Standard 2.1 (and by extension a Spanified full framework). Sounds like I'm waiting on .NET Standard 3.0 / Framework 4.8, which are coming some time next year.
As to the satellite discussion, I don't completely buy the argument for why it needs to be a trailing standard. Having a leading standard would mean I don't have to repackage my netcoreapp2.1 library as netstandard3.0. For Microsoft, this means better adoption of the standard in library code.
Its worth pointing out that the "spanification" of a huge base of core API surface is a bit of an edge case, and things like this won't come up often. Usually new APIs can and will show up in nuget packages. So new standard releases might be rare anyhow.
The consumer directly targets a platform, they do not target the standard.
Yes, but they would have to be concerned about supported standard versions of the platforms they target when consuming libraries as opposed to seeing 'standard' and knowing it will work. Say we like a library and use it in asp.net core. If I tell the team to use only netstandard libraries I know that forever anything they use will be also available on xamarin. On the other hand if there already was netstandard2.1 I'd have to enforce netstandard2.0 rule and monitor the state of platforms we use and once caught up allowing the use of netstandard2.1.
Which is true. However, if that library additionally supported a later standard it would mean the library could automatically use newer apis if and when the platform targeted by the consumer supported that standard.
I understand this point from the view of a library dev and it would be great, but I'm worried about how it would turn out in the real world:
netstandard2.0 and netstandard2.1 or would they simply switch with message upgraded to netstandard2.1 - is that enough for them to realize they are dropping platforms not caught up yet? Right now you'd have to go with dropped netstandard2.0 in favor of netcoreapp2.1 which means you probably know what evil you're doing.At any rate I don't think either lead or lag approach is wrong - I personally prefer lag, but in reality it just shifts responsibilities and assumptions of inexperienced people around. What is needed is clear plan how to evolve and even if lag is chosen there should be a 'leading draft' spec or something that implementers can start adopting instead of just waiting whether others decide to implement apis that core added.
netstandard has historically been a lagging standard. I'm not sure why people suddenly thought it would become a leading standard.
It is irresponsible to suggest that we just define the new standard on the back of a napkin based on what shipped in .NET Core 2.1 without at least sitting down with the major players to discuss what it should encompass.
I didn’t hear anyone recommend a back of napkin specification.
What happens though if, say, mono decides they don’t like the net core span APIs and do things differently? Since there is no standard, they’re certainly entitled to. Then what does netstandard vnext implement? Having a leading standard provides guidance.
@jherby2k but the other way around: adding things to netstandard doesn't require mono to implement them.
luckily we're in a situation now where MS has control over the feature roadmap of all major .net implementations.
Before this issue became viral, other requests for newer versions were effectively duped against https://github.com/dotnet/standard/issues/127
TL;DR the process of new versions of .NET Standard and API additions isn't defined (yet).
Can we perhaps split the concerns that came up in this issue into separate issues?
From what I understand, they are:
it’s whg JSON.NET stil supports .NET20 for some strange reason
Seriously though, if there was a netstandard2.1, and only .NET Core supported it, it isn't really a standard. And if you want every .NET platform moving in lockstep so netstandard2.1 was a true standard then you will lose the speed of innovation that is happening on platforms like .NET Core. Nothing in life is free.
What makes the having the standard "lockstep"? The existence of the standard and everyone implementing it are 2 distinct steps. They need not and will not happen simultaneously. Just as they didn't with netstandard2.0 (e.g. Tizen came later, as will other platforms).
What can happen simultaneously:
netstandardX is releasednetstandardX.All of these are good things, the widest audience possible can take advantage as soon as possible.
Then, as platforms implement netstandardX, they are able to take advantage of those builds of libraries. Consumers can get a wave of goodness as soon as a netstandardX release of their platform is available. This is motivating for both users and platform authors to implement new netstandard versions, as it opens the door to so much. At the moment, there's little reason for them to follow. What do they implement? No clue, there's no standard. There's not even a list of APIs to implement. And when they do, there's no TFM for people to build against that can consume it.
I get "what's in the standard?" isn't necessarily an easy question, sure, agreed. I don't get the arguments it ties everything together for simultaneous releases across the ecosystem. That part doesn't make sense to me. Am I missing something?
What can happen simultaneously:
You're missing the step where there is the planning of the standard, by all the interested parties. You're assuming that the definition of netstandardX is based solely on the implementation of netcoreappX, which is clearly not the right answer.
If you want netcoreappX and netstandardX to be released on the same day, then what you're asking for is to _delay the release of netcoreappX until the planning of the standard is complete_. I don't think anybody wants that.
BTW: I think there's a fundamental mistake in thinking here. Nobody is saying netstandardX is delayed until everybody's implementation is complete, only until the parties can all get together and agree on what should be in the standard. Implementations can and will follow on later.
Perhaps the name "Standard" was a bad decision to begin with.
From an engineering perspective, at least in Europe, a "Standard" is defined by the industry as a goal to achieve. After a new "Standard" is defined by the standard body, everyone aims to conform to it.
A new standard will incorporate everything that was learned and incorporates new research results and developments (e.g. a refined standard for construction that is more earthquake resistant. this happens in the standard first due to research and then everyone needs to conform to that standard).
To many engineers, this is what the name "Standard" implies.
if it is the other way around with ".NET Standard", it should have been named ".NET Common"? (I'm terrible at naming things)
EDIT: Better example: New WiFi standard 802.11xyz. it will be definded firsts by the industry/manufacturers, then everyone implements devices conforming to the standard
You're assuming that the definition of
netstandardXis based solely on the implementation ofnetcoreappX, which is clearly not the right answer.
Not assuming anything. But, let's say the standard isn't what netcoreapp2.1 built. The methods need to change now (perhaps a lot). Then we have a mess and duplicate methods/types/etc. The standard has to be quite heavily thought of when Microsoft is implementing a new .NET Core class of types and methods, IMO. If it's not, we've already got a big problem. Now, I don't think this went without happening. I know they thought about it, my point is: standard planning is already underway in most regards, though we don't know how far along.
I also don't agree "all the interested parties" is accurate. That's millions of people. There has to be a group that drives this that's incredibly smaller. It of course can't involve every dev, though they're very interested. It can't involve every vendor or platform maker either. It'd only be the major platforms, IMO.
I was saying they can happen simultaneously. It's already apparent that they don't, because they didn't. Not the question is: how far does the standard lag. What do we do? Wait for every platform maker to implement the methods they see fit and base the standard on that? I'd imagine they're waiting on a standard to implement. I'd love to hear if I'm wrong there, given you can't compile for anything else that has these methods. .NET Core 2.1 was released with netcoreapp2.1. Are we going to add a bunch of TFMs and method lists for moving targets back to PCL land, or do we have a goalpost?
I think @migueldeicaza's thoughts above are well reasoned and are exactly what I'd expect from any platform owner. At least netcoreapp2.1 is a target that exists. Why not just aim for that? If everyone else does that, it basically becomes the standard. At the moment, as a platform owner, it's what I'd do. I really think we need a standard, ASAP. The longer we're without one, the more directions everyone goes in.
Orthogonal to this cadence are platform releases that are not guaranteed to be in any standard - ever. This is essentially what .NET Core 2.1 did. But it did so in the absence of .NET Standard vNext leaving everyone confused as this thread clearly demonstrates. And like @NickCraver said, the longer there is no clear standard, the more directions everyone goes in.
The 'catch' if any is the .net standard planning team must operate with foresight about 12 months into the future.
It's almost like something that I tell my devs.
Complexity has to live somewhere, it's either in the user space or in the dev space.
I think what people were happy to see with .Net Standard 2.0, was that this complexity had moved out of the "user" space (i.e. as a lib developer I now longer had to fill my code with #ifdef's to support features). And now that complexity is moving back to the "user" space which seems like a step backwards.
@rhux Which complexity is that?
The idea that the complexity to handle multiple different targets or feature sets can get pushed out of the developer space and into the standard.
Looking back through this thread @NickCraver said it much more eloquently than I did (reving the different versions and PCL potential problem). As a developer, and adopter of .NET having to now re-worry about the fragmentation (.NET standard or Core or Full Framework is, well ... annoying. I know they were never 100% equivalent, but .NET Standard 2.0 went a long way in reducing that mental capacity so we could worry about other things (and not whether our consumers of our libraries had the right version of .NET).
Anyways, it might of been a bit of a forced analogy, so feel free to ignore it.
Multi-targeting isn't an issue; I doubt if std2.1 came out anyone would drop std2.0, and preferably would be targeting even lower versions (as low as the support headache you can get away with)
However, the desire for std2.1 is more one of progressive enhancement.
Doing progressive enhancement via netstd is like saying "if (feature set) ... else ..."
Doing it via platform TFM is like saying "if (chrome) ... else if (firefox) ... else if (edge) ... else if (opera) ... else if (IE11) ... else if (IE10) ... else if (IE9) ... else if (IE8) ... else if (IE6) ... else ..." which is possible, but horrible.
@benaadams You're arguing against a straw man.
@bradwilson
I think there's a fundamental mistake in thinking here. Nobody is saying
netstandardXis delayed until everybody's implementation is complete, only until the parties can all get together and agree on what should be in the standard. Implementations can and will follow on later.
I think the fundamental issue here is lack of communication. Nobody from MS is really saying anything about what will be in .Net Standard 2.1 or when it will be released or anything like that.
In that situation, all we can do is speculate. And we already have to multi-target a specific framework (netcoreapp2.1) to get new features, so I think it's natural we're worried we'll have to multi-target more and more frameworks.
And until you announce that .Net Standard 2.1 will be released before other frameworks implement those new features, I think we'll keep worrying.
(Note that I'm not saying implementations of new features on other frameworks should be delayed until after .Net Standard 2.1. I'm saying .Net Standard 2.1 should be expedited.)
I posted a comment on a Xamarin.Android issue and some of what I wrote is relevant here. I wanted to mention it here, as this idea of what's in the Standard vs. not, and what library developers can/should take advantage of in .NET Core vs. .NET Standard has ramifications today, as demonstrated by issues mobile developers are encountering when using the new Entity Framework Core 2.1 release.
I'll call out one thing that I read above vs. what the reality is. @RussKeldorph had earlier written:
The System.Memory package (which contains Span/Memory/etc) is available OOB (for full framework and older version of .net core (like 2.0), and it complies with netstandard1.1 so can be used on any of the platforms that meet netstandard1.1+ spec.
Unfortunately, that ideal is not the reality. The System.Memory 4.5.0 package claims to support Xamarin.Android and Xamarin.iOS with no additional OOB package dependencies, and used _._ placeholder files to assert that those platforms provided the necessary implementation.
However, when System.Memory 4.5.0 was published, neither of those platforms provided such an implementation.
Xamarin.Android has since been fixed (VS 15.7.3) but Xamarin.iOS today still can't completely build (i.e. full AOT for device targeting) any app referencing any package that depends—directly or indirectly— on the new System.Memory bits.
I quite honestly wish I didn't have to care about System.Memory. I just want to use EF Core 2.1, which depends on .NET Standard 2.0, plus a list of 10 innocuous-seeming OOB packages, none of which is System.Memory. But diving deeper:
Microsoft.EntityFrameworkCore 2.1.0 depends on (among other things):
Microsoft.Extensions.Caching.Memory >= 2.1.0, which depends on:
Microsoft.Extensions.Caching.Abstractions >= 2.1.0, which depends:
Microsoft.Extensions.Primitives >= 2.1.0, which depends on:
System.Memory >= 4.5.0, which fails to build for Xamarin.iOS.I honestly don't know if the answer to preventing issues like this is revving the .NET Standard so it is clear exactly what Standard-conforming target platforms must add, and/or if library developers need to be more mindful and deliberate with dependencies (and dependencies of dependencies, etc.).
System.Memory feels to me like it should be part of the Standard. If a System.* package asserts that most/all TFMs will provide their own implementation, rather than the package providing implementation bits, it feels to me like functionality the Standard ought to mandate.
On a related note, I also think it needs to be made very clear in any NuGet package description, (1) whether the "support" claimed for a target platform is simply a redirection/assertion that the platform provides the implementation—or if the implementation bits are in the package itself, and (2) the complete dependency tree for all required minimum versions. Dependency spelunking isn't fun.
System.Memory feels to me like it should be part of the Standard. If a System.* package asserts that most/all TFMs will provide their own implementation, rather than the package providing implementation bits, it feels to me like functionality the Standard ought to mandate.
Honestly, given the problems we're encountering with that package being out in some platforms and in other platforms. It should have been in netstandard 2.0. When a package have a foot in both worlds, the package changes at the rate of the slowest platform it is embedded in.
@jherby2k
Sounds like I'm waiting on .NET Standard 3.0 / Framework 4.8, which are coming some time next year.
The .NET Framework 4.8 (with a release date in 2019) will not have any Span & friends due to compatibility concerns for existing applications.
Oh great, so does that mean
Net standard 3.0 is also not going to include them? So disappointing.
Wish they would just drop .net 4 like they did with 3.5, and start over
I also find this disturbing. I mean, it's not even 4.7.3, it's 4.8. Adding an API doesn't break any existing application, the only way I see how things could break is when 1) behavior changed (how would that be with span?) or 2) return types are now different.
I agree, the whole 'in-place' system isn't working for the future, it basically freezes the system and no movement is possible (as adding APIs isn't even on the table here).
Fun times ahead for library writers . Not only for the multiple realms we have to support (the dead past aka '.NET 4.x' and the future aka '.NET core') but also the tough decision when to drop .NET 4.x support as it's no longer feasible.
I have to say, Microsoft, this is a cop-out. The problems are mainly in your courtyard but it's simply delegated to us library writers to 'solve' it for you. For a company who wants to invite more and more developers to their platforms, it's a little odd that you make it harder for the devs that are already on your platforms.
Not only for the multiple realms we have to support (the dead past aka '.NET 4.x' and the future aka '.NET core') but also the tough decision when to drop .NET 4.x support as it's no longer feasible.
Support at least .NET Standard 2.0; which includes 4.6.1+
If you drop .NET Standard 2.0 because .NET Standard 2.1 comes out (and only support that); then you are kinda missing the point...
@benaadams sure, netstandard 2.0 is the bare minimum. Thing is, .NET standard 2.0 doesn't cover everything. E.g. my software uses config files, DbProviderFactory (even tho it's added to .net core now, it's not in a standard) and other things on the .NET full version. There are workarounds in place for the .netstandard 2.0 build for most of that (if it's possible), but if people use e.g. web.config and .net full, they likely would like to use that for configuration of my stuff too (it has always been that way so they're used to it). So it would be nice if there were just 2 platforms to support .netstandard (for .net core, xamarin etc.) and .net full for the people who don't use .net core/xamarin etc.
The real pain is IMHO in the fear that these two platforms will now move away from each other rapidly, or better worded: the .net full part will be stuck in time while the rest drives away into the future.
It's always a problem when something new comes out and it's only supported on one of the platforms you have to target. That's fine, as long as somewhere in foreseeable future it's also supported across the board so you can utilize in your own code without a lot of hassle. It now looks like that's not going to happen with Span
So to summarize, netstandard is a trailing standard that has to wait for full framework, and full framework ain’t changing ever again. Ergo netstandard 2.0 is the best we’re gonna get, and we better resume multi targeting. Boo.
I know this comment is slightly different from the OP's request, but.... Maybe I'm missing something, or am not savvy to some inner details; however, why can't, over the next couple years, the dotnet full framework be adjusted to be OS independent? I get you don't want to break old things, and it would be a major undertaking (and lots of functions use windows native commands).. But, if it's clearly stated that x is a breaking change on the full framework, why can't a change like that happen?
why can't, over the next couple years, the dotnet full framework be adjusted to be OS independent?
They already did that, and called it .NET Core.
@bradwilson I meant for the .netfull framework.. But, maybe it doesn't matter. People seem sentimental about losing .net 46.
Okay.... so if Span/Memory isn't coming to .NET Framework, couldn't we at least contemplate having an update to .NET Standard that includes other quality-of-life improvements?
And maybe some of the stuff being considered for .NET Core 2.2, like System.IO.Path.Join(string, string).
Or at the very least, how about some of the things that are already shipping in .NET Framework 4.7.2 _and_ .NET Core 2.0:
@timdoke I understand what you're asking for, but if that work was put in, it's no longer the desktop CLR, because it's lost the key attributes that define it. It's not just a matter of wishing for something different; it is what it is, and changing that significantly gives you something _different_, not a new version of the desktop CLR.
Funny, I stumbled upon this thread cos VS told me there's no such thing as netstandard2.1
Seeing that the issue is in an open state, may I suggest a solution:
Why don't .NET Core become the standard? .NET Core stays platform independent, but is also responsible for taking the lead wrt innovation.
Any platform specific features will reside on the platform specific code repo called [_PlatformName_].NET, for example Windows.NET.
That means the .NET Core code repo is the major code base and platform specific repos are essentially addons/extensions specific to the each platform which means there's lots of re-usability. Library authors can target .NET Core and consumers can use platform specific extensions to enhance there app.
My 2 cents :)
I'm glad I found this discussion because I too was one of the people thinking .NET Standard was the target to use for everything. Now I can see why that can no longer be the case, but I think I understand the reasons behind it a bit better.
Whilst I still very much hope the radius of .NET Standard can keep on increasing I don't think that should stop .NET Core from moving on if it needs to, otherwise the team could be pushed behind a very long time.
I'd much rather Core keeps giving us production ready stuff we can use today (I'm glad I can use 2.1, the build and runtime performance improvements alone are fantastic) than having to wait further when we don't actually need to, because that gives us an option - settling on widest support possible or making use of the latest features. As @davidfowl says this has always been the case...
It's a bitter pill for library developers for sure... but essentially it looks like it came to the point where "the free lunch is over" and there are compromises to be made again. Arguably Microsoft could've managed these expectations better but I'm sure a lot of these realizations also came about as work was being done and the team discussed between themselves and the community. Most of us will know the pain of working with legacy stuff to sympathize.
The important thing now is knowing whether .NET Standard will keep evolving so people can figure out if they can/should wait for a new rev or if multi-targeting will be the only possible option from here on.
I'm hoping the former can still be the case. Better late than never.
A note about the governance model is up. It states
APIs in the .NET Standard must be implemented by all .NET implementations (excluding .NET implementations that are no longer updated).
..and framework already decided against this ref Rich Lander
To me this reads that this will not go into the standard before framework is "no longer updated".
@nsboard Can you please clearify?
So we’re essentially waiting for full framework to go on extended support (security updates only), which it defacto already is.
If security updates count as updates, we’re waiting for full framework to go EOL, which won’t happen for decades (see vb6). In that case .net standard is dead.
I'm disappointed that they went with ".NET Standard is the lowest common denominator" instead of ".NET Standard is .NET". I'm not convinced lowest common denominator .NET Standard is of much use. It'll help facilitate the transition from Framework to Core and then that's it.
It'll help facilitate the transition from Framework to Core and then that's it.
If .NET Standard is primarily to bridge OG Framework + Core, and .NET Core 3.0 will support Windows/desktop, then perhaps that's a sign that eventually the library targets should just be netcoreapp rather than netstandard.
eventually the library targets should just be netcoreapp rather than netstandard
Yes, that's what I'm thinking. If Standard lags as much as it sounds like it will from reading the governance document then .NET Core becomes de facto the real standard.
@BowserKingKoopa
I'm disappointed that they went with ".NET Standard is the lowest common denominator" instead of ".NET Standard is .NET".
We pretty much went with .NET Standard is .NET approach. Portable Class Libraries (PCLs) were the "lowest common denominator" approach. The difference isn't so much in tooling but in intention. In PCL's case, the platform owners didn't care about portability (some did, but many didn't). We cared about portability so we built a system that maximizes code reuse by given you the biggest possible intersection, which we called profiles.
With .NET Standard, we inversed that. We want to be intentional about which APIs should be everywhere while at the same time we try to avoid holding all platform hostage and prevent them from innovating and shipping new APIs just because the APIs weren't standardized yet. We believe this gives us the best of both worlds: platforms are largely independent while we retain a shared standard and vision for all .NET implementations that library authors an rely on.
@hsorbo, @jherby2k
The .NET Standard isn't locked in if a specific .NET platform is no longer advanced. Take, for example, Silverlight or Windows Store (precursor to UWP). They are both done in that we no longer add APIs to them. Whether or not they get updated for security/reliability bug fixes is orthogonal from .NET Standard view point. They just remain on an older version of the standard.
Given that there is PR for .NET Standard vNext (albeit it marked as work-in-progress) I believe this issue can be closed.
@jherby2k's original ask was:
I can't find any information about a .net standard 2.1.
You can now track #785.
I really want to use the new Span-ified methods like Stream.Read in my class libraries, but it looks like that stuff isn't in System.Memory but rather the .net core 2.1 SDK. Any other way to get these APIs, or do I have to wait for .net standard 2.1. And is there any ETA on that?
.NET Standard can only get new members on existing types if we rev the standard itself, which is the plan. And for the upcoming version of the standard we intend to bring all these methods that accept and return Span<T> or friends.
Although it seems like I'm late to the party, I put my 2 cents in.
Perhaps the main source of confusion is the poor naming decision made? Span
Why do we even need .Net Framework and mono to continue evolving (they could be left behind as legacy just being hotfixed) .Net Core seem to be working so well. I am thinking that because of the way it was engineered where it does not depend on previous versions, allowing it to evolve without breaking previous work, then it should be the main focus of .net for now and the future, and platform specific libraries would be released as individual packs for each platform, that way when new stuff comes to .Net it would not have to be implemented more than once and everyone would know the latest .net core means the latest features, and whatever version my lib is on I could stay on and it would work anywhere cause its .net core ...just thinking out loud
Why do we even need .Net Framework and mono to continue evolving (they could be left behind as legacy just being hotfixed) .Net Core seem to be working so well.
For the Mono (and related Unity) side CoreCLR is missing some architecture and platform support as it doesn't run on the following which Mono does: Linux (s390x, SPARC, PowerPC, MIPS), Solaris (SPARC, x86-64), IBM AIX, macOS (PowerPC), Wii, FreeBSD, OpenBSD, NetBSD, Android, iPhone, tvOS, watchOS, PlayStation 3, PlayStation 4, XboxOne (Exclusive mode), Webassembly
If we rev the standard at the pace of the fastest platform, doesn't that defeat the purpose?
The question is then, what purpose?
If we rev the standard at the pace of the fastest platform, doesn't that defeat the purpose?
The question is then, what purpose?
The purpose of the standard is to drive convergence. I think what Fowler was concerned about is that if the standard revs very fast you can build libraries that don't run everywhere yet. But given that these point in time issues will always exist, I don't buy this as a counter argument of reving the standard either.
That being said, we cannot rev the standard too fast in the sense that we need to take our time to understand if the concepts we're planning on adding can and will likely be supported by all current but also future platforms. Unfortunately this isn't an exact science.
The purpose of the standard is to drive convergence.
If so, then the standard should be in the forefront and the discussion should be on what to put in the standard and how to evolve it.
New "features" put in a standard implementation that might end up in the standard should be marked as experimental, as pointed out by others. Being clear on and communicating namespaces might be a simple solution.
Unfortunately this isn't an exact science.
👍
Microsoft have managed to get a lot of developers to use .netstandard as the base for their own libraries, not because of necessity, but to prepare for future alternatives.
When you get such debacles people will jump ship, and only use .netstandard when necessary.
That will in the end kill .netstandard.
New "features" put in a standard implementation that might end up in the standard should be marked as experimental, as pointed out by others. Being clear on and communicating namespaces might be a simple solution.
I think they should only be in the standard if they are actually a standard, I'd disagree with experimental features being put in something with a name like standard. Sounds like a great way to start confusing people, especially if those experimental features ever disappear from something that is supposed to be a standard by definition. They just don't mix, IMHO.
New "features" put in a standard implementation that might end up in the standard should be marked as experimental, as pointed out by others. Being clear on and communicating namespaces might be a simple solution.
I think they should only be in the standard if they are actually a standard
Yes, sorry, bad wording on my part. By 'standard implementation' I was just referring to .Net core etc.
namespace Microsoft.NetCore.whatever when experimenting
namespace System.whatever when standardised
@pi3k14 @gehnster
The standard is about driving convergence but the standard is not about defining & building the features themselves. Any feedback on the actual design of the feature needs to be made in the context of the platform that first introduces them. In other words, the standard is only about adding concepts that already exist in one implementation so that (1) other implementations also gain the feature and (2) developers can write portable code that uses the feature.
In other words, we aren't previewing any features with the standard.
Yes, sorry, bad wording on my part. By 'standard implementation' I was just referring to .Net core etc.
namespace Microsoft.NetCore.whatever when experimenting
namespace System.whatever when standardised
Ah yeah that makes a lot more sense to me now. :)
This model doesn't work for us because it forces us to either make breaking changes after the feature got standardized or live with duplication after standardization.
Any feedback on the actual design of the feature needs to be made in the context of the platform that first introduces them.
That is not a standardisation approach.
This model doesn't work for us
You have chosen the model, and duplication, with deprecation policies, is part of such an standardisation model.
Or stop calling it a standard. It is just a collection with nice parts from everywhere.
Why do we even need .Net Framework and mono to continue evolving (they could be left behind as legacy just being hotfixed) .
will be done with .Net 5 which is .net core and old framework is left at version 4.8.
Most helpful comment
I know that .NET standard was kind of retrofitted over the current frameworks, but going forward, shouldn't the standard be established first? I mean, if its truly a specification, shouldn't the specification be agreed upon prior to implementation? It would also give non-MS implementations (i.e. mono) something concrete to target for their future releases.