We should use -> instead of : to denote function return type

Hello guys!
I have been using Kotlin for the past month and I absolutely love it :heart: (maybe too obsessed with it too)
I really like the syntax and it definitely has boosted my productivity by quite a bit.

However, there is one inconsistency in the syntax of Kotlin that in particular irks me, which is the syntax for denoting the return type of a function.

In function declarations, we use the : operator to denote the return type like so:

// function declaration
fun myFunction(a: Int, b: Char): Boolean {

However, the return type of a function in a function type is denoted using the -> operator like so:

// function type
val myFunction: (Int, Char) -> Boolean

Now, I read from this Kotlin webpage that the choice to use : in function declaration and -> in function type is to improve code readability, as illustrated in the following example from the webpage above:

// before:
fun max(col: Collection<Int>, compare: fun(Int, Int): Int): Int {
// after:
fun max(col: Collection<Int>, compare: (Int, Int) -> Int): Int {

I totally agree that it makes it more readable and I appreciate that. However, I believe that if we instead use the -> in function declarations, we can achieve a similar level of readability (in my opinion) while maintaining consistency, like so:

fun max(col: Collection<Int>, compare: (Int, Int) -> Int) -> Int {

If the above suggested syntax is used, consistency is improved like so:

fun myFunction(a: Int, b: Char) -> Boolean {
val myFunction: (Int, Char) -> Boolean

This makes perfect sense if we also consider that currently : is being used for denoting a type for a variable while -> is used for denoting a return type in function types as well to denote returning expressions in lambda functions. The type of myFunction is not Boolean, it is (Int, Char) -> Boolean, so using : to denote a return type for a function does not seem logical to me.

I think this is also used in Swift too (correct me if I am wrong).

I understand that it is nearly impossible to change the syntax now that Kotlin has already been released and is used in production; I also do see how trivial this inconsistency is and that there are more important issues at hand with the Kotlin development. However, I still want to write my thought about this since I love this language so much and I want to see if there is anyone out there that shares the same sentiment as me :rofl:


I see swings and roundabouts here:

  • On the one hand, using -> for function return types would indeed make them look more like function types.

  • But on the other, they would then look less like variable/property declarations — which are also things that yield a value of a given type.

I guess it depends how you interpret the type part of the function definition: is it primarily a part of a function type, or is it primarily telling you what value the function returns?

I think I tend to see it as the latter.

There’s also the issue of higher-order functions which return other functions. If -> were used both to separate a function’s parameters from its return type and also within that return type, would that not be confusing (and maybe introduce ambiguities)?


Well explained, thanks!
I think what you mean is → is partly to denote the type of the variable/value it is returning and partly to denote that the type is of a function.
And with function declarations, we already have the keyword fun, so I suppose logically we do not need to use →

1 Like

Respectfully I disagree. Here is an example

fun bla(arg:(Int)->String)->(String)->Int {


That looks like a nightmare for the parser

fun bla(arg:(Int)->String):(String)->Int {


Its a function that takes an integer to string function and returns a string to integer function. Also lambdas are not free. Sometimes the overhead cost of creating a lambda is enough to avoid it. Creating an anonymous fun perhaps. Here is a lambda { ident:Type → (expression to be returned) }
I like how the arrow makes it obvious you are using a lambda and you will paying the cost of creating a lambda.


Especially for the human parser, IMO.