I propose we add support for C# collection expressions to F# lists and sets, so that a collection of this type can be initialized from C# code with a collection expression.
The use case for F# lists and sets in C# code, as I see it, is to extend the immutability and value equality of C# records to those with collections of equatable items (strings, integers, other records) as properties/fields. By combining a record with an immutable collection type that (like the record) implements value equality, a complex type can be constructed that is fully immutable and supports "deep" equality checks all the way down, as is often done in F#. This becomes very useful when writing unit tests that need to define and check all fields and sub-fields on objects,. It also opens up use cases for these complex types to be used in a HashSet or as keys in a Dictionary.
C# collection expressions don't have "automatic" support for immutable collections (the compiler looks for an Add method), but support can be added to a collection type by adding a CollectionBuilderAttribute to the type and implementing a static creation method.
This code can be used today in C#:
record Poem {
public string Name { get; init; } = "Untitled";
public string Content { get; init; } = "";
public FSharpSet<string> Tags { get; init; } = SetModule.Empty<string>();
}
Poem originalPoem = repository.GetPoem(id);
Poem newPoem = originalPoem with { Tags = SetModule.FromArray(["sonnet", "moon", "sky"]) };
if (originalPoem != newPoem) {
repository.UpdatePoem(id, newPoem);
}
With this change, the code could become:
record Poem {
public string Name { get; init; } = "Untitled";
public string Content { get; init; } = "";
public FSharpSet<string> Tags { get; init; } = [];
}
Poem originalPoem = repository.GetPoem(id);
Poem newPoem = originalPoem with { Tags = ["sonnet", "moon", "sky"] };
if (originalPoem != newPoem) {
repository.UpdatePoem(id, newPoem);
}
The existing ways of approaching this problem are to:
- use a non-F# collection type such as the ones in the namespace
System.Collections.Immutable; these types do not implement value equality; so another approach must be used to compare two objects
- initialize another collection type (with or without collection expressions) and convert to an F# list using
ListModule.OfSeq or ListModule.OfArray
- implement a custom collection type that supports value equality (with
object.Equals and with IEquatable<T>) and collection expressions, as well as whatever other functions / features are needed
Pros and Cons
The advantages of making this adjustment to F# are:
- Better interoperability with C# code that uses F#-defined types
- Making the F# list type more useful for C# developers
The disadvantages of making this adjustment to F# are:
- Code must be added to the F# library (and maintained) to support a C# feature that does not (currently) exist in F#
Extra information
Estimated cost (XS, S, M, L, XL, XXL): XS
Related suggestions:
Affidavit (please submit!)
Please tick these items by placing a cross in the box:
Please tick all that apply:
I propose we add support for C# collection expressions to F# lists and sets, so that a collection of this type can be initialized from C# code with a collection expression.
The use case for F# lists and sets in C# code, as I see it, is to extend the immutability and value equality of C# records to those with collections of equatable items (strings, integers, other records) as properties/fields. By combining a record with an immutable collection type that (like the record) implements value equality, a complex type can be constructed that is fully immutable and supports "deep" equality checks all the way down, as is often done in F#. This becomes very useful when writing unit tests that need to define and check all fields and sub-fields on objects,. It also opens up use cases for these complex types to be used in a
HashSetor as keys in aDictionary.C# collection expressions don't have "automatic" support for immutable collections (the compiler looks for an
Addmethod), but support can be added to a collection type by adding aCollectionBuilderAttributeto the type and implementing a static creation method.This code can be used today in C#:
With this change, the code could become:
The existing ways of approaching this problem are to:
System.Collections.Immutable; these types do not implement value equality; so another approach must be used to compare two objectsListModule.OfSeqorListModule.OfArrayobject.Equalsand withIEquatable<T>) and collection expressions, as well as whatever other functions / features are neededPros and Cons
The advantages of making this adjustment to F# are:
The disadvantages of making this adjustment to F# are:
Extra information
Estimated cost (XS, S, M, L, XL, XXL): XS
Related suggestions:
Affidavit (please submit!)
Please tick these items by placing a cross in the box:
Please tick all that apply: