Kotlin functional programming

Keywords: kotlin


Features of functional programming

Declarative function

Lambda expression

Higher order function


Features of functional programming

Functional programming is essentially a collection of functions. For example, you want to filter odd numbers in a collection:

fun testFunX(): Unit {
    val list = listOf(1,2,3,4,5,6,7)
    val lx = list.filter { it %2 == 1 } // filter function, parameter is lambda expression

Functional programming is a programming paradigm about invariance;
Functional programming is a programming paradigm about function sets;

Features of functional programming:

  • A function is also a data type, which can be used as a parameter. At the same time, the return value of a function can also be a function - a function can be used as both a parameter and a return value, that is, first-class function support.
  • Pure function, which does not change the external data structure, is a function without side effects. Without modifying the data, a new data map will be created and immutable data will be used.
  • compose function:
    • Functional programming constructs the logic of a program through the combination of different functions.
    • Object oriented programming is the logic of building programs by sending messages between objects.

Declarative function

  • Declarative function
// Use the fun keyword to declare a function
fun sum1(x: Int, y: Int): Int {
    return x + y
  • Declare variables of function type
    Functions can also be used as variables to declare variables of a function type   sum2  :
val sum2 = fun (x: Int, y: Int):Int {return x + y}

fun testSum2(): Unit {
    println(sum2)   // Output: (kotlin. Int, kotlin. Int) - > kotlin. Int
    println(sum2(3,9))   // Output: 12

(kotlin.Int, kotlin.Int) -> kotlin.Int  —— The expression with "-" > "is a function type,
Represents a function that inputs two Int type values and outputs one Int type value.  


  • Declare functions in other forms
// Declare the sumX() function with an expression
fun sumX(x: Int, y: Int) = x+y

// Use the fun keyword to declare an anonymous function, and directly use an expression to implement the function
// The type of {x+y} is () - > kotlin.int function; The {x+y} expression returns a Lambda expression
val sumF = fun(x: Int, y: Int) = { x+y }

// The sumF2() function is declared with an expression, {} represents a Lambda expression
fun sumF2(x: Int, y: Int) = { x + y }


Lambda expression

fun testFunX(): Unit {
    val list = listOf(1,2,3,4,5,6,7)
    val lx = list.filter { it %2 == 1 } // filter() function, parameter is lambda expression

The parameter {it% 2 = = 1} of the filter() function is a lambda expression,
There is only one argument to the filter() function, so the parentheses are omitted.

Complete description of filter() function:

list.filter({ it %2 == 1 })
// or
list.filter({ it -> it %2 == 1 })


Declaration of filter() function:

public inline fun <T> Iterable<T>.filter(predicate: (T) -> Boolean): List<T> {
    return filterTo(ArrayList<T>(), predicate)

public inline fun <T, C : MutableCollection<in T>> Iterable<T>.filterTo(destination: C, predicate: (T) -> Boolean): C {
    for (element in this) if (predicate(element)) destination.add(element)
    return destination

The parameter to the filter() function is a function   predicate: (T) -> Boolean  .

The testFunX() function is written in full:

val isOdd = {it: Int -> it %2 ==1} // lambda expressions 

fun testFunY(): Unit {
    val list = listOf(1,2,3,4,5,6,7)
    val lx = list.filter(isOdd)	// lambda expressions as arguments
    println(lx)		// Output: [1, 3, 5, 7]
    println(isOdd)	// Output: (kotlin. Int) - > kotlin. Boolean


Higher order function

Kotlin higher order function: a function that takes another function as a parameter or returns a value.
A higher-order function is a composite of multiple functions.

Knowledge points: type aliases   typealias.

Case: input a string list, filter out the list with odd length of string elements and output it.

1. This requirement can be decomposed into two functions:

val len = fun (s: String?) = s?.length ?:0  // Calculates the length of the string
val odd = fun (i:Int) = i%2 == 1    // Judge whether the input value is odd

2. Use the function so to encapsulate the logic of "whether the length of the string is odd"

// Encapsulates whether the length of the string is odd
val so = fun (len: (String?)->Int, odd:(Int)->Boolean) : (String?)->Boolean = {odd(len(it))}

  3. The declaration of this function is relatively long, which can be simplified as follows:

// Use type aliases to simplify function types:
typealias L = (String?)->Int
typealias O = (Int)->Boolean
typealias S = (String?)->Boolean

3.1. Simplified so function

// Simplify the so function:
val sop = fun (len: L, odd: O) : S = {odd(len(it))}

// {odd(len(it))} is a lambda expression that returns a (string?) - > Boolean function type

4. Test

fun testSLO(): Unit {
	val strList = listOf("x","xy","xyz","xyz1","xyz12","xyz123","xyz1234")
    println(strList.filter(so(len,odd)))  // Output: [x, xyz, xyz12, xyz1234]
    println(strList.filter(sop(len,odd))) // Output: [x, xyz, xyz12, xyz1234]

Composite function codes such as so(len,odd) and sop(len,odd) are very close to mathematical formulas and easy to understand.

Posted by Buchead on Thu, 25 Nov 2021 17:14:39 -0800