Closed vzarytovskii closed 2 weeks ago
@vzarytovskii Will https://github.com/fsharp/fslang-suggestions/issues/905 also be part of 5. Overload resolution priority
?
@vzarytovskii Will fsharp/fslang-suggestions#905 also be part of
5. Overload resolution priority
?
No, linked suggesting is F# specific feature and not connected with C# attribute proposal. 5
will likely not be worked on for F# 9, since it shouldn't be affecting existing method resolution rules.
To expand: the issues above are only about .NET 9 and compatibility, any existing F# suggestions will likely be orthogonal to any above. The approach would likely be to go the path the least resistance, and make sure "everything works". Later on (F# 10+) decide whether any extended support is needed/desired. Reasoning for that is, well, we want it to work, but we want to see how the feature expands in C#/runtime after release and what level of support is adequate for F#, so we can properly plan and design the it.
@vzarytovskii This is a great list!
Full support (out of the picture for F# 9): Shall there be an ability to declare such extensions for consumption from both F# and C# (i.e. expanding our type augmentation and extensions support). This is up to @dsyme to approve/reject.
I think it's reasonable to support this - so yes, approved-in-principle - though it opens many smaller questions. The question is really about how to fit this with the existing mechanisms in F# for declaring extensions and I'm open to hearing community suggestions and let you and others shape the detailed design process for resolving the technical issues in this.
I assume the current compilation of current F# extensions can't "fit" with what this new thing expects. To make this palatable perhaps an attribute CLIExtension
could be added to F#-style extensions to make them compile differently.
[<Extension>]
- for what we call "C#-style extensions". This will give three ways of declaring extensions in F# but I think it may be unavoidable.@vzarytovskii This is a great list!
Full support (out of the picture for F# 9): Shall there be an ability to declare such extensions for consumption from both F# and C# (i.e. expanding our type augmentation and extensions support). This is up to @dsyme to approve/reject.
I think it's reasonable to support this - so yes, approved-in-principle - though it opens many smaller questions. The question is really about how to fit this with the existing mechanisms in F# for declaring extensions and I'm open to hearing community suggestions and let you and others shape the detailed design process for resolving the technical issues in this.
Yeah, we'll need to wait for the implementation/finished spec on C#/CLR side and see how would that be fitting with what do we currently have in F#.
I assume the current compilation of current F# extensions can't "fit" with what this new thing expects. To make this palatable perhaps an attribute
CLIExtension
could be added to F#-style extensions to make them compile differently.
Probably not fully expressible with current extensions, yes.
- Failing that I'm guessing that an attributed declaration form will be possible - like
[<Extension>]
- for what we call "C#-style extensions". This will give three ways of declaring extensions in F# but I think it may be unavoidable.
Yep, we'll pretty much have "one more way" of doing that.
@vzarytovskii As for the overload resolution priority attribute, I am curious what the implications of remaining unaware of it might be given a few excerpts from the proposal:
a new attribute … that can be used by API authors to adjust the relative priority of overloads … even if those APIs would normally be considered ambiguous
(emphasis mine)
The type or member is still visible in overload resolution, and may cause unwanted overload resolution failures when there is a perfectly good alternative, but that alternative is either ambiguous with the obsoleted member, or the presence of the obsoleted member causes overload resolution to end early without ever considering the good member. For this purpose, we want to have a way for API authors to guide overload resolution on resolving the ambiguity, so that they can evolve their API surface areas and steer users towards performant APIs without having to compromise the user experience.
(emphasis mine)
It sounds like the attribute would (intentionally) make it possible to create APIs that could only be disambiguated by a compiler that understood the attribute.
I left a comment on the C# issue: https://github.com/dotnet/csharplang/issues/7706#issuecomment-2061392247.
@vzarytovskii As for the overload resolution priority attribute, I am curious what the implications of remaining unaware of it might be given a few excerpts from the proposal:
a new attribute … that can be used by API authors to adjust the relative priority of overloads … even if those APIs would normally be considered ambiguous
(emphasis mine)
The type or member is still visible in overload resolution, and may cause unwanted overload resolution failures when there is a perfectly good alternative, but that alternative is either ambiguous with the obsoleted member, or the presence of the obsoleted member causes overload resolution to end early without ever considering the good member. For this purpose, we want to have a way for API authors to guide overload resolution on resolving the ambiguity, so that they can evolve their API surface areas and steer users towards performant APIs without having to compromise the user experience.
(emphasis mine)
It sounds like the attribute would (intentionally) make it possible to create APIs that could only be disambiguated by a compiler that understood the attribute.
Yep, that's my understanding as well, if compiler is unaware of attribute, type resolution would work as if it was just another overload...i.e. default rules would work. Attribute is designed to hint the compiler which one to prefer specific one (e.g. string vs Span
I left a comment on the C# issue: dotnet/csharplang#7706 (comment).
Yep, that's my understanding as well, if compiler is unaware of attribute, type resolution would work as if it was just another overload...i.e. default rules would work.
Yeah, but doesn't this mean that there could now be (more) C# libraries whose APIs would be impossible to consume from F#? (It already is possible to define overloaded APIs in C# that are impossible to consume from F#, but this would add another way to do it.)
Minimum (targeted for F# 9): Make sure F# compiler works when consuming such interfaces
The other item I would make sure to focus on is that F# can consume generics that have ref struct
type arguments. This is likely to show up in a number of places in the BCL and it seems inevitable that F# users will encounter this. It's possible this is cheap for F#, or even free. But given that up until now they've been banned in generics know that both the runtime and roslyn code base had assert style guards that fired when they were encountered.
Yep, that's my understanding as well, if compiler is unaware of attribute, type resolution would work as if it was just another overload...i.e. default rules would work.
Yeah, but doesn't this mean that there could now be (more) C# libraries whose APIs would be impossible to consume from F#? (It already is possible to define overloaded APIs in C# that are impossible to consume from F#, but this would add another way to do it.)
It might be, can you drop some examples here please?
It might be, can you drop some examples here please?
The proposal doesn't seem to have an example of this, but the wording implies to me that enabling such APIs to be created is part of the point of the feature: i.e., in a case where it would be impossible to disambiguate a new overload of an API from an obsolete one using the current overload resolution rules, this new attribute would enable the compiler to do so, which would allow the API author to conveniently replace usage of an obsolete API in a way that was impossible before. But that by definition sounds like it would mean that any compiler that didn't understand the attribute — an older C# compiler, F# if it weren't updated to understand the attribute, etc. — would not have a way to resolve the ambiguity in such a case.
https://github.com/dotnet/csharplang/pull/7906: developers can add weight to which methods are better in overload resolution. This seems unlikely to impact F# as much.
Want to point out one place this will intersect with F#. Consider that very likely Debug
will end up looking like the following:
public static class Debug
{
[OverloadResolutionPriority(-1)]
public static void Assert(bool condition) { ... }
public static void Assert(bool condition, [CallerArgumentExpression] string? message = "") { ... }
}
Nothing will break for F# here when this happens, code will still compile as it used to. The experience for C# though will improve from a lot of Debug.Assert failed
messages to the actual expression that passed into the assert. This is one part I thought might be interesting to F# .
F# 9.0 is now in and locked. there are two issues that need a little work, we will try to do before 9.0 ship and turn them on.
https://github.com/dotnet/fsharp/issues/17514 https://github.com/dotnet/fsharp/issues/17509
So I am closing this issue. F# 10.0 is a long way off.
We need to assess which features we will need to support in F# 9
Params collections: developers can now put params in front of many more collection types in signatures including Span.
MethodCall(1,2,3)
toMethodCall(MyFancyType.Create().Add(1).Add(3).Add(3))
or similar following the full specref struct generics and interfaces : A ref struct can now both implement an interface
A type parameter can now be (anti)constrained to allow ref struct arguments
Extension types: this is a new way of declaring extension members (both static and instance)Cut from C# for .NET9, so we don't need to do it now
- Minimum (targeted for F# 9): Support calling methods with such augmented types (extensions). C# feature still has a lot of TODOs, which means we'll likely won't be able to start working on it until C# has a working prototype implemented. This will still need an RFC and design. - 3 design decisions will need to be made: - Support for extension members - Support for extension static members - Support for extension that implement interfaces - Support of such extensions in SRTPs. - Full support (out of the picture for F# 9): Shall there be an abillity to declare such extensions for consumption from both F# and C# (i.e. expanding our type augmenation and extensions support). This is up to @dsyme to approve/reject.Overload resolution priority: developers can add weight to which methods are better in overload resolution. This seems unlikely to impact F# as much.
We will likely need to look at 1 and see it doesn't break, but no rush supporting it in F# 9 (since we're pretty much at capacity currently), 2 and 3 will need to be supported, 4 is the same as 1 for the release (i.e. make sure nothing is breaking, wider support will require separate design based on final set of features implemented in C#), 5 will be likely out of the picture for F# 9.