New [Experimental] attribute with language/compiler support #3555
-
We have a pretty decent way of indicating that a member in a library should no longer be used, with language/compiler support: Library authors currently have three choices:
Proposal: introduce a new attribute called By default, trying to use an experimental API surface would generate an error, and IDEs should either not include them in autocomplete or only do so with an additional "but you need to enable..." indication. Specifying an "allow experimental feature use" would allow users to opt into using these members. The generated code should not be affected by this at all, beyond the normal changes based on the presence of members. (So compiling the same code with and without the flag could generate different IL due to overload resolution for example, but no specific code generator changes would be needed.) Nice-to-have options to be discussed:
|
Beta Was this translation helpful? Give feedback.
Replies: 31 comments 3 replies
-
(Apologies if this is a duplicate - I did look beforehand, but didn't find anything.) |
Beta Was this translation helpful? Give feedback.
-
Couldn't warnings be accomplished via analyzers, and hiding the members via |
Beta Was this translation helpful? Give feedback.
-
Source generators could be used to automatically generate the Editor browsable attribute from the experimental attribute by adding it to an enhanced partial method (c# 9 feature). |
Beta Was this translation helpful? Give feedback.
-
not in this repo but in the runtime repo |
Beta Was this translation helpful? Give feedback.
-
@YairHalberstadt: Given that we'd need a common attribute to start with (unless we decide everyone should create their own, which I'd really like to avoid) I think it makes more sense for the compiler to know about this than to rely on analyzers. |
Beta Was this translation helpful? Give feedback.
-
@ufcpp: Wonderful, thank you - subscribed :) |
Beta Was this translation helpful? Give feedback.
-
Would this somewhat act like how we can't have unsafe code without the csproj file having |
Beta Was this translation helpful? Give feedback.
-
@jskeet then why not add it to the standard library? |
Beta Was this translation helpful? Give feedback.
-
I don't see why language/compiler support is necessary. |
Beta Was this translation helpful? Give feedback.
-
@YairHalberstadt: Yes, the attribute should be added to the standard library. But I believe the feature would only really be a first class feature if it could be relied upon via the compiler rather than people using an analyzer. |
Beta Was this translation helpful? Give feedback.
-
@Turnerj: Yes, "unsafe" is exactly the kind of model I'm thinking about. |
Beta Was this translation helpful? Give feedback.
-
The analyzer and source generator could be included in the standard library as well. I think it makes sense to build a precedent where features can be added in a first class way without compiler support, rather than requiring everything to be a new language feature. |
Beta Was this translation helpful? Give feedback.
-
As I've just noted in the runtime repo issue it may well be that versioning makes this infeasible. (You'd want to be able to remove experimental-in-1.1 features from 1.2, but then diamond dependencies would mean you might end up with 1.2 anyway, at which point it all breaks. |
Beta Was this translation helpful? Give feedback.
-
@YairHalberstadt: What benefit do you see over "we don't need to write the language specification part"? Because I see that latter as actually a benefit - I'd far rather rely on something that is well-defined in the language specification than a piece of analyzer documentation which is entirely separate. I'd want to be able to rely on this in the same way that I rely on |
Beta Was this translation helpful? Give feedback.
-
The advantage is that changing the compiler is hard and experimentation slow. Doing this via already existing mechanisms means anyone can prototype this, it can be used via a nuget package, and then once it's stable it can be merged into dotnet/runtime. |
Beta Was this translation helpful? Give feedback.
-
I think maybe a good approach, would be to create the prototype first, and then see if there's still something missing which necessitates language changes, or if the itch has been sufficiently scratched? |
Beta Was this translation helpful? Give feedback.
-
@YairHalberstadt: Yes, that would be fine, but I suspect we may very well disagree about whether a language change would be a good idea at the end, if the prototype were successful. I suspect the diamond dependency issue is a fatal blow though :( |
Beta Was this translation helpful? Give feedback.
-
Fascinatingly, this came up in offline discussion today on our teams chat @chsienki @RikkiGibson. Also, this kinda already exists, albeit in a wpf namespace: https://github.com/dotnet/roslyn/blob/fab7134296816fc80019c60b0f5bef7400cf23ea/docs/features/ExperimentalAttribute.md. |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
Food for thought... Instead of Experimental, call this Unsafe ? |
Beta Was this translation helpful? Give feedback.
-
@anthonydotnet: I'd be very strongly against that. Unsafe already has a very specific meaning in C# - let's not overload it. |
Beta Was this translation helpful? Give feedback.
-
Hmm... yeah true. |
Beta Was this translation helpful? Give feedback.
-
The analogy with unsafe is even stronger when you consider the proposed
I wonder if these two features could learn from each other and, if they were both adopted, if they should be made consistent, at least to some degree. |
Beta Was this translation helpful? Give feedback.
-
Borrowed from an old Preliminary Features section I wrote and modified to use the term 'experimental':
|
Beta Was this translation helpful? Give feedback.
-
I would personally prefer an abstract WarningAttribute, where attributes that inherit from it will have a compiler warning, so we compiler team wouldn't have to create specific cases for any attribute like this in the compiler. It would look like: public abstract class WarningAttribute : Attribute
{
public string Message { get; }
public WarningAttribute(string message)
{
Message = message;
}
}
[AttributeUsage(...)]
public sealed class ExperimentalAttribute : WarningAttribute
{
public ExperimentalAttribute(string message) : base(message)
{
}
}
// Same for Obsolete/Deprecated/whatever. Compiler will just display Message property
// The compiler may as well enforce the attribute to have a constant expression for Message property I guess? |
Beta Was this translation helpful? Give feedback.
-
I like the idea, but I think the one problem with that approach is that currently |
Beta Was this translation helpful? Give feedback.
-
@HaloFour The diagnostic ID is configurable starting with dotnet/runtime#33089 |
Beta Was this translation helpful? Give feedback.
-
Could this be covered in generalized code generation from packages? Not sure which issue but I think if we could have ability to analyze and inject code, also ability to generate warning and/or error from package, |
Beta Was this translation helpful? Give feedback.
-
Would this proposal address this? |
Beta Was this translation helpful? Give feedback.
Would this proposal address this?
dotnet/designs#285