There are at least 3 ways to define a record:
type Record =
{ clients: int
field: string }
member x.MyField = x.field
type Record =
{ clients: int
field: string }
member x.MyField = x.field
type Record = {
clients: int
field: string
} with
member x.MyField = x.field
type Record =
{
clients: int
field: string
}
member x.MyField = x.field
If we cann't recommend a particular style (because people do it differently) we should at least list the common ones to help new-comers (and list advantages and disadvantages...
⚠Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.
The current guidance does not enumerate the various ways to define records, though I'd be open to a PR that does lay out a few of these other styles.
@cartermp Should we discuss and decide on one of the above with some people or just list those three (personally, I don't really like all of them) ?
type Record =
{ Clients: int
Field: string }
member x.MyField = x.field
The problem is none of them have a particularly nice line up between the end of definition and a member. Having the requirement to use { } seems odd.
@7sharp9 Note that while I completely agree with you that any of the styles "feel" awkward this issue is not really about that. What I'm asking for is: What do we suggest newcomers to use considering the current state of the language.
I think your comment should be a language suggestion or discussed with @dsyme directly ;)
@vasily-kirichenko Now I realize that your suggestion is slightly different:
type Record =
<indent >{ Clients: int
<indent+2>Field: string }
<indent >member x.MyField = x.field
vs
type Record =
<indent-2>{ Clients: int
<indent >Field: string }
<indent >member x.MyField = x.field
which was my suggestion. It seems your suggestion is also what the compiler uses and looks quite good. Maybe we should just go with that?
@matthid I totally agree :)
I use the same style that @vasily-kirichenko does.
One thing to keep in mind about using what the compiler does is documented here: #5552
TL;DR, for beginners who don't know how to please the compiler with indent/outdent rules, this is the best way to do it without getting yelled at by an IDE:
type MyRecord =
{
SomeField : int
}
interface IMyInterface
@vasily-kirichenko's suggestion is what you'll likely find the most online, which is a virtue. But so is recommending something that is as resilient as possible. The current section shows neither, so I think either of these is an improvement.
@cartermp Yes good feedback and indeed something we want to fix. The syntax you suggest seems the most F# "untypical" of all the suggestions to me as it uses a lot of "blank lines" and noise. Shouldn't we try to improve our tooling instead?
We could also go:
type Record =
{ clients: int
field: string }
member x.MyField = x.field
type Record =
<i >{<i-1>clients: int
<i ><i >field: string }
<i >member x.MyField = x.field
which I guess would fix this problem as well. But this is never seen anywhere at the moment (or at least I have never seen it).
3 means cleaner git diffs while saving vertical space and having simpler horizontal spacing.
In my experience, only two forms work "at scale": the one @vasily-kirichenko suggests (my personal favorite) and the 3rd choice from the original listing. I'd vote for either of those. Note, also, @vasily-kirichenko suggestion works best for _record instances_ (in case having symmetry between definition and instantiation is important).
3's instances are consistent:
let empty = {
Field1 = 1
Field2 = "hi"
}
can also be consistent with list / array style:
div [
firstThing prop1 [
innerThing prop2 prop3
inneIinnerThing prop4 prop5 [
deepThing noProp
]
]
secondThing prop6 [
lastThing prop7 prop8
]
]
as the first can:
div
[ firstThing prop1
[ innerThing prop2 prop3
innerThing prop4 prop5
[ deepThing noProp ] ]
secondThing prop6
[ lastThing prop7 prop8 ] ]
Added a suggestion PR https://github.com/dotnet/docs/pull/6956, which tries to capture this discussion
Most helpful comment