I noticed that I get the same effect if I define this trivial function:
fun double ( i: Int ) = i*2
and if I define a variable and assign a lambda (with an identical body) to it:
var double = { i : Int -> i*2 }
I get the same result if I call double(a)
with either declaration.
This leaves me confused. When is it needed, recommended, advantageous to define a variable as a lambda rather than define a function to it?
When is it needed, recommended, advantageous to define a variable as a lambda rather than define a function to it?
Whenever you have the choice of either, you should use a fun
declaration. Even with a fun
you can still get a first-class callable object from it by using a function reference.
On the JVM, a fun
is significantly more lightweight, both in terms of RAM and invocation overhead. It compiles into a Java method, whereas a val
compiles into an instance field + getter + a synthetic class that implements a functional interface + a singleton instance of that class that you must fetch, dereference, and invoke a method on it.
You should consider a function-typed val
or var
only when something is forcing you to do it. One example is that you can dynamically replace a var
and effectively change the definition of the function. You may also receive function objects from the outside, or you may need to comply with an API that needs them.
In any case, if you ever use a function-typed property of a class, you'll know why you're doing it.
First, if I understand you right, your question is "Why are functions first-class citizens in Kotlin -- And when to use them as such?", right?
Kotlin functions are first-class, which means that they can be stored in variables and data structures, passed as arguments to and returned from other higher-order functions. You can operate with functions in any way that is possible for other non-function values. (see here)
As stated in the docs, one use case are higher-order functions. As a first step, I will leave the wikipedia link here: https://en.wikipedia.org/wiki/Higher-order_function
Basically, a higher-order function is a function that takes functions as parameters, or returns a function. This means that a higher-order function has at least one parameter of a function type or returns a value of a function type.
Following a short example of a higher-order function that receives a parameter of function type (Int) -> Boolean
:
fun foo(pred: (Int) -> Boolean) : String = if(pred(x)) "SUCCESS" else "FAIL"
This higher-order function can now be called with any (Int) -> Boolean
function.
The docs also state ... [can be used] in any way that is possible for other non-function values.
This means that you can, for example, assign different functions to a variable, depending on your current context.
For example:
// This example is verbose on purpose ;)
var checker: (Int) -> Boolean
if (POSITIVE_CHECK) {
checker = { x -> x > 0 } // Either store this function ...
} else {
checker = { x -> x < 0 } // ... or this one ...
}
if (checker(someNumber)) { // ... and use whatever function is now stored in variable "checker" here
print("Check was fine")
}
(Code untested)
You can define variable and assign it lambda when you want change behaviour for some reason. For example, you have different formula for several cases.
val formula: (Int) -> Int = when(value) {
CONDITION1 -> { it*2 }
CONDITION2 -> { it*3 }
else -> { it }
}
val x: Int = TODO()
val result = formula(x)
If you simply need helper function, you should define it as fun
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With