Functional Programming in Kotlin — серия статей о функциональном программировании на Kotlin.
В функциональном программировании функции языка программирования рассматриваются с точки зрения математических функций, которые представляют собой зависимость одной переменной величины от другой. Такие функции называются чистыми (pure function). Они имеют ряд ограничений в сравнении с функциями, к которым привыкли программисты на традиционных языках:
- чистая функция всегда возвращает значение;
- она не выбрасывает исключений;
- не изменяет данных за пределами своей области видимости;
- не изменяет свои аргументы;
- всегда возвращает одинаковое значение для одних и тех же аргументов.
Пример чистой функции на языке Kotlin:
1 |
fun division(x: double, y: Double): Double = x / y |
Пример нечистой функции:
1 2 3 4 |
fun addItems(value: Int, list: MutableList<Int>): List<Int> { list.add(value) return list } |
Функция из второго примера изменяет один из своих аргументов ( list) и поэтому не может считаться чистой.
РЕКОМЕНДУЕМ:
Полезные советы разработчику на Kotlin
Сторонники функционального программирования утверждают, что приложения, написанные с использованием исключительно или преимущественно чистых функций, всегда более надежны, так как приложение состоит из набора понятных и простых строительных блоков, каждый из которых легко протестировать.
Для объединения функций применяется композиция, когда несколько функций используются для создания новой. Интуитивно ты можешь попробовать сделать это следующим образом:
1 2 3 |
fun f(x: Int) = x + 1 fun g(x: Int) = 2 * x println(f(g(2)) |
Но это неверно. Настоящая композиция должна выполняться как операция над функциями:
1 2 3 4 5 6 |
fun f(x: Int) = x + 1 fun g(x: Int) = 2 * x fun compose(f: (Int) -> Int, g: (Int) -> Int): (Int) -> Int = { x -> f(g(x)) } val fog = compose(::f, ::g) println(fog(2)) |
Предыдущий пример композиции подходит только для типов Int, но его можно расширить для поддержки любых типов данных:
1 2 3 4 5 6 7 |
fun r1(x: Boolean): Int = if(x) 1 else 0 fun r2(x: Int): Boolean = if(x == 0) false else true fun <T, U, V>compose(f: (U) -> V, g: (T) -> U): (T) -> V = { f(g(it)) } val r1of2 = compose<Int, Boolean, Int>(::r1, ::r2) println(r1of2(2)) |
РЕКОМЕНДУЕМ:
Хорошие и плохие приемы программирования на Kotlin