fslang-suggestions icon indicating copy to clipboard operation
fslang-suggestions copied to clipboard

Add Support for C# Class Fields in SRTP

Open nodakai opened this issue 2 years ago • 2 comments

I propose we

enhance SRTP to uniformly support all properties and fields, irrespective of being from C# or F#.

https://stackoverflow.com/questions/75741761/srtp-member-constraits-cant-see-raw-fields-of-c-sharp-classes

F# Project Lib0.fsproj

namespace Lib0

type T0 =
  val Id: string
  new s={Id=s}
type T1 =
  val mutable Id: string
  new s={Id=s}

C# Project Lib1.csproj

namespace Lib1;
public class Class1
{
  public string Id;
  public Class1(string id) {
    Id = id;
  }
}

public class Class2
{
  public string Id { get; set; }

  public Class2(string id) {
    Id = id;
  }
}

F# Project Test1.fsproj

module Lib =
  type T2 =
    val Id: string
    new s={Id=s}
  type T3 =
    val mutable Id: string
    new s={Id=s}

let inline f<'T when 'T: (member Id: string)> (x: 'T) = x.Id

f (Lib0.T0("Lib0.T0")) |> printfn "%s"  // ok
f (Lib0.T1("Lib0.T1")) |> printfn "%s"  // ok
f (Lib.T2("Lib.T2")) |> printfn "%s"  // ok
f (Lib.T3("Lib.T3")) |> printfn "%s"  // ok
// f (Lib1.Class1("Class1")) |> printfn "%s"  // The type 'Lib1.Class1' does not support the operator 'get_Id'
f (Lib1.Class2("Class2")) |> printfn "%s"  // ok

The existing way of approaching this problem in F# is

defining F# wrappers for each C# class with fields? Can be quite verbose, error-prone

Pros and Cons

The advantages of making this adjustment to F# are

better interoperability with a wider .NET ecosystem which is predominantly C#-based

The disadvantages of making this adjustment to F# are

additional work and code required to make it happen

Extra information

Estimated cost (XS, S, M, L, XL, XXL):

No idea, maybe L?

Related suggestions:

#671 #1307

Affidavit (please submit!)

Please tick these items by placing a cross in the box:

  • [x] This is not a question (e.g. like one you might ask on StackOverflow) and I have searched StackOverflow for discussions of this issue
  • [x] This is a language change and not purely a tooling change (e.g. compiler bug, editor support, warning/error messages, new warning, non-breaking optimisation) belonging to the compiler and tooling repository
  • [x] This is not something which has obviously "already been decided" in previous versions of F#. If you're questioning a fundamental design decision that has obviously already been taken (e.g. "Make F# untyped") then please don't submit it
  • [x] I have searched both open and closed suggestions on this site and believe this is not a duplicate

Please tick all that apply:

  • [x] This is not a breaking change to the F# language design
  • [ ] I or my company would be willing to help implement and/or test this --- happy to help testing

For Readers

If you would like to see this issue implemented, please click the :+1: emoji on this issue. These counts are used to generally order the suggestions by engagement.

nodakai avatar Sep 26 '23 04:09 nodakai

This is reasonable, marking as approved-in-principle

dsyme avatar Sep 26 '23 09:09 dsyme

Should this perhaps include constant fields as well? I've long been wondering why we cannot create an SRTP function that utilizes Int32.MaxValue, which can be useful in quite a few math functions.

@vzarytovskii, I saw you started this in #16481. This probably needs an RFC, no? What do you think how we should define "all fields" from this proposal? Ideally, "all" is "all" ;).

abelbraaksma avatar May 05 '24 09:05 abelbraaksma