DEV Community

Theo Millard
Theo Millard

Posted on

Higher-Order Functions

Kotlin functions are first-class

  • Can be stored in variables or data structures
  • Can be passed as arguments
  • Can be returned from higher-order-functions (functions that returns a function)

Functions

Kotlin functions are declared using fun keyword.
Function parameters are defined name: type, separated using commas.

fun add(x: Int, y: Int): Int {
    return x + y
}
Enter fullscreen mode Exit fullscreen mode

Kotlin functions can have default arguments

import kotlin.random.Random

fun getRandomPercentage(start: Int = 0, end: Int = 100): Int {
    return Random.nextInt(start, end)
}

getRandomPercentage() // Random number from 0-100
getRandomPercentage(20,30) // Random number from 20-30
getRandomPercentage(end = 50) // Random number from 0-50
Enter fullscreen mode Exit fullscreen mode

Higher-Order Functions

A function that takes functions as parameters, or returns a function

Here, fold takes a combine function which takes params (acc and next num) and returns new acc.
The operations can be anything, as long returning same acc value.

fun <T, R> Collection<T>.fold(
    initial: R,
    combine: (acc: R, nextElement: T) -> R
): R {
    var accumulator: R = initial
    for (element: T in this) {
        accumulator = combine(accumulator, element)
    }
    return accumulator
}

val items = listOf(1, 2, 3, 4, 5)

items.fold(0, { 
    acc: Int, i: Int -> 
    val result = acc + i
    result
})
Enter fullscreen mode Exit fullscreen mode

Example on projects:
Here I have setupOperatorButton to receive a functions with params (2 doubles) and return String.
Here I only need to pass the calculator functions.

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        val view = binding.root
        setContentView(view)
        setupBtnListener()
    }

    private fun setupBtnListener() {
        setupOperatorButton(binding.plusBtn) { a, b -> Calculator.add(a, b) }
        setupOperatorButton(binding.minBtn) { a, b -> Calculator.subtract(a, b) }
        setupOperatorButton(binding.mulBtn) { a, b -> Calculator.multiply(a, b) }
        setupOperatorButton(binding.divBtn) { a, b -> Calculator.divide(a, b) }
    }

    private fun setupOperatorButton(button: View, operation: (Double, Double) -> String) {
        button.setOnClickListener {
            val a = binding.numberOneEt.text.toString().toDoubleOrNull()
            val b = binding.numberTwoEt.text.toString().toDoubleOrNull()
            val result = operation(a, b)
            binding.resultTv.text = result
        }
    }
}
Enter fullscreen mode Exit fullscreen mode
object Calculator {
    fun add(a: Double, b: Double): String {
        val result = a + b
        return result.toString()
    }

    fun subtract(a: Double, b: Double): String {
        val result = a - b
        return result.toString()
    }

    fun multiply(a: Double, b: Double): String {
        val result = a * b
        return result.toString()
    }

    fun divide(a: Double, b: Double): String {
        if (b == 0.0) return "NaN" // or handle division by zero separately
        val result = a / b
        return result.toString()
    }
}
Enter fullscreen mode Exit fullscreen mode

References

Top comments (0)