Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shorthand syntax for single case DUs #727

Closed
5 tasks done
Happypig375 opened this issue Mar 25, 2019 · 10 comments
Closed
5 tasks done

Shorthand syntax for single case DUs #727

Happypig375 opened this issue Mar 25, 2019 · 10 comments

Comments

@Happypig375
Copy link
Contributor

Happypig375 commented Mar 25, 2019

Title of Suggestion

I propose we add a shorthand syntax for single case Discriminated Unions.

The existing way of approaching this problem in F# is usually repeating the type name.

//Current
type SomeDomainType = SomeDomainType of int
type Temperature = private Temperature of int

//Proposed
type SomeDomainType of int
type Temperature private of int

Pros and Cons

The advantages of making this adjustment to F# are

  1. They are common
  2. It's duplicate information for the reader
  3. The Rename tool in Visual Studio cannot rename both at once because types are not union cases, but they usually take the same name.

The disadvantages of making this adjustment to F# are one more syntax to learn.

Extra information

Estimated cost (XS, S, M, L, XL, XXL): S

Related suggestions: (put links to related suggestions here)

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
@realvictorprm
Copy link
Member

I think this is a minor change with big positive impact. Thumbs up! :)

@theprash
Copy link

The disadvantages of making this adjustment to F# are one more syntax to learn.

Just to expand on this, for people new to F# I've found a common pitfall is to not fully understand the difference between a DU case and the DU type itself. Even after understanding the difference they sometimes conflate these two things for a while. This syntax blurs the boundaries between those two things which could contribute to that misunderstanding.

I would also add as a distinct disadvantage that this would add yet another instance in F# where there are multiple equivalent ways to do exactly the same thing, making it harder to know what's idiomatic and harder to read code in general. I think F# already has more of these than many languages. This is made worse by being a late addition to the language, so even the most idiomatic code will never use this feature if it was written for earlier F# versions.

@sgtz
Copy link

sgtz commented Mar 25, 2019

at least the way I use them, single case DUs may fragment into n-cases... that's part of the beauty of using them. Visually, I don't see a clear path from the proposed shorthand to the additional cases. Stylistically, I feel it's better to be explicit on this.

@amongonz
Copy link

amongonz commented Apr 3, 2019

I think this syntax is better suited as a general extension of the existing syntax exception MyException of msg:string, but for normal classes/structs. So it would allow let-fields, inheritance, etc., but also pattern matching over the primary constructor.

Bonus points if we could use the parameters inside the type directly, unlike exception syntax. Silly example:

type HttpHeader of name:string * value:string with
    member __.Formatted = sprintf "%s: %s" name value

Edit: note it would also subsume existing exception syntax:

type TemperatureException of value:int with
    inherit Exception(sprintf "Reached %d degrees" value) // No `this.Message` override needed!

@smoothdeveloper
Copy link
Contributor

I'm not yet sure about the proposed syntax, as it is not too inconvenient to define a single case DU right now when needed, but it looks fitting idioms.

Is this something that should go along the same line as haskell "newtype" or even related to some degree to units of measures?

@7sharp9
Copy link
Member

7sharp9 commented Apr 5, 2019

I think this shorthand is too similar to a type alias.

@Happypig375
Copy link
Contributor Author

of stands out a lot more than =.

@charlesroddie
Copy link

I've found a common pitfall is to not fully understand the difference between a DU case and the DU type itself.

Agreed. Using the same name for the DU type as for one of its cases is confusing. If anything, doing this should be warned about, not encouraged with a shorthand syntax.

@cartermp
Copy link
Member

cartermp commented Apr 6, 2019

I can certainly sympathize with the existing syntax with single-case DUs today - it kind of sucks, and the tooling point is valid. I wouldn't shocked if it were done differently had F# been first conceived today. However, I think this does break the following design principles:

  • education/learning paths and simplicity
  • does this give multiple ways to achieve the same thing

@dsyme
Copy link
Collaborator

dsyme commented Apr 12, 2023

Closing as I'm not inclined to any new syntax for these.

@dsyme dsyme closed this as completed Apr 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

10 participants