This issue confused me too in the beginning. Functions and methods are not alike.
- Functions are curried by default to support partial application. They don't support named argument calls.
- Methods support named arguments using a single tuple for all parameters.
- (EDIT after Bent Tranberg's comment) Methods also support curried declaration
member _.Add x y = x + y and even mixed style declaration member _.Add3 (x: int, y: int) (z: int) = x + y + z but these methods cannot be called using named arguments o.Add3 (y=2, x=1) 3 💥
In JavaScript, named arguments can be simulated using an object literal as argument. Let's try do the same in F#, using tuple or record:
1. Tuple: Method arguments are provided all at once with a tuple. Can we use a tuple as function parameter and call the function with named arguments? No ❌
let add (x, y) = x + y
add (x = 1, y = 2) // 💥
// ~ Error FS0039: The value or constructor 'x' is not defined
2. Anonymous record: not possible due to actual limitation in anonymous record deconstruction ❌
let add {| X = x; Y = y |} = x + y
// ~~ Error FS0010: Unexpected symbol '{|' in pattern
3. Named record: ⚠️
type AddParam = { x: int; y: int }
let add { x = x; y = y } = x + y
add { x = 1; y = 2 }
This way, we are able to name the arguments and choose their order ({ y = 2; x = 1 } but we loose the partial application. So it's not idiomatic→ should be avoided, unless in specific cases.
4. Single-case DU: 👌
If we care only about the argument naming but not about the argument re-ordering, we can use discriminated unions, especially single-case DU:
type XParam = X of int
type YParam = Y of int
let add (X x) (Y y) = x + y
add (X 1) (Y 2)
This way, the arguments appeared as named and partial application is preserved.
--
EDIT
☝ I don't recommend creating single-case DU just to simulate named arguments ! It's the other way around: when we have single-case DU in our domain model, we know that they will bring their semantic to document the code and help reasoning about the code, in this case more or less like named arguments.