A function literal as an "anonymous function", i.e. a function that is not declared, but passed immediately as an expression. Consider the following example:
max(strings, {a, b -> a.length < b.length})Function max is a higher-order function, i.e. is takes a function value as the second argument. This second argument is an expression that is itself a function, i.e. a function literal. As a function, it is equivalent to
fun compare(a : String, b : String) : Boolean = a.length < b.lengthFunction types
For a function to accept another function as a parameter, we have to specify a function type for that parameter. For example the abovementioned function max is defined as follows:
fun max<T>(collection : Collection<out T>, less : (T, T) -> Boolean) : T? { var max : T? = null for (it in collection) if (max == null || less(max, it)) max = it return max }The parameter less is of type (T, T) -> Boolean, i.e. a function that takes two parameters of type T and returns a Boolean: true if the first one is smaller than the second one.
In the body, line 4, less is used as a function: it is called by passing two arguments of type T.
A function type is written as above, or may have named parameters, for documentation purposes and to enable calls with named arguments.
val compare : (x : T, y : T) -> Int = ...Syntactic forms of function literals
The full syntactic form of function literals, i.e. literals of function types, is as follows:
val sum = {(x : Int, y : Int) : Int -> x + y}- A function literal is always surrounded by curly braces,
- parameter declarations in the full syntactic form go inside parentheses and have optional type annotations,
- the optional return type annotation goes after the parameter list,
- the body goes after an '->' sign.
If we leave all the optional annotations out, what's left looks like this:
val sum : (Int, Int) -> Int = {(x, y) -> x + y}As this is the most common case, Kotlin allows us to leave the parentheses out as well, if no type annotations are present, and so we get the short syntactic form for functional literals:
val sum : (Int, Int) -> Int = {x, y -> x + y}It very common that a function literal has only one parameter. If Kotlin can figure the signature out itself, it allows us not to declare the only parameter, and will implicitly declare it for us under the name it:
ints.filter {it > 0} // this literal is of type '(it : Int) -> Boolean'Note that if a function takes another function as the last parameter, the function literal argument can be passed outside the parenthesized argument list. See Higher-order functions and the grammar for callSuffix.
See the grammar for function literals here.
Closures
A function literal (as well as a local function and object expressions) can access its closure, i.e. the variables declared in the outer scope. Unlike Java the closure variables can be modified:
var sum = 0 ints filter {it > 0} forEach { sum += it } print(sum)Extension function literals
Besides ordinary functions, Kotlin supports extension functions. This kind of functions in so useful, that extension function literals are also supported. One of the most important examples of their usage is Type-safe Groovy-style builders.
An extension function differs from an ordinary one in that it has a receiver type specification. One can specify a receiver type in a function literal as well:
val sum = {Int.(other : Int) : Int -> this + other}Receiver type may be specified only in the full syntactic form of a function literal (remember that parameter types and return type annotations are optional in this form).
Such a literal has a function type with receiver:
sum : Int.(other : Int) -> Intit can be called with a dot or in infix form (since it has only one parameter):
1.sum(2) 1 sum 2Disambiguation of this expressions
See This expressions.
What's next
Expressions
Functions

11 Comments
comments.show.hideJul 24, 2011
Anonymous
Just curious, what do you call the '=>' sign in Kotlin?
Thanks.
--
Jul 25, 2011
Maxim Shafirov
Fat arrow
Jan 25, 2012
Clayton Wohl
I'm not sure if this is the right place to ask, but how do I get the following example to compile? I want to assign one of my functions to a variable (or value)
Jan 25, 2012
Andrey Breslav
Currently, the only way to do this is to say:
fundoub(i:Int):Int{returni*2;}funmain(args:Array<String>){valt2={(i:Int)->doub(i)}}Dec 19, 2012
Andy Selvig
Are there any thoughts or plans about implementing the ability to pass non-literal functions (or even methods) as arguments? That would be a huge feature and really let you write clean, composable code.
Dec 19, 2012
Andrey Breslav
Yes, we will support this. Hopefully, rather soon.
Nov 19, 2012
Oliver Plow
Reading about the outer scope in the section about closures brought the idea of inner in Beta to my mind: see Fig.2 on p.6 in this document. I liked that idea and it has gone completely lost. Do you think inner would be useful for Kotlin? I know it conflicts somehow with super, but it might be worth considering :-).
Nov 19, 2012
Andrey Breslav
What use cases do you have in mind?
Nov 20, 2012
Oliver Plow
Oh yeah, I should have expected this answer ... ;-). Lazy as I am I just cloned the example from the document:
This is not really in the spirit of inner as in Beta, but Beta is the only language I have seen where MySubClass.first() would automatically call super.first() without the developer having coded this explicitly.
I tried to play around with the Qualified this thing. But I guess it does not apply here, since traits and classes are not nestedt in the way of nested classes. The problem with this example is IMHO that the trait with inner.first() takes over control of what is happening. But control should always remain with the class using the trait. At least that's the way I used to see things.
Nevertheless, maybe there is still a point with inner here as it saves some extra methods.
Nov 20, 2012
Oliver Plow
Well, I believe it does not work. You just do this:
The inner.first() thing only saves us from having to declare
and that is not too much of a bang to justify a new keyword, I believe. Maybe someone else or me still gets a good idea how to use it ;-).
Nov 20, 2012
Andrey Breslav
Agree