fsharp / fsharp/fslang-suggestions
Allow the union pattern to be implemented explicitly
- Dominant language
- No language data
- Stars
- 373
- Forks
- 21
- PR merge metrics
- No merged PRs in 30d
Description
In F#, discriminated unions are a pattern, e.g.
```fsharp
type U = A of value: int | B of value: string
```
generates code containing roughly this public API:
```fsharp
type U =
static member NewA(value: int) = ...
static member NewB(value: string) = ...
member IsA: bool
member IsB: bool
member Tag: int
static type A =
inherit U
member value: int
static type B =
inherit U
member value: string
static type Tags =
| A = 0
| B = 1
```
plus various attributes.
I propose it be possible to implement this pattern explicitly (unchecked) without committing to a representation of the backing data beyond the presence of subtypes A and B of the reference type U, and the presence of `Tag`/`Tags`.
This is quite a large feature:
* there are some variations to consider for single case unions
* there are variations to consider for struct unions
* there will be responses that the pattern is too complex to write by hand. For example people may request that it is possible to omit the `Tag` and `Tags` even if pattern matching over a large number of union cases is slower for these cases (preferring type tests on the input type)
* there will be responses that authoring is not the same as proposed C# unions, which may reduce the utility of the feature
* there will be questions about whether it is possible to use FSharp.Reflection on these types, given this is driven by various additional attributes
* there will be questions about what happens if people get the pattern slightly wrong
* there will be questions about whether this allows https://github.com/fsharp/fslang-suggestions/issues/154
* there will be questions about whether the `Tags` need to form a contiguous `0..n-1` list
* there will be questions about whether the attributes need to be present
* it relies on #277
The existing way of approaching this problem in F# is to accept the default representations for backing data.
## Pros and Cons
The advantages of making this adjustment to F# are that programmers can control the ultimate representation of union types without subsequent consuming code changing and without breaking binary compatibility.
The disadvantages of making this adjustment to F# are that
* it is complex to use (more complex than people will like)
* its use cases are rare
* it may inhibit later development of features for unions
On the whole I feel this is "too costly" to do for the benefits it brings but I am recording the idea here, partly because it clarifies what was meant by #726 and partly because it relates to #154 and #277
## Extra information
Estimated cost (XS, S, M, L, XL, XXL): L
Related suggestions: https://github.com/fsharp/fslang-suggestions/issues/164 deals with some similar issues for records.
## 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](http://stackoverflow.com)) and I have searched stackoverflow for discussions of this issue
* [ ] 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
* [ ] 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 :+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 reviewing the dependency on #277 and the related suggestions #154, #726, and #164. The proposal raises unresolved questions about single-case and struct unions, tags, attributes, reflection, and malformed patterns. Done would require an agreed scope and language design before implementation work can begin.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- fsharp
- Domain
- compilers
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 20/100