What is a "receiver" in Kotlin? - kotlin
How is it related to extension functions? Why is with a function, not a keyword?
There appears to be no explicit documentation for this topic, only the assumption of knowledge in reference to extensions.
It is true that there appears to be little existing documentation for the concept of receivers (only a small side note related to extension functions), which is surprising given:
their existence springing out of extension functions;
their role in building a DSL using said extension functions;
the existence of a standard library function with, which given no knowledge of receivers might look like a keyword;
a completely separate syntax for function types.
All these topics have documentation, but nothing goes in-depth on receivers.
First:
What's a receiver?
Any block of code in Kotlin may have a type (or even multiple types) as a receiver, making functions and properties of the receiver available in that block of code without qualifying it.
Imagine a block of code like this:
{ toLong() }
Doesn't make much sense, right? In fact, assigning this to a function type of (Int) -> Long - where Int is the (only) parameter, and the return type is Long - would rightfully result in a compilation error. You can fix this by simply qualifying the function call with the implicit single parameter it. However, for DSL building, this will cause a bunch of issues:
Nested blocks of DSL will have their upper layers shadowed:
html { it.body { // how to access extensions of html here? } ... }
This may not cause issues for a HTML DSL, but may for other use cases.
It can litter the code with it calls, especially for lambdas that use their parameter (soon to be receiver) a lot.
This is where receivers come into play.
By assigning this block of code to a function type that has Int as a receiver (not as a parameter!), the code suddenly compiles:
val intToLong: Int.() -> Long = { toLong() }
Whats going on here?
A little side note
This topic assumes familiarity with function types, but a little side note for receivers is needed.
Function types can also have one receiver, by prefixing it with the type and a dot. Examples:
Int.() -> Long // taking an integer as receiver producing a long
String.(Long) -> String // taking a string as receiver and long as parameter producing a string
GUI.() -> Unit // taking an GUI and producing nothing
Such function types have their parameter list prefixed with the receiver type.
Resolving code with receivers
It is actually incredibly easy to understand how blocks of code with receivers are handled:
Imagine that, similar to extension functions, the block of code is evaluated inside the class of the receiver type. this effectively becomes amended by the receiver type.
For our earlier example, val intToLong: Int.() -> Long = { toLong() } , it effectively results in the block of code being evaluated in a different context, as if it was placed in a function inside Int. Here's a different example using handcrafted types that showcases this better:
class Bar
class Foo {
fun transformToBar(): Bar = TODO()
}
val myBlockOfCodeWithReceiverFoo: (Foo).() -> Bar = { transformToBar() }
effectively becomes (in the mind, not code wise - you cannot actually extend classes on the JVM):
class Bar
class Foo {
fun transformToBar(): Bar = TODO()
fun myBlockOfCode(): Bar { return transformToBar() }
}
val myBlockOfCodeWithReceiverFoo: (Foo) -> Bar = { it.myBlockOfCode() }
Notice how inside of a class, we don't need to use this to access transformToBar - the same thing happens in a block with a receiver.
It just so happens that the documentation on this also explains how to use an outermost receiver if the current block of code has two receivers, via a qualified this.
Wait, multiple receivers?
Yes. A block of code can have multiple receivers, but this currently has no expression in the type system. The only way to achieve this is via multiple higher-order functions that take a single receiver function type. Example:
class Foo
class Bar
fun Foo.functionInFoo(): Unit = TODO()
fun Bar.functionInBar(): Unit = TODO()
inline fun higherOrderFunctionTakingFoo(body: (Foo).() -> Unit) = body(Foo())
inline fun higherOrderFunctionTakingBar(body: (Bar).() -> Unit) = body(Bar())
fun example() {
higherOrderFunctionTakingFoo {
higherOrderFunctionTakingBar {
functionInFoo()
functionInBar()
}
}
}
Do note that if this feature of the Kotlin language seems inappropriate for your DSL, #DslMarker is your friend!
Conclusion
Why does all of this matter? With this knowledge:
you now understand why you can write toLong() in an extension function on a number, instead of having to reference the number somehow. Maybe your extension function shouldn't be an extension?
You can build a DSL for your favorite markup language, maybe help parsing the one or other (who needs regular expressions?!).
You understand why with, a standard library function and not a keyword, exists - the act of amending the scope of a block of code to save on redundant typing is so common, the language designers put it right in the standard library.
(maybe) you learned a bit about function types on the offshoot.
When you call:
"Hello, World!".length()
the string "Hello, World!" whose length you're trying to get is called the receiver.
More generally, any time you write someObject.someFunction(), with a . between the object and the function name, the object is acting as the receiver for the function. This isn't special to Kotlin, and is common to many programming languages that use objects. So the concept of a receiver is likely very familiar to you, even if you haven't heard the term before.
It's called a receiver because you can think of the function call as sending a request which the object will receive.
Not all functions have a receiver. For example, Kotlin's println() function is a top-level function. When you write:
println("Hello, World!")
you don't have to put any object (or .) before the function call. There's no receiver because the println() function doesn't live inside an object.
On the receiving end
Now let's look at what a function call looks like from the point of view of the receiver itself. Imagine we've written a class that displays a simple greeting message:
class Greeter(val name: String) {
fun displayGreeting() {
println("Hello, ${this.name}!")
}
}
To call displayGreeting(), we first create an instance of Greeter, then we can use that object as a receiver to call the function:
val aliceGreeter = Greeter("Alice")
val bobGreeter = Greeter("Bob")
aliceGreeter.displayGreeting() // prints "Hello, Alice!"
bobGreeter.displayGreeting() // prints "Hello, Bob!"
How does the displayGreeting function know which name to display each time? The answer is the keyword this, which always refers to the current receiver.
When we call aliceGreeter.displayGreeting(), the receiver is aliceGreeter, so this.name points to "Alice".
When we call bobGreeter.displayGreeting(), the receiver is bobGreeter, so this.name points to "Bob".
Implicit receivers
Most of the time, there's actually no need to write this. We can replace this.name with just name and it will implicitly point to the name property of the current receiver.
class Greeter(val name: String) {
fun displayGreeting() {
println("Hello, $name!")
}
}
Notice how that differs from accessing a property from outside the class. To print the name from outside, we'd have to write out the full name of the receiver:
println("Hello, ${aliceGreeter.name}")
By writing the function inside the class, we can omit the receiver completely, making the whole thing much shorter. The call to name still has a receiver, we just didn't have to write it out. We can say that we accessed the name property using an implicit receiver.
Member functions of a class often need to access many other functions and properties of their own class, so implicit receivers are very useful. They shorten the code and can make it easier to read and write.
How do receivers relate to extensions?
So far, it seems like a receiver is doing two things for us:
Sending a function call to a specific object, because the function lives inside that object
Allowing a function convenient and and concise access to the other properties and functions that live inside the same object
What if we want to write a function that can use an implicit receiver for convenient access to the properties and functions of an object, but we don't want to (or can't) write our new function inside that object/class? This is where Kotlin's extension functions come in.
fun Greeter.displayAnotherGreeting() {
println("Hello again, $name!")
}
This function doesn't live inside Greeter, but it accesses Greeter as if it was a receiver. Notice the receiver type before the function name, which tells us that this is an extension function. In the body of the extension function, we can once again access name without its receiver, even though we're not actually inside the Greeter class.
You could say that this isn't a "real" receiver, because we're not actually sending the function call to an object. The function lives outside the object. We're just using the syntax and appearance of a receiver because it makes for convenient and concise code. We can call this an extension receiver, to distinguish it from the dispatch receiver that exists for functions that are really inside an object.
Extension functions are called in the same way as member functions, with a receiver object before the function name.
val aliceGreeter = Greeter("Alice")
aliceGreeter.displayAnotherGreeting() // prints "Hello again, Alice!"
Because the function is always called with an object in the receiver position before the function name, it can access that object using the keyword this. Like a member function, an extension function can also leave out this and access the receiver's other properties and functions using the current receiver instance as the implicit receiver.
One of the main reasons extension functions are useful is that the current extension receiver instance can be used as an implicit receiver inside the body of the function.
What does with do?
So far we've seen two ways to make something available as an implicit receiver:
Create a function inside the receiver class
Create an extension function outside the class
Both approaches require creating a function. Can we have the convenience of an implicit receiver without declaring a new function at all?
The answer is to call with:
with(aliceGreeter) {
println("Hello again, $name!")
}
Inside the block body of the call to with(aliceGreeter) { ... }, aliceGreeter is available as an implicit receiver and we can once again access name without its receiver.
So how come with can be implemented as a function, rather than a language feature? How is it possible to simply take an object and magic it into an implicit receiver?
The answer lies with lambda functions. Let's consider our displayAnotherGreeting extension function again. We declared it as a function, but we could instead write it as a lambda:
val displayAnotherGreeting: Greeter.() -> Unit = {
println("Hello again, $name!")
}
We can still call aliceGreeter.displayAnotherGreeting() the same as before, and the code inside the function is the same, complete with implicit receiver. Our extension function has become a lambda with receiver. Note the way the Greeter.() -> Unit function type is written, with the extension receiver Greeter listed before the (empty) parameter list ().
Now, watch what happens when we pass this lambda function as an argument to another function:
fun runLambda(greeter: Greeter, lambda: Greeter.() -> Unit) {
greeter.lambda()
}
The first argument is the object that we want to use as the receiver. The second argument is the lambda function we want to run. All runLambda does is to call the provided lambda parameter, using the greeter parameter as the lambda's receiver.
Substituting the code from our displayAnotherGreeting lambda function into the second argument, we can call runLambda like this:
runLambda(aliceGreeter) {
println("Hello again, $name!")
}
And just like that, we've turned aliceGreeter into an implicit receiver. Kotlin's with function is simply a generic version of this that works with any type.
Recap
When you call someObject.someFunction(), someObject is acting as the receiver that receives the function call
Inside someFunction, someObject is "in scope" as the current receiver instance, and can be accessed as this
When a receiver is in scope, you can leave out the word this and access its properties and functions using an implicit receiver
Extension functions let you benefit from the receiver syntax and implicit receivers without actually dispatching a function call to an object
Kotlin's with function uses a lambda with receiver to make receivers available anywhere, not just inside member functions and extension functions
Kotlin knows the concept of a function literals with receiver. It enables access on visible methods and properties of a receiver of a lambda within its body without having to use any additional qualifier. That's very similar to extension functions in which you can as well access members of the receiver object inside the extension.
A simple example, also one of the greatest functions in the Kotlin standard library, is apply:
public inline fun <T> T.apply(block: T.() -> Unit): T {
block()
return this
}
Here, block is a function literal with receiver. This block parameter is executed by the function and the receiver of apply, T, is returned to the caller. In action this looks as follows:
val foo: Bar = Bar().apply {
color = RED
text = "Foo"
}
We instantiate an object of Bar and call apply on it. The instance of Bar becomes the receiver of apply. The block, passed as an argument in curly brackets does not need to use additional qualifiers to access and modify the properties color and text.
The concept of lambdas with receiver is also the most important feature for writing DSLs with Kotlin.
var greet: String.() -> Unit = { println("Hello $this") }
this defines a variable of type String.() -> Unit, which tells you
String is the receiver
() -> Unit is the function type
Like F. George mentioned above, all methods of this receiver can be called in the method body.
So, in our example, this is used to print the String. The function can be invoked by writing...
greet("Fitzgerald") // result is "Hello Fitzgerald"
the above code snippet was taken from Kotlin Function Literals with Receiver – Quick Introduction by Simon Wirtz.
Simply put ( without any extra words or complications) , the "Receiver" is the type being extended in the extension function or the class name. Using the examples given in answers above
fun Foo.functionInFoo(): Unit = TODO()
Type "Foo" is the "Receiver"
var greet: String.() -> Unit = { println("Hello $this") }
Type "String" is the "Receiver"
Additional tip: Look out for the Class before the fullstop(.) in the "fun" (function) declaration
fun receiver_class.function_name() {
//...
}
Simply put:
the receiver type is the type an extension function extends
the receiver object is the object an extension function is called on; the this keyword inside the function body corresponds to the receiver object
An extension function example:
// `Int` is the receiver type
// `this` is the receiver object
fun Int.squareDouble() = toLong() * this
// a receiver object `8` of type `Int` is passed to the `square` function
val result = 8.square()
A function literal example, which is pretty much the same:
// `Int` is the receiver type
// `this` is the receiver object
val square: Int.() -> Long = { toLong() * this }
// a receiver object `8` of type `Int` is passed to the `square` function
val result1 = 8.square()
val result2 = square(8) // this call is equal to the previous one
The object instance before the . is the receiver. This is in essence the "Scope" you will define this lambda within. This is all you need to know, really, because the functions and properties(varibles, companions e.t.c) you will be using in the lambda will be those provided within this scope.
class Music(){
var track:String=""
fun printTrack():Unit{
println(track)
}
}
//Music class is the receiver of this function, in other words, the lambda can be piled after a Music class just like its extension function Since Music is an instance, refer to it by 'this', refer to lambda parameters by 'it', like always
val track_name:Music.(String)->Unit={track=it;printTrack()}
/*Create an Instance of Music and immediately call its function received by the name 'track_name', and exclusively available to instances of this class*/
Music().track_name("Still Breathing")
//Output
Still Breathing
You define this variable with and all the parameters and return types it will have but among all the constructs defined, only the object instance can call the var, just like it would an extension function and supply to it its constructs, hence "receiving" it.
A receiver would hence be loosely defined as an object for which an extension function is defined using the idiomatic style of lambdas.
Typically in Java or Kotlin you have methods or functions with input parameters of type T. In Kotlin you can also have extension functions that receive a value of type T.
If you have a function that accepts a String parameter for example:
fun hasWhitespace(line: String): Boolean {
for (ch in line) if (ch.isWhitespace()) return true
return false
}
converting the parameter to a receiver (which you can do automatically with IntelliJ):
fun String.hasWhitespace(): Boolean {
for (ch in this) if (ch.isWhitespace()) return true
return false
}
we now have an extension function that receives a String and we can access the value with this
Related
How do I specify an ActionListener in Kotlin?
I want to add an ActionListener to a JButton in Kotlin. In Java, I would just write this: JPanel makeButtonPanel() { JPanel panel = new JPanel(new FlowLayout()); JButton dirButton = new JButton("Change directory"); dirButton.addActionListener(e -> chooseDirectory()); panel.add(dirButton) return panel; } But it's not so simple in Kotlin. I first tried this: private fun makeButtonPanel() : JPanel { val panel = JPanel(FlowLayout()) val dirButton = JButton("Choose") dirButton.addActionListener(e -> chooseDirectory()) // error message here // ... } private fun chooseDirectory() { ... } But I'm getting this error message: Type Mismatch Required: ((ActionEvent!) -> Unit)! Found: KFunction1<ActionEvent, Unit> I understand that the ! means that this is a java method with uncertain nullability, but that doesn't help me understand how to write it. All I want it to do is call the chooseDirectory() method. There must be a clean, simple way to do this, but I don't see it.
As you've discovered, you need to use braces ({ }). This is because braces are a necessary part of defining a lambda in Kotlin. (That differs from languages like Java and Scala, where the necessary part is the -> or => arrow. That's because in Kotlin the arrow is optional if there are one or no parameters; if one, the it keyword is used.) Without the braces, the code would call your chooseDirectory() function, and try to pass its result to addActionListener() — which obviously wouldn't work. Braces are also sufficient: they're taken as defining a lambda unless you're giving the body of a function or method or an if/when branch. (Again, this differs from most C/Java-like languages. In Kotlin, if you just want a block scope, you have to use a construct such as run.) As for the parentheses, they're optional here. You could include them if you wanted: dirButton.addActionListener({ chooseDirectory() }) But Kotlin has a convention that if a function's last parameter is a function, you can pass it after the parens: dirButton.addActionListener(){ chooseDirectory() } And if that would make the parens empty, then you can omit them entirely: dirButton.addActionListener{ chooseDirectory() } That's to allow functions that look like new language syntax. For example, you may have met the with function: with(someObject) { itsProperty = someValue } That's just a perfectly ordinary function, defined in the standard library, and taking a function as its last parameter. Similarly, repeat: repeat(10) { // Some code to be run 10 times… } There's one further thing worth mentioning here. In Kotlin, lambdas are one way to define functions, which are first-class types and can be defined, passed around, and used just like other types. This differs from Java, which has traditionally used interfaces for those purposes — often interfaces with a Single Abstract Method (‘SAM interfaces’) — and in which lambdas are little more than syntactic sugar for defining an anonymous implementation of such an interface. As a special case, for interoperability, Kotlin allows a lambda to define an implementation of a Java SAM interface (or, since Kotlin 1.4, of a Kotlin fun interface), instead of a function. ActionListener is a Java SAM interface, which is why you can use a lambda here.
Okay, I figured it out, and it was pretty simple. I just have to dispense with the parentheses and say dirButton.addActionListener { chooseDirectory() } I'm still not clear on when I should use braces instead of parentheses.
When do I use another function without paramters in Kotlin?
I'm a novice of Kotlin. I found that I can use another function without parameters even if it has. Let me know when I can use it. Q1) Why can I use 2 types? (with parameters & without parameters) Is it Kotlin's feature? Q2) What does it mean? ((Result!) -> Unit)!
It seems you are confused, you can never use a function without arguments. If the function has arguments then you have to fill the slot somehow. The closest thing that could relate to what you are referring to is default values for arguments. fun example(boolean: Boolean = true) {} example() example(true) example(false) You can omit the argument because it has defaulted in the function signature. The documentation What you are showing in the image file is a lambda. In the first example: signIn(listener: Session...) That seems to be a callback. So it is gonna be an interface or maybe an abstract class called when some async operation is finished. The second example, it is the callback implemented as a lambda signIn() { result -> //do something } In Kotlin the last argument if it is a lambda or something that can be implemented as a lambda can be moved out of the parenthesis for syntactic sugar. A lambda is like an anonymous function, it is a literal of a function. By example you can declare a lambda: val lambda = {text: String -> text.lenght % 2 == 0} fun setRuleForText(rule: (String)-> Boolean) {...} setRuleForText(lambda) setRuleForText() { text: String text.isNotEmpty() } In this case, the argument is a kotlin function. The argument rule is a function that receives a String as an argument and returns Boolean. Something to point out is that expressions return the last written value without the need for the reserved return word. This is the documentation. And here you can see from a good source more about functions (the author is a Kotlin certified trained by Jetbrains) In your case (Result) -> Unit means the lambda should receive a Result type as argument and then return Unit (unit is like void in Java but is more than that), no explicit return type. signIn() { result -> //do something } Most of the types, the argument on lambdas is inferred automatically, but if not, then signIn() { result: Result -> //do something }
Both of the listed functions take a parameter. The first is: signIn(listener: Session.SignInListener!) That takes a single parameter, of type Session.SignInListener. (The ! means that Kotlin doesn't know whether it's nullable or not, because it's from Java and isn't annotated.) The other is: signIn {...} (listener: ((Result!) -> Unit)!) That's the IDE's representation of the function with this signature: signIn(listener: ((Result!) -> Unit)!) That takes a single parameter, which is a function type (see below). The reason the IDE shows it with braces is that in Kotlin, if the last parameter to a function is a lambda, you can move it outside the parentheses. So a call like this: signIn({ println(it) }) could equally well be written like this: signIn() { println(it) } The two forms mean exactly the same. And, further, if the lambda is the only parameter, you can omit the parens entirely: signIn { println(it) } Again, it means exactly the same thing. That syntax allows you to write functions that look like new language syntax. For example: repeat (10) { // ... } looks like a new form of loop construct, but it's really just a function called repeat, which takes two parameter (an integer, and a lambda). OK, let's look at that function type: ((Result!) -> Unit)! That's the type of a function which takes one parameter of type Result, and returns Unit (i.e. nothing useful; think of it as the equivalent of void). Again, it's complicated because Kotlin doesn't know about the nullability; both the Result parameter and the parameter holding this function have !s to indicate this. (Without them, it would just be (Result) -> Unit.)
what actually param(this.otherParam) means in kotlin? [duplicate]
How is it related to extension functions? Why is with a function, not a keyword? There appears to be no explicit documentation for this topic, only the assumption of knowledge in reference to extensions.
It is true that there appears to be little existing documentation for the concept of receivers (only a small side note related to extension functions), which is surprising given: their existence springing out of extension functions; their role in building a DSL using said extension functions; the existence of a standard library function with, which given no knowledge of receivers might look like a keyword; a completely separate syntax for function types. All these topics have documentation, but nothing goes in-depth on receivers. First: What's a receiver? Any block of code in Kotlin may have a type (or even multiple types) as a receiver, making functions and properties of the receiver available in that block of code without qualifying it. Imagine a block of code like this: { toLong() } Doesn't make much sense, right? In fact, assigning this to a function type of (Int) -> Long - where Int is the (only) parameter, and the return type is Long - would rightfully result in a compilation error. You can fix this by simply qualifying the function call with the implicit single parameter it. However, for DSL building, this will cause a bunch of issues: Nested blocks of DSL will have their upper layers shadowed: html { it.body { // how to access extensions of html here? } ... } This may not cause issues for a HTML DSL, but may for other use cases. It can litter the code with it calls, especially for lambdas that use their parameter (soon to be receiver) a lot. This is where receivers come into play. By assigning this block of code to a function type that has Int as a receiver (not as a parameter!), the code suddenly compiles: val intToLong: Int.() -> Long = { toLong() } Whats going on here? A little side note This topic assumes familiarity with function types, but a little side note for receivers is needed. Function types can also have one receiver, by prefixing it with the type and a dot. Examples: Int.() -> Long // taking an integer as receiver producing a long String.(Long) -> String // taking a string as receiver and long as parameter producing a string GUI.() -> Unit // taking an GUI and producing nothing Such function types have their parameter list prefixed with the receiver type. Resolving code with receivers It is actually incredibly easy to understand how blocks of code with receivers are handled: Imagine that, similar to extension functions, the block of code is evaluated inside the class of the receiver type. this effectively becomes amended by the receiver type. For our earlier example, val intToLong: Int.() -> Long = { toLong() } , it effectively results in the block of code being evaluated in a different context, as if it was placed in a function inside Int. Here's a different example using handcrafted types that showcases this better: class Bar class Foo { fun transformToBar(): Bar = TODO() } val myBlockOfCodeWithReceiverFoo: (Foo).() -> Bar = { transformToBar() } effectively becomes (in the mind, not code wise - you cannot actually extend classes on the JVM): class Bar class Foo { fun transformToBar(): Bar = TODO() fun myBlockOfCode(): Bar { return transformToBar() } } val myBlockOfCodeWithReceiverFoo: (Foo) -> Bar = { it.myBlockOfCode() } Notice how inside of a class, we don't need to use this to access transformToBar - the same thing happens in a block with a receiver. It just so happens that the documentation on this also explains how to use an outermost receiver if the current block of code has two receivers, via a qualified this. Wait, multiple receivers? Yes. A block of code can have multiple receivers, but this currently has no expression in the type system. The only way to achieve this is via multiple higher-order functions that take a single receiver function type. Example: class Foo class Bar fun Foo.functionInFoo(): Unit = TODO() fun Bar.functionInBar(): Unit = TODO() inline fun higherOrderFunctionTakingFoo(body: (Foo).() -> Unit) = body(Foo()) inline fun higherOrderFunctionTakingBar(body: (Bar).() -> Unit) = body(Bar()) fun example() { higherOrderFunctionTakingFoo { higherOrderFunctionTakingBar { functionInFoo() functionInBar() } } } Do note that if this feature of the Kotlin language seems inappropriate for your DSL, #DslMarker is your friend! Conclusion Why does all of this matter? With this knowledge: you now understand why you can write toLong() in an extension function on a number, instead of having to reference the number somehow. Maybe your extension function shouldn't be an extension? You can build a DSL for your favorite markup language, maybe help parsing the one or other (who needs regular expressions?!). You understand why with, a standard library function and not a keyword, exists - the act of amending the scope of a block of code to save on redundant typing is so common, the language designers put it right in the standard library. (maybe) you learned a bit about function types on the offshoot.
When you call: "Hello, World!".length() the string "Hello, World!" whose length you're trying to get is called the receiver. More generally, any time you write someObject.someFunction(), with a . between the object and the function name, the object is acting as the receiver for the function. This isn't special to Kotlin, and is common to many programming languages that use objects. So the concept of a receiver is likely very familiar to you, even if you haven't heard the term before. It's called a receiver because you can think of the function call as sending a request which the object will receive. Not all functions have a receiver. For example, Kotlin's println() function is a top-level function. When you write: println("Hello, World!") you don't have to put any object (or .) before the function call. There's no receiver because the println() function doesn't live inside an object. On the receiving end Now let's look at what a function call looks like from the point of view of the receiver itself. Imagine we've written a class that displays a simple greeting message: class Greeter(val name: String) { fun displayGreeting() { println("Hello, ${this.name}!") } } To call displayGreeting(), we first create an instance of Greeter, then we can use that object as a receiver to call the function: val aliceGreeter = Greeter("Alice") val bobGreeter = Greeter("Bob") aliceGreeter.displayGreeting() // prints "Hello, Alice!" bobGreeter.displayGreeting() // prints "Hello, Bob!" How does the displayGreeting function know which name to display each time? The answer is the keyword this, which always refers to the current receiver. When we call aliceGreeter.displayGreeting(), the receiver is aliceGreeter, so this.name points to "Alice". When we call bobGreeter.displayGreeting(), the receiver is bobGreeter, so this.name points to "Bob". Implicit receivers Most of the time, there's actually no need to write this. We can replace this.name with just name and it will implicitly point to the name property of the current receiver. class Greeter(val name: String) { fun displayGreeting() { println("Hello, $name!") } } Notice how that differs from accessing a property from outside the class. To print the name from outside, we'd have to write out the full name of the receiver: println("Hello, ${aliceGreeter.name}") By writing the function inside the class, we can omit the receiver completely, making the whole thing much shorter. The call to name still has a receiver, we just didn't have to write it out. We can say that we accessed the name property using an implicit receiver. Member functions of a class often need to access many other functions and properties of their own class, so implicit receivers are very useful. They shorten the code and can make it easier to read and write. How do receivers relate to extensions? So far, it seems like a receiver is doing two things for us: Sending a function call to a specific object, because the function lives inside that object Allowing a function convenient and and concise access to the other properties and functions that live inside the same object What if we want to write a function that can use an implicit receiver for convenient access to the properties and functions of an object, but we don't want to (or can't) write our new function inside that object/class? This is where Kotlin's extension functions come in. fun Greeter.displayAnotherGreeting() { println("Hello again, $name!") } This function doesn't live inside Greeter, but it accesses Greeter as if it was a receiver. Notice the receiver type before the function name, which tells us that this is an extension function. In the body of the extension function, we can once again access name without its receiver, even though we're not actually inside the Greeter class. You could say that this isn't a "real" receiver, because we're not actually sending the function call to an object. The function lives outside the object. We're just using the syntax and appearance of a receiver because it makes for convenient and concise code. We can call this an extension receiver, to distinguish it from the dispatch receiver that exists for functions that are really inside an object. Extension functions are called in the same way as member functions, with a receiver object before the function name. val aliceGreeter = Greeter("Alice") aliceGreeter.displayAnotherGreeting() // prints "Hello again, Alice!" Because the function is always called with an object in the receiver position before the function name, it can access that object using the keyword this. Like a member function, an extension function can also leave out this and access the receiver's other properties and functions using the current receiver instance as the implicit receiver. One of the main reasons extension functions are useful is that the current extension receiver instance can be used as an implicit receiver inside the body of the function. What does with do? So far we've seen two ways to make something available as an implicit receiver: Create a function inside the receiver class Create an extension function outside the class Both approaches require creating a function. Can we have the convenience of an implicit receiver without declaring a new function at all? The answer is to call with: with(aliceGreeter) { println("Hello again, $name!") } Inside the block body of the call to with(aliceGreeter) { ... }, aliceGreeter is available as an implicit receiver and we can once again access name without its receiver. So how come with can be implemented as a function, rather than a language feature? How is it possible to simply take an object and magic it into an implicit receiver? The answer lies with lambda functions. Let's consider our displayAnotherGreeting extension function again. We declared it as a function, but we could instead write it as a lambda: val displayAnotherGreeting: Greeter.() -> Unit = { println("Hello again, $name!") } We can still call aliceGreeter.displayAnotherGreeting() the same as before, and the code inside the function is the same, complete with implicit receiver. Our extension function has become a lambda with receiver. Note the way the Greeter.() -> Unit function type is written, with the extension receiver Greeter listed before the (empty) parameter list (). Now, watch what happens when we pass this lambda function as an argument to another function: fun runLambda(greeter: Greeter, lambda: Greeter.() -> Unit) { greeter.lambda() } The first argument is the object that we want to use as the receiver. The second argument is the lambda function we want to run. All runLambda does is to call the provided lambda parameter, using the greeter parameter as the lambda's receiver. Substituting the code from our displayAnotherGreeting lambda function into the second argument, we can call runLambda like this: runLambda(aliceGreeter) { println("Hello again, $name!") } And just like that, we've turned aliceGreeter into an implicit receiver. Kotlin's with function is simply a generic version of this that works with any type. Recap When you call someObject.someFunction(), someObject is acting as the receiver that receives the function call Inside someFunction, someObject is "in scope" as the current receiver instance, and can be accessed as this When a receiver is in scope, you can leave out the word this and access its properties and functions using an implicit receiver Extension functions let you benefit from the receiver syntax and implicit receivers without actually dispatching a function call to an object Kotlin's with function uses a lambda with receiver to make receivers available anywhere, not just inside member functions and extension functions
Kotlin knows the concept of a function literals with receiver. It enables access on visible methods and properties of a receiver of a lambda within its body without having to use any additional qualifier. That's very similar to extension functions in which you can as well access members of the receiver object inside the extension. A simple example, also one of the greatest functions in the Kotlin standard library, is apply: public inline fun <T> T.apply(block: T.() -> Unit): T { block() return this } Here, block is a function literal with receiver. This block parameter is executed by the function and the receiver of apply, T, is returned to the caller. In action this looks as follows: val foo: Bar = Bar().apply { color = RED text = "Foo" } We instantiate an object of Bar and call apply on it. The instance of Bar becomes the receiver of apply. The block, passed as an argument in curly brackets does not need to use additional qualifiers to access and modify the properties color and text. The concept of lambdas with receiver is also the most important feature for writing DSLs with Kotlin.
var greet: String.() -> Unit = { println("Hello $this") } this defines a variable of type String.() -> Unit, which tells you String is the receiver () -> Unit is the function type Like F. George mentioned above, all methods of this receiver can be called in the method body. So, in our example, this is used to print the String. The function can be invoked by writing... greet("Fitzgerald") // result is "Hello Fitzgerald" the above code snippet was taken from Kotlin Function Literals with Receiver – Quick Introduction by Simon Wirtz.
Simply put ( without any extra words or complications) , the "Receiver" is the type being extended in the extension function or the class name. Using the examples given in answers above fun Foo.functionInFoo(): Unit = TODO() Type "Foo" is the "Receiver" var greet: String.() -> Unit = { println("Hello $this") } Type "String" is the "Receiver" Additional tip: Look out for the Class before the fullstop(.) in the "fun" (function) declaration fun receiver_class.function_name() { //... }
Simply put: the receiver type is the type an extension function extends the receiver object is the object an extension function is called on; the this keyword inside the function body corresponds to the receiver object An extension function example: // `Int` is the receiver type // `this` is the receiver object fun Int.squareDouble() = toLong() * this // a receiver object `8` of type `Int` is passed to the `square` function val result = 8.square() A function literal example, which is pretty much the same: // `Int` is the receiver type // `this` is the receiver object val square: Int.() -> Long = { toLong() * this } // a receiver object `8` of type `Int` is passed to the `square` function val result1 = 8.square() val result2 = square(8) // this call is equal to the previous one
The object instance before the . is the receiver. This is in essence the "Scope" you will define this lambda within. This is all you need to know, really, because the functions and properties(varibles, companions e.t.c) you will be using in the lambda will be those provided within this scope. class Music(){ var track:String="" fun printTrack():Unit{ println(track) } } //Music class is the receiver of this function, in other words, the lambda can be piled after a Music class just like its extension function Since Music is an instance, refer to it by 'this', refer to lambda parameters by 'it', like always val track_name:Music.(String)->Unit={track=it;printTrack()} /*Create an Instance of Music and immediately call its function received by the name 'track_name', and exclusively available to instances of this class*/ Music().track_name("Still Breathing") //Output Still Breathing You define this variable with and all the parameters and return types it will have but among all the constructs defined, only the object instance can call the var, just like it would an extension function and supply to it its constructs, hence "receiving" it. A receiver would hence be loosely defined as an object for which an extension function is defined using the idiomatic style of lambdas.
Typically in Java or Kotlin you have methods or functions with input parameters of type T. In Kotlin you can also have extension functions that receive a value of type T. If you have a function that accepts a String parameter for example: fun hasWhitespace(line: String): Boolean { for (ch in line) if (ch.isWhitespace()) return true return false } converting the parameter to a receiver (which you can do automatically with IntelliJ): fun String.hasWhitespace(): Boolean { for (ch in this) if (ch.isWhitespace()) return true return false } we now have an extension function that receives a String and we can access the value with this
Why do I have to wrap my Kotlin method references in closures?
In kotlin, I'm trying to create a dispatch table: class Foo { fun handleEvent(bytes:ByteArray) { // do something fun with the bytes } } class Bar { fun handleEvent(bytes:ByteArray) { // do something fun with the bytes } } foo = Foo() bar = Bar() val eventHandlers:HashMap<RemoteEvent, (bytes:ByteArray)->Unit> = hashMapOf( 0x01 to foo.handleEvent, 0x02 to bar.handleEvent) Kotlin doesn't seem to like this, it complains in multiple ways, but the relevant one seems to be be function invocation expected. I can fix this by wrapping those in closures: val eventHandlers:HashMap<RemoteEvent, (bytes:ByteArray)->Unit> = hashMapOf( 0x01 to { bytes -> foo.handleEvent(bytes) }, 0x02 to { bytes -> bar.handleEvent(bytes) }) Is there no other way? Why do I have to the method signatures, which are correct, in closures which are the same? Are closures and methods not on the same footing in Kotlin?
In Kotlin, function references are created with the :: operator (not .). Your intended use case can easily be achieved using this: val eventHandlers: HashMap<RemoteEvent, (bytes: ByteArray) -> Unit> = hashMapOf( 0x01 to foo::handleEvent, 0x02 to bar::handleEvent) // ^ Function references, Kotlin docs foo.handleEvent is interpreted as accessing the property called handleEvent (which doesn't exist.) foo::handleEvent is a KFunction instance representing the function called handleEvent, and since this matches the lambda signature (ByteArray) -> Unit it works as expected. Notice that this is different from e.g. C# or C++, where due to language restrictions, methods and properties/fields cannot share the same name. In these languages . is fine for method groups/function pointers because it is impossible that foo.bar would be ambiguous.
Without closures expression is evaluated (invoked) in line. Closures generate an anonymous object with defined method (within closures) that can be invoked when needed. Only exception is when function consuming the lambda is declared as inline in which case entire function block is injected into calling place, including the lambda (to prevent generating object).
Difference between function receiver and extension function
I was reading about Kotlin and did not quite get the idea from What I understood extension function gives ability to a class with new functionality without having to inherit from the class and what is receiver the same except it can be assigned to variable Is there anything else about it? Can someone give some examples on it
Extension functions: Like Swift and C#, Kotlin provides the ability to extend a class with new functionality without having to modify the class or inherit from the class. You might wonder why? Because we cannot edit and add functions to the language or SDK classes. So we end up creating Util classes in Java. I believe all the projects have a bunch of *Utils classes to put the helper methods that are used at multiple places in the code base. Extensions functions help to fix this Util problem. How do we write a helper method in Java to find whether the given long value refers to today? public class DateUtils { public static boolean isToday(long when) { // logic ... } } And we call that method by passing the long value as an argument: void someFunc(long when) { boolean isToday = DateUtils.isToday(when); } In Kotlin, we can extend the Long class to include the isToday() function in it. And we can call the isToday() function on the Long value itself like any other member functions in the class. // Extension function fun Long.isToday(): Boolean { // logic ... } fun someFunc(time: Long) { val isToday = time.isToday() } Compared to the Util methods, Kotlin provides a much richer syntax using the Extension functions. This improves the readability of the code which in turns improves its maintainability. And we get a little help from the code completion of the IDE. So we don't have to remember which Util class to use for the desired function. Under the hood, Kotlin compiler generates the static helper methods as though we had written them as Java static Util methods. So we get this nice and richer syntax in Kotlin without sacrificing any performance. Similar to functions, Kotlin also supports extension properties where we can add a property to an existing class. Higher order functions: A higher-order function is a function that takes functions as parameters, or returns a function. Lets look at how a higher order function is written. fun execute(x: Int, y: Int, op: (Int, Int) -> Int): Int { return op(x, y) } Here the third parameter ( op ) is a function and so it makes this function a higher order function. The type of the parameter op is a function that takes 2 Ints as parameter and returns a Int. To invoke this Higher order function, we can pass a function or a lambda expression: execute(5, 5) { a, b -> a + b } Receiver (or Function literal with Receiver or Lambda with Recevier): A Higher order function that takes an extension function as its parameter is called Lambda with Receiver. Let's look at the implementation of the apply function which is available in the Kotlin standard library. inline fun <T> T.apply(block: T.() -> Unit): T { block(); return this } The function we pass to this apply function is actually an extension function to the type T. So in the lambda function, we can access the properties and the functions of the type T as though we are writing this function inside class T itself. Here the generic type T is the receiver and we are passing a lambda function, hence the name Lambda with Receiver. Another Example: inline fun SQLiteDatabase.inTransaction(func: SQLiteDatabase.() -> Unit) { beginTransaction() try { func() setTransactionSuccessful() } finally { endTransaction() } } Here, the inTransaction() is an Extension function to the SQLiteDatabase class and the parameter of the inTransaction() function is also an extension function to the SQLiteDatabase class. Here SQLiteDatabase is the receiver, for the lambda that is passed as the argument. To invoke that function: db.inTransaction { delete( ... ) } Here the delete() is the function of the SQLiteDatabase class and since the lambda we pass is an Extension function to the receiver SQLiteDatabase we can access the delete function without any additional qualifiers with it, as though we are calling the function from inside the SQLiteDatabase class itself.
While #Bob's answer is far more informative on Kotlin than could I hope to be, including extension functions, it doesn't directly refer to the comparison between "function literals with receiver" as described in https://kotlinlang.org/docs/reference/lambdas.html#function-literals-with-receiver and extension functions (https://kotlinlang.org/docs/reference/extensions.html). I.e. the difference between: val isEven: Int.() -> Boolean = { this % 2 == 0 } and fun Int.isEven(): Boolean = this % 2 == 0 The receiver part of the name refers to both of these syntaxes receiving the base Int argument as this. As I understand it, the difference between the two is simply between one being an expression confirming to a function type and the other a declaration. Functionally they are equivalent and can both be called as: when { myNumber.isEven() -> doSomething(myNumber) } but one is intended for use in extension libraries, while the other is typically intended for use as an argument for a function with a function-type parameter, particularly the Kotlin builder DSLs.