docs
docs copied to clipboard
Anonymous records are not nominal
Type of issue
Outdated article
Description
The paragraph:
Anonymous records are nominal types. They are best thought of as named record types (which are also nominal) that do not require an up-front declaration.
is misleading ‒ the code goes to show that anonymous records with different members are incompatible, but I am not sure what that is supposed to prove ‒ int * int is also incompatible with string * string and I haven't heard one call tuples nominal.
This should be the real proof:
type R1 = { X: int }
type R2 = { X: int }
let r1 : R1[] = [| |]
let r2 : R2[] = r1 // error - type mismatch
type AR1 = {| X: int |}
type AR2 = {| X: int |}
let ar1 : AR1[] = [| |]
let ar2 : AR2[] = ar1 // fine - AR2 is identical to AR1
Two declarations with a different name but same structure being equivalent is exactly what a structural system exhibits, as opposed to a nominal one.
Page URL
https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/anonymous-records
Content source URL
https://github.com/dotnet/docs/blob/main/docs/fsharp/language-reference/anonymous-records.md
Document Version Independent Id
7c5955cd-60ba-12a6-8661-d9b9b7700cf1
Platform Id
178aabe3-cc05-5195-37e1-d1bd63900af6
Article author
@KathleenDollard
Metadata
- ID: b69dfedf-d03a-1733-5c06-7b2000bad772
- PlatformId: 178aabe3-cc05-5195-37e1-d1bd63900af6
- Service: dotnet-fsharp
@T-Gro @KathleenDollard Thoughts?
This issue is correct - the examples does not prove much about nominality. With regular records, the nominality comes from the fully qualified name.
For anonymous records, nominality is from using the exact same set of fields and field types.
I think this section is not adding much by speaking about nominal types (as opposed to e.g. positional types, tuples) - we might end up better removing that sub-section alltogether.
let a = {| X = 1; Y = false |}
let b = {| Y = true; X = 5 |}
// We can compare a and b. They are same by using same fields
let tup1 = (1,true)
let tup2 = (false,5)
// We cannot compare two tuples, since the order is switched - tuples are positional types
But as written above, even though an explanation is possible, I do not see much value of describing it here. It's type-theory interesting, not end-user interesting I would say.