Skip to content

Add To Record Codegen CLI shape to allow C# 9.0 with keyword interop #903

@jbtule

Description

@jbtule

Add To Record Codegen CLI shape to allow C# 9.0 with keyword interop

I propose adding to the F# Record CLI code gen, whatever is necessary to necessary to the F# Record CLI code gen to make it work the C# 9.0 with keyword.

Given in F#:

type Suit = Heart | Diamond | Club | Spade
type Card = {Rank:int; Suit:Suit}

it would be great if this would work in C#:

public const int Ace = 14;

var orig = new Card(Ace, Suit.Spade);
var lowAce = orig with { Rank = 1};

The existing way of approaching this interop works is as so:

var lowAce = new Card(1, orig.Suit);

Probably what is needed is a public clone method named <Clone>$ and adding the new .net 5.0 init only setters to the properties. I'm not sure what else is needed to make C# 9 think a class is a record, but it looks like the C#9 code gen for records is very limited when the record is a sealed class like they are in F#.

I was trying to test this out, using F#'s ability to name a method whatever I want, but it appears I could not create an object that matched the C# record shape in .net 5.0 preview 7, whether it was due to the preview release or due to limitation on CLI protection levels that get generated in F# (no private or protected), i am not sure.

Pros and Cons

The advantages of making this adjustment to F# are smoother interop with C#. Reduces the need in .net 5.0 for using CLIMutable on records since it would have init only setters.

The disadvantages are you'll have to coordinate with the C#/Rosyln Teams with what they are actually looking for to identify records, and keep it in sync, and this is still an unreleased feature of C# 9.0. Another disadvantage is init only properties only work on .net 5.0 runtime.

Extra information

Estimated cost: M

Here is where I attempted to extend the Shape of an F# record, but failed:
jbtule/ConsumeFSharp-FromCSharp#2

Here is a link to the C# 9.0 Record Spec Proposal:
https://github.com/dotnet/csharplang/blob/master/proposals/csharp-9.0/records.md

Affidavit (please submit!)

Please tick this by placing a cross in the box:

  • This is not a question (e.g. like one you might ask on stackoverflow) and I have searched stackoverflow for discussions of this issue
  • I have searched both open and closed suggestions on this site and believe this is not a duplicate
  • 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.

Please tick all that apply:

  • 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

For Readers

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions