add1 (of type n:int -> int, with labeled parameter) cannot be used as the first argument (of type 'a -> 'b, without labels) in List.map:
let add1 ~(n: int) : int = n + 1
let nums = [1; 2; 4; 8]
let result = List.map add1 nums (* Error: add1 has type n:int -> int
but an expression was expected of type 'a -> 'b *)
In OCaml, labels such as ~n are part of the type, so n:int -> int and int -> int are not compatible types. One could imagine systems where one could implicitly cast values from type n:int -> int to values of type int -> int but these systems are more complex and this is not done in OCaml.
This would be ambiguous. Let’s extend your example
let f ~n m = 1 + n + m * m
let g xs = List.map f xs
then there is two way to interpret the g function, either
let g xs = List.map (fun x y -> f ~n:x y) xs
because obviously n is the first parameter of f; or
let g xs = List.map (fun x y -> f ~n:y x) xs
because obviously m is the first positional argument of f.
And this happens for a very simple application and type.
Rather than trying to create elaborated implicit conversion rules (which leads to many issues once such conversion rule can be chained), OCaml eschews any implicit conversion.
This creates some boilerplate from time to time.
However, it helps to make sure that both the caller and callee agree on the meaning of labels.
Labels often are used to make function more readable and easier to use, this erasing a label should be a conscious decision.
Also @unfode would you mind trying to not use screenshot to post code? Images are not accessible and makes the forum harder to read for blind users.
Most of the time you would design functions such that the labelled parameters would not be the ones that would be injected by higher-order functions like map anyway, so having a label doesn’t really add any extra boilerplate. E.g.
let add ~x y = x + y
let nums = List.map (add ~x:1) [1; 2; 3]
In your example, x and y of add are “equal” in terms of importance. It doesn’t make sense to me that x has a label while y doesn’t. When you use add directly, wouldn’t it be weird to write let sum = add ~x:1 2?
I tried F# today, where parameters are labelled by default. Example:
let greet (name: string) : string = $"Hello {name} from F#!"
let greet_lambda: string -> string = fun name -> $"Hi, {name}!"
let names: string list = ["Alice"; "Bob"]
let greetings = List.map greet names
let greetings_lambda = List.map greet_lambda names