fsharp / fsharp/fslang-suggestions
Add To Record Codegen CLI shape to allow C# 9.0 `with` keyword interop
- Dominant language
- No language data
- Stars
- 373
- Forks
- 21
- PR merge metrics
- No merged PRs in 30d
Description
# 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#:
```FSharp
type Suit = Heart | Diamond | Club | Spade
type Card = {Rank:int; Suit:Suit}
```
it would be great if this would work in C#:
```csharp
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:
```csharp
var lowAce = new Card(1, orig.Suit);
```
Probably what is needed is a public clone method named `$` 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:
https://github.com/jbtule/ConsumeFSharp-FromCSharp/pull/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:
* [x] This is not a question (e.g. like one you might ask on [stackoverflow](http://stackoverflow.com)) and I have searched stackoverflow for discussions of this issue
* [x] I have [searched both open and closed suggestions on this site](http://github.com/fsharp/fslang-suggestions/issues) and believe this is not a duplicate
* [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.
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
## 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.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by reading the F# Record CLI code generation and the linked C# 9.0 Record Spec Proposal, then reproduce the Card and with-expression examples against .NET 5. The work is done when an F# record exposes the CLI shape required for C# 9 with expressions, with compatibility and runtime constraints documented or tested.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp, fsharp
- Domain
- compilers
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 30/100