Is there any reason Function types (like `(P1, P2, P3) -> R`) need a bracket in the left side

Is there any reason Function types (like (P1, P2, P3) -> R) need a bracket in the left side. It is conventient to write P1, P2, P3 -> R and some languages prefer the latter style.

Because we use () for empty parentheses, and it is easy to think we need a bracket to include multiple arguments?


It may be because it’s easier to parse - no other kind of type begins with a bracket - and because, as you said yourself, brackets are suggestive of functions. It also reduces possible confusion if the type of one or more of the parameters is itself a function type.

Having said all that, I’ve always found it rather strange that parameters within a lambda expression don’t have to be enclosed in brackets though I suppose in that case, if there are explicit parameters, the parser ‘knows’ that they’re going to be on the first line.

Another reason for needing brackets which has just occurred to me is that the function type may have a receiver. To take an example of such a function literal from the documentation:

val sum = fun Int.(other: Int): Int = this + other

this would look very strange - and be difficult to read - if the brackets were not present

If we have:

fun f1(a: ((A) -> B) -> C) {
  // do something


fun f2(a: (A) -> (B) -> C) {
  // do something else

In your way, both of them should be written as:

fun fStupid(a: A -> B -> C) {

Ambiguity sucks.

1 Like

Another potential ambiguity:

fun func(a: A, b: B -> Unit): Unit

Does func take in two parameters (an A and a function from B to Unit) or one (a function from an A and a B to Unit)?

The same ambiguity can arise at the call site, too.

1 Like