46. Explain Pure Functions in kotlin Functional Programming
A pure function is a function that:
1. Has no side effects (doesn’t touch or change global state, no I/O)
Example of a Pure Function
fun add(a: Int, b: Int): Int {
return a + b
}
Example of an Impure Function
var counter = 0
fun increment(): Int {
counter += 1
return counter
}
❌ This is not a pure function.
47. Why Use Pure Functions?
Benefit | Description |
---|---|
✅ Predictable | Easy to test and debug |
✅ Reusable | Works the same in any context |
✅ Thread-safe | No shared state, safe for concurrency |
✅ Composable | Can be combined easily in functional chains (map, filter, etc.) |
48. Explain Function Composition in kotlin functional programming.
Function Composition is a functional programming concept where you combine two or more functions to create a new function. The output of one function becomes the input of the next.
In Kotlin, you can compose functions using:
If you have:
Then:
Example:
val add2: (Int) -> Int = { it + 2 }
val multiply3: (Int) -> Int = { it * 3 }
val composed1 = add2 compose multiply3 // (x * 3) + 2
val composed2 = add2 andThen multiply3 // (x + 2) * 3
println(composed1(5)) // Output: 17
println(composed2(5)) // Output: 21
Function composition is powerful for clean, reusable, and declarative code.
49. How to Define compose() and andThen() in Kotlin
infix fun <P1, R, R2> ((P1) -> R).andThen(function: (R) -> R2): (P1) -> R2 {
return { p1: P1 -> function(this(p1)) }
}
infix fun <P1, P2, R> ((P2) -> R).compose(function: (P1) -> P2): (P1) -> R {
return { p1: P1 -> this(function(p1)) }
}
50. Explain Lambdas and Inline Functions in Kotlin
Kotlin supports functional programming concepts like lambdas and inline functions, which make your code more expressive and efficient.
A lambda is an anonymous function—you can pass it as a value or store it in a variable.
val sum = { a: Int, b: Int -> a + b }
println(sum(3, 4)) // Output: 7
Or use it as a function parameter:
fun operateOnNumbers(a: Int, b: Int, operation: (Int, Int) -> Int): Int {
return operation(a, b)
}
val result = operateOnNumbers(5, 3) { x, y -> x * y }
println(result) // Output: 15
In Kotlin, you can mark a function with the inline keyword to avoid the overhead of function calls, especially when passing lambdas.
Without inline, lambdas are compiled into objects (allocated on the heap). With inline, the compiler copies the function body into the call site, improving performance.
Example:
inline fun logAndRun(action: () -> Unit) {
println("Before action")
action()
println("After action")
}
fun main() {
logAndRun {
println("Running something...")
}
}
Output:
Before action
Running something...
After action
Because of inline, the action() lambda is inlined (copied directly into main()), avoiding extra object creation.
Use noinline when you don’t want a lambda to be inlined (e.g., if you want to pass it as a value or store it in a variable).
inline fun process(noinline block: () -> Unit) {
val stored = block // This requires `noinline`
}
Use crossinline to prevent return inside lambdas (because inlining allows non-local returns, which can be dangerous).
inline fun runSafe(crossinline block: () -> Unit) {
val runnable = Runnable {
block() // Can't use `return` here
}
runnable.run()
}
*
Feature | Purpose | Example |
---|---|---|
Lambda | Anonymous function | { x, y -> x + y } |
inline | Avoid lambda allocation, better perf | inline fun run(block: () -> Unit) |
noinline | Disable inlining for specific lambda | noinline block: () -> Unit |
crossinline | Prevent non-local returns in lambda | crossinline block: () -> Unit |