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


#1

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?

Thanks.


#2

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.


#3

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


#4

If we have:

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

And:

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.


#5

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.