I propose we allow putting a dot before the record field in the with expression to explicitly denote it as a field instead of a type:
type SdlWindowConfig =
{ WindowTitle : string
WindowX : int
WindowY : int }
static member defaultConfig =
{ WindowTitle = "Default Title"
WindowX = 0
WindowY = 0 }
type SdlConfig =
{ WindowConfig : SdlWindowConfig }
static member defaultConfig =
{ WindowConfig = SdlWindowConfig.defaultConfig }
type WorldConfig =
{ Imperative : bool
Accompanied : bool
Advancing : bool
FramePacing : bool
ModeOpt : string option
SdlConfig : SdlConfig }
static member defaultConfig =
{ Imperative = true
Accompanied = false
Advancing = true
FramePacing = false
ModeOpt = None
SdlConfig = SdlConfig.defaultConfig }
let worldConfig =
{ WorldConfig.defaultConfig with
.SdlConfig.WindowConfig.WindowTitle = "My Title" } // <-
Without the dot, backwards compatibility dictates that SdlConfig be resolved as a type.
let worldConfig =
{ WorldConfig.defaultConfig with
SdlConfig.WindowConfig.WindowTitle = "My Title" }
error FS0001: This expression was expected to have type
'WorldConfig'
but here has type
'SdlConfig'
The existing ways of approaching this problem in F# include
- not using nested record field update (boilerplate)
let sdlWindowConfig = { SdlWindowConfig.defaultConfig with WindowTitle = "My Title" }
let sdlConfig = { SdlConfig.defaultConfig with WindowConfig = sdlWindowConfig }
let worldConfig = { WorldConfig.defaultConfig with SdlConfig = sdlConfig }
// or the pyramid...
let worldConfig =
{ WorldConfig.defaultConfig with
SdlConfig =
{ SdlConfig.defaultConfig with
WindowConfig =
{ SdlWindowConfig.defaultConfig with
WindowTitle = "My Title" } } }
- prepending with type (unintuitive)
let worldConfig =
{ WorldConfig.defaultConfig with
WorldConfig.SdlConfig.WindowConfig.WindowTitle = "My Title" } // need to repeat "WorldConfig" for every update in SdlConfig!
Pros and Cons
The advantages of making this adjustment to F# are
- Less noise (we already use type inference to hide types, why require them at nested record field updates?)
- Less repetition
- Less surprises (with a style that uses the dot everywhere)
open System
type NotDU = Int32 // is a type abbreviation
type DU = | Int32 // unambiguously a DU so "it's a good practice to prepend |"
The disadvantage of making this adjustment to F# is another way to do the same thing.
Extra information
Estimated cost (XS, S, M, L, XL, XXL): S
Related suggestions:
Affidavit (please submit!)
Please tick these items by placing a cross in the box:
Please tick all that apply:
For Readers
If you would like to see this issue implemented, please click the 👍 emoji on this issue. These counts are used to generally order the suggestions by engagement.
I propose we allow putting a dot before the record field in the
withexpression to explicitly denote it as a field instead of a type:Without the dot, backwards compatibility dictates that
SdlConfigbe resolved as a type.The existing ways of approaching this problem in F# include
Pros and Cons
The advantages of making this adjustment to F# are
The disadvantage of making this adjustment to F# is another way to do the same thing.
Extra information
Estimated cost (XS, S, M, L, XL, XXL): S
Related suggestions:
Affidavit (please submit!)
Please tick these items by placing a cross in the box:
Please tick all that apply:
For Readers
If you would like to see this issue implemented, please click the 👍 emoji on this issue. These counts are used to generally order the suggestions by engagement.