fsharp / fsharp/fslang-suggestions

Allow methods with name New* on DUs as long as they have different parameters

Open
#532 16 comments 0 reactions 0 assignees View on GitHub
approved-in-principle area: unions needs rfc
Dominant language
No language data
Stars
373
Forks
21
PR merge metrics
No merged PRs in 30d

Description

Allow to define a static method on DU which name is `New` and a set of parameters is different from the set of values of the DU case with name ``.

Sometimes DU case has composite values which can be set one by one or separately.
Imagine a ventilation channel which part has length and profile where profile has width and height.

``` F#
type Dimension = int
type TypeSize = int
type Profile = Profile of int * int

type ElementDimensions =
| Inherited of Length : Dimension
| TypeSizeDimensions of TypeSize : TypeSize * Length : Dimension
| CustomDimensions of Profile : Profile * Lenght : Dimension
```

So the last case can be constructed from **profile** and **length** or form **width**, **height** and **length**.
But neither this

``` F#
type ElementDimensions =
| Inherited of Length : Dimension
| TypeSizeDimensions of TypeSize : TypeSize * Length : Dimension
| CustomDimensions of Profile : Profile * Lenght : Dimension
static member NewCustomDimensions (width, height, length) =
CustomDimensions(Profile(width, height), length)
```

Nor this does work

``` F#
static member CustomDimensions (width, height, length) =
CustomDimensions(Profile(width, height), length)
```

## Pros and Cons

As this is a construction of the same DU case it would be natural to overload this method especially for consumer from C#. However be able to use `NewCustomDimensions (width, height, length)` the same way as `CustomDimensions (Profile, Length)` would be nice in F#.
Anyway DU case constructor is tupled.

## Workaround

Use a different case name, e.g.

```
type ElementDimensions =
| Inherited of Length : Dimension
| TypeSizeDimensions of TypeSize : TypeSize * Length : Dimension
| CustomDimensionsAux of Profile : Profile * Lenght : Dimension
static member CustomDimensions (width, height, length) = CustomDimensionsAux(Profile(width, height), length)
static member CustomDimensions (profile, length) = CustomDimensionsAux(profile, length)
```
Use a different method name not prefixing `New`, e.g.
```
type ElementDimensions =
| Inherited of Length : Dimension
| TypeSizeDimensions of TypeSize : TypeSize * Length : Dimension
| CustomDimensions of Profile : Profile * Lenght : Dimension
static member MakeCustomDimensions (width, height, length) = CustomDimensions(Profile(width, height), length)
static member MakeCustomDimensions (profile, length) = CustomDimensions(profile, length)
```

## Extra informtion

Estimated cost (XS, S, M, L, XL, XXL): I guess it is S, I don't have enough knowledge to estimate.

[Original issue](https://github.com/fsharp/fsharp/issues/604)

## Affadavit (must be submitted)

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
* [X] I would be willing to help implement and/or test this
* [ ] I or my company would be willing to help crowdfund F# Software Foundation members to work on this

Contributor guide

No contributing guide indexed for this repository

Research direction

No files, tests, or entry points are mentioned. Start with the DU examples and the proposed New overload rule, then review the language-design implications. Done would mean methods with distinct parameter sets can construct the corresponding DU case without the listed workarounds.

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
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.