Interfaces with static abstract members (IWSAMs) [RFC-1124] #677
Replies: 20 comments 53 replies
-
Forget cans of worms. Behold! The cans of cans! |
Beta Was this translation helpful? Give feedback.
-
Hey, I'm aware that the interface list for double is just ridiculous, but I don't see how it introduces overhead inf terms of runtime, since I expected static interface methods to be resolved JIT-time (maybe I'm wrong there since that would mean having separate code for all types and not only for structs) Personally i was down over-abstraction road in haskell with redefining all the basic type-classes holding one single function each where Nonetheless I think (when used carefully) this could be a great tool for mathematical stuff and should not end up being treated as a second-class-citizen in F# |
Beta Was this translation helpful? Give feedback.
-
I've added two sections to the RFC here: https://github.com/fsharp/fslang-design/blob/main/RFCs/FS-1124-interfaces-with-static-abstract-members.md#self-type-constraints |
Beta Was this translation helpful? Give feedback.
-
let inline f<^T when WithBoth<^T>>() =
let v1 = 'T.StaticProperty
let v2 = 'T.StaticMethod(3)
v1 + v2 This syntax is very confusing. It will be also inconvenient to refactor (rename the type), also can be glitches when function is defined inside parametrized class: type Test<'T>() =
let inline f<^T when WithBoth<^T>>() =
let v1 = 'T.StaticProperty
let v2 = 'T.StaticMethod(3)
v1 + v2
member this.X = ()
|
Beta Was this translation helpful? Give feedback.
-
I would propose to recognize ' as ^ in lexer, when inline keyword is declared |
Beta Was this translation helpful? Give feedback.
-
I also wanted to suggest supporting flexible types e.g. ability to write let getZero<#INumber<'T>> () =
'T.Zero instead of let getZero<'T when 'T:>INumber<'T>> () =
'T.Zero The currently suggested syntax let getZero<'T when INumber<'T>> () =
'T.Zero is not short enough and also have a downside of having to learn smth new, while flexible types are well-known concept |
Beta Was this translation helpful? Give feedback.
-
I suggest to extract abbreviations into another RFC and properly design it to keep scope of current feature narrow. E.g. abbreviations from PR's branch cannot be used to constrain type parameter of class. Related request from @blumu. type Printer<^T when
^T : (static member Print : string -> unit)
and ^T : (static member Flush : unit -> unit)> = ^T
type Combine<^T1, ^T2 when ^T1 :> Printer<^T1> and ^T2 :> Printer<^T2>> =
static member inline PrintAndFlushBoth(m: string) =
'T1.Print(m)
'T2.Print(m)
'T1.Flush()
'T2.Flush()
|
Beta Was this translation helpful? Give feedback.
-
I've added very preliminary guidance on using IWSAMs to the RFC. This is based on the essays in the drawback sections such as this one. I feel it is necessary to have strong guidance in place in order to justify this feature, and justify our working on it, given it is so problematic. Having the guidance also helps structure discussion and prevent rabbit-holes. It also helps motivate @vzarytovskii and me to work on it 😄 |
Beta Was this translation helpful? Give feedback.
-
There's one other question about ambiguity here when types The explicit syntax via Are you planning to base F#'s operators on IWASM, will they remain SRTP-style and will they accept types implementing Edit: type A =
interface IAdditionOperators<A, B, C> with ...
type B =
Ainterface IAdditionOperators<B, A, D> with ... Of course the order of parameters would be a natural choice here |
Beta Was this translation helpful? Give feedback.
-
@dsyme |
Beta Was this translation helpful? Give feedback.
-
Can we also deprecate the use of |
Beta Was this translation helpful? Give feedback.
-
I've reviewed my comments about units of measure here: dotnet/fsharp#12881 (comment) and I propose we shift to making a feature restriction here where unitized types are simply not considered to implement The current RFC proposes to use rewriting of the interfaces considered to be supported by unitized types, e.g.
Note the [ Aside: While this is specific ti UoM, it hints at one reason why I'm not a great fan of the nominal concept modelling being used in Now F# SRTP doesn't have this problem, and it's worth asking why. This is because the F# compiler rewrites each use of the actual target method when resolving an SRTP constraint on a unitized type on a type known to the compiler, so successfully solves a constraint of this form: static member op_Multiply: double<m> * double<kg> -> double<m * kg> It's worth considering if this could be done for IWSAM constraints, however I don't believe it can.
Overall it is better to simply say that unitized types are simply not considered to support the At the moment I propose hard-wiring this rule as filtering any interfaces that dervies from anything in the |
Beta Was this translation helpful? Give feedback.
-
The rational grounds for avoiding or moderating type-level programming features (HKT, IWSAMs, ML functors, TCs, implicits, refinement types, conditional/structural types ...) is documented both in this RFC and elsewhere. My personal motivation stems from 30 years of seeing repeated obvious misuses of some of these features to create complexity that is, in balance, worse than the problems solved.
Tbh this is the kind of rhetoric we avoided in order to make our case for .NET Generics. Instead we argued on the grounds of concrete productivity benefits that stood up to scrutiny of those deeply experienced in developer tooling including Hejlsberg, Morrison, Miller, Rudder, Gates and others. Arguing about some inevitable march of history towards the glories of type-level programming would have got us thrown out the door, and indeed many idealistic MSR projects related to optimization or verification regularly failed when they took that approach. |
Beta Was this translation helpful? Give feedback.
-
I wanted to ask if the work of the dotnet runtime for abstract statics makes f# want to look at different codegen for SRTP? Will that improve performance? (I have no idea) |
Beta Was this translation helpful? Give feedback.
-
SRTP calls have essentially zero overhead, except perhaps where the compiler fails to do some obvious reductions that could be fixed. IWSAMs will have an indirect dispatch except for struct instantiations which will no doubt be inlined and zero overhead. |
Beta Was this translation helpful? Give feedback.
-
Would we be able to use Active Patterns with this feature? . I have not seen any mention on the RFC |
Beta Was this translation helpful? Give feedback.
-
Hey, i just stumbled on something that might be really a dotnet question, but nonetheless I think it is relevant for F#'s IWASM support: This feature introduces eomething like "static subtyping", so my question is whether there will be something like a downcast for types. For example in standard subtyping i can downcast an object to some specific interface when I know it really has the type. Will something similar be available for static Interfaces? The natural choice would be to "downcast" an instance of |
Beta Was this translation helpful? Give feedback.
-
I'm trying out F# 7. @dsyme this was added to C# in C# 8.0 and I see no reason why it wasn't added to F# at that time. Now I thought with this whole new set of features we would catch up, but it seems we're not. |
Beta Was this translation helpful? Give feedback.
-
Still playing with F# 7 and the more I explore the feature the more I realize there are certain omissions in the RFC. Apart from that, even if there are no adjustments to F# core operators that use SRTP with simulated members, it would be nice to mention it in the RFC as it is a bit surprising to me that eventually an |
Beta Was this translation helpful? Give feedback.
-
Hi 😊 The link to the RFC changed, if you wanna update it: https://github.com/fsharp/fslang-design/blob/main/FSharp-7.0/FS-1124-interfaces-with-static-abstract-members.md |
Beta Was this translation helpful? Give feedback.
-
Opening the can of cans of discussions.
Suggestion: fsharp/fslang-suggestions#1151
RFC: https://github.com/fsharp/fslang-design/blob/main/FSharp-7.0/FS-1124-interfaces-with-static-abstract-members.md
Beta Was this translation helpful? Give feedback.
All reactions