kotlin и ФП: то, что вы всегда хотели в java, но боялись...
TRANSCRIPT
![Page 1: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/1.jpg)
Kotlin и ФП: то, что вы всегда хотели в Java, но боялисьпопробовать (даже после Java 8)
Марат Ахин
15 февраля 2018 г.
Санкт-Петербургский политехнический университет
1
![Page 2: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/2.jpg)
Recap
То, о чем забыл рассеянный преподаватель
2
![Page 3: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/3.jpg)
Функциональное программирование
3
![Page 4: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/4.jpg)
Функциональное программирование
Что это такое?
• Функциональная программа является вычисляемым выражением,которое отвечает на интересующий нас вопрос
• Сам процесс вычисления нас особо не интересует• Вычисления являются повторяемыми
4
![Page 5: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/5.jpg)
Функциональное программирование
• Функциональная программа отвечает на вопрос “что?”• Императивная программа отвечает на вопрос “как?”
Черное и белое
5
![Page 6: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/6.jpg)
Функциональное программирование в реальности
Посередине между черным и белым
• Кто-то попытался добавить ФП в свой императивный мир• Java• C++• C#
• Кто-то попытался добавить ИП в свой функциональный мир• OCaml• Clojure
• Кто-то попытался объединить две стороны• Scala• Kotlin
• Кто-то просто странный• JavaScript
6
![Page 7: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/7.jpg)
ФП в Котлине
• Все — это функция объект• Функция, получается, тоже объект, просто не совсем обычного типа
fun <T> stringifyList(list: List<T>, f: (T) -> String): List<String> {return TODO()
}
Wat? Generics?
7
![Page 8: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/8.jpg)
Generics 101
8
![Page 9: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/9.jpg)
Generics 101
• В Котлине есть дженерики• АКА параметрический полиморфизм• Основывается на дженериках из Java
• Привет, type erasure, вот это вот все• Но кое-что работает по-другому (ждите следующей серии!)
fun <T> anyToString(value: T): String = value.toString()
class ValueWrapper<T>(val value: T) {val valueAsString = value.toString()
}
9
![Page 10: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/10.jpg)
Generics 101
10
![Page 11: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/11.jpg)
Как использовать функциональный тип
fun <T> stringifyList(list: List<T>, f: (T) -> String): List<String> {val res = mutableListOf<String>()for (e in list) {
res.add(f.invoke(e))}return res
}
Wat? Mutable lists???
11
![Page 12: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/12.jpg)
Kotlin collections 101
12
![Page 13: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/13.jpg)
Kotlin collections 101
• Коллекции (списки, множества, отображения) в Котлине разделенына неизменяемые и изменяемые на уровне системы типов
• Неизменяемые коллекции не позволяют изменять свое содержимое(ммм…)
• Изменяемые коллекции расширяют неизменяемые и добавляютвозможность модификации
• Для создания коллекций принято использовать функции изстандартной библиотеки
• listOf()/mutableListOf()• setOf()/mutableSetOf()• ...
Более подробно посмотрим в следующих сериях
13
![Page 14: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/14.jpg)
Kotlin collections 101
14
![Page 15: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/15.jpg)
Как использовать функциональный тип
fun <T> stringifyList(list: List<T>, f: (T) -> String): List<String> {val res = mutableListOf<String>()for (e in list) {
res.add(f.invoke(e))}return res
}
15
![Page 16: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/16.jpg)
Как использовать функциональный тип
fun <T> stringifyList(list: List<T>, f: (T) -> String): List<String> {val res = mutableListOf<String>()for (e in list) {
res.add(f(e))}return res
}
16
![Page 17: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/17.jpg)
Как создать функциональный тип (1)
class ErrorProcessor {fun buildErrorDescList(): List<String> {
val errorList = getErrorList()return stringifyList(errorList, ::anyToString)
}}
17
![Page 18: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/18.jpg)
Как создать функциональный тип (2)
class ErrorProcessor {fun buildErrorDesc(e: Error): String = e.toString()
fun buildErrorDescList(): List<String> {val errorList = getErrorList()return stringifyList(errorList, this::buildErrorDesc)
}}
18
![Page 19: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/19.jpg)
Как создать функциональный тип (3)
class ErrorProcessor {fun buildErrorDescList(): List<String> {
val errorList = getErrorList()return stringifyList(errorList,
fun(e: Error): String {return e.toString()
})
}}
19
![Page 20: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/20.jpg)
Как создать функциональный тип (3)
class ErrorProcessor {fun buildErrorDescList(): List<String> {
val errorList = getErrorList()return stringifyList(errorList,
fun(e): String {return e.toString()
})
}}
20
![Page 21: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/21.jpg)
Как создать функциональный тип (3)
class ErrorProcessor {fun buildErrorDescList(): List<String> {
val errorList = getErrorList()return stringifyList(errorList,
fun(e) = e.toString())}
}
21
![Page 22: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/22.jpg)
Как создать функциональный тип (4)
class ErrorProcessor {fun buildErrorDescList(): List<String> {
val errorList = getErrorList()return stringifyList(errorList,
{ e: Error -> e.toString() })}
}
22
![Page 23: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/23.jpg)
Как создать функциональный тип (4)
class ErrorProcessor {fun buildErrorDescList(): List<String> {
val errorList = getErrorList()return stringifyList(errorList,
{ e -> e.toString() })}
}
23
![Page 24: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/24.jpg)
Как создать функциональный тип (4)
class ErrorProcessor {fun buildErrorDescList(): List<String> {
val errorList = getErrorList()return stringifyList(errorList) {
e -> e.toString()}
}}
24
![Page 25: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/25.jpg)
Как создать функциональный тип (4)
class ErrorProcessor {fun buildErrorDescList(): List<String> {
val errorList = getErrorList()return stringifyList(errorList) { it.toString() }
}}
25
![Page 26: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/26.jpg)
Неужели все это придется писать самому?
26
![Page 27: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/27.jpg)
Функции высших порядков
• fold/foldRight• map/flatMap• filter• groupBy• all/any/none• …
Под капот заглянем чуть позже
27
![Page 28: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/28.jpg)
Захват переменных из окружения
class ErrorProcessor {private val freshErrorId
get() = UUID.randomUUID()
private val ignoredErrorTypes = mutableSetOf<ErrorType>()
fun buildErrorDescList(): List<String> =getErrorList()
.filter { it.type !in ignoredErrorTypes }
.map { freshErrorId to it }
.map { (id, error) -> ”[$id] ${error.msg}” }}
28
![Page 29: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/29.jpg)
Функциональные типы с неявным this
• Обозначаются как T.[function type]• Являются очередным способом сделать код более читаемым
fun <T, R> with(receiver: T, block: T.() -> R): R =receiver.block()
public class UserBuilder {public void setName(final String name) { ... }public void setAddress(final Address address) { ...}public void setEmail(final String email) { ... }public User build() { ... }
}
29
![Page 30: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/30.jpg)
Функциональные типы с неявным this
fun buildTestUser(): User =with(UserBuilder()) {
setName(”Test User”)setAddress(null)setEmail(”[email protected]”)build()
}
30
![Page 31: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/31.jpg)
Функциональные типы с неявным this
fun buildTestUser_(ub: UserBuilder): User {ub.setName(”Test User”)ub.setAddress(null)ub.setEmail(”[email protected]”)return ub.build()
}
fun buildTestUser2(): User =with(UserBuilder(), ::buildTestUser_)
31
![Page 32: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/32.jpg)
Функции-расширения
• Воплощение функциональных типов с неявным this надпроизвольными типами
• Являются еще одним очень классным способом сделать код болеечитаемым
• К этому моменту вы, должно быть, начали догадываться, чтоявляется одной из основных идей Котлина…
• Кроме того, позволяют расширять внешний код
fun UserBuilder.buildTestUser(): User =with(this, ::buildTestUser_)
32
![Page 33: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/33.jpg)
Функции-расширения
public inline fun <T> T.apply(block: T.() -> Unit): T {block()return this
}public inline fun <T> T.also(block: (T) -> Unit): T {
block(this)return this
}public inline fun <T, R> T.run(block: T.() -> R): R {
return block()}public inline fun <T, R> T.let(block: (T) -> R): R {
return block(this)}
33
![Page 34: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/34.jpg)
Intermission
34
![Page 35: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/35.jpg)
Inline functions
• В Котлине можно пометить функцию как inline
• Компилятор будет пробовать встраивать тело такой функции прямов место вызова
• Более того, он будет пробовать встраивать и переданные вinline-функцию лямбда-аргументы
• Это позволяет улучшить производительность за счет некоторыхдополнительных оптимизаций
• С другой стороны, это усложняет жизнь компилятору
• inline очень интересно дружит с дженериками, но об этом потом
35
![Page 36: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/36.jpg)
Inline functions
public inline fun <T, R> Iterable<T>.flatMap(transform: (T) -> Iterable<R>): List<R> {return flatMapTo(ArrayList<R>(), transform)
}
36
![Page 37: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/37.jpg)
Inline functions
• Лямбда-аргументы у inline-функции встраиваются по умолчанию• Если мы хотим это запретить, используем noinline на аргументе
• Например, если хотим передать эту лямбду дальше или сохранитьее где-нибудь
class FunctionStorage(val functionResults: MutableMap<() -> Any, Any>)
inline fun FunctionStorage.run(noinline body: () -> Any) =functionResults[body] ?: kotlin.run {
val res = body()functionResults[body] = resres
}37
![Page 38: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/38.jpg)
Inline functions
public inline fun <T, R> Iterable<T>.flatMap(/* noinline */ transform: (T) -> Iterable<R>): List<R> {return flatMapTo(ArrayList<R>(), transform) // wat?
}
• Из inline- в inline-функцию передача работает нормально
• Потому что мы просто встраиваем один вызов в другой
38
![Page 39: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/39.jpg)
How to return?
fun foo(angle: Double): Double {if (angle == 0.0) return Double.NaNreturn Math.sin(angle) + Math.cos(angle)
}
39
![Page 40: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/40.jpg)
How to return?
fun bar(angle: Double, f: (Double) -> Double): Double {return f(angle)
}
fun main(args: Array<String>) {bar(Math.PI) { angle ->
if (angle == 0.0) return Double.NaNreturn Math.sin(angle) + Math.cos(angle)// return is not allowed here// wat?
}}
40
![Page 41: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/41.jpg)
How to return?
fun bar(angle: Double, f: (Double) -> Double): Double {return f(angle)
}
fun main(args: Array<String>) {bar(Math.PI) { angle ->
if (angle == 0.0) return@bar Double.NaNreturn@bar Math.sin(angle) + Math.cos(angle)
}}
41
![Page 42: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/42.jpg)
How to return?
fun bar(angle: Double, f: (Double) -> Double): Double {return f(angle)
}
fun main(args: Array<String>) {bar(Math.PI, fun(angle): Double {
if (angle == 0.0) return Double.NaNreturn Math.sin(angle) + Math.cos(angle)
})}
А что для inline-функций?
42
![Page 43: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/43.jpg)
How to return?
inline fun bar(angle: Double, f: (Double) -> Double): Double {return f(angle)
}
fun main(args: Array<String>) {bar(Math.PI) { angle ->
if (angle == 0.0) return Double.NaNreturn Math.sin(angle) + Math.cos(angle)// everything is OK// wat?
}}
43
![Page 44: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/44.jpg)
How to return?
fun youShallNotPrintlnAfterEmptyStr(list: List<String>) {list.forEach { str ->
if (str.isEmpty()) return // Non-local returnprintln(str)
}}
fun youShallPrintlnAfterEmptyStr(list: List<String>) {list.forEach { str ->
if (str.isEmpty()) return@forEachprintln(str)
}}
44
![Page 45: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/45.jpg)
Crossinline
public inline fun <T> Iterable<T>.forEachAsync(action: (T) -> Unit): Unit {for (element in this)
GlobalThreadPool.submit(Callable { action(element) })// Possible non-local return
}
45
![Page 46: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/46.jpg)
Crossinline
public inline fun <T> Iterable<T>.forEachAsync(crossinline action: (T) -> Unit): Unit {for (element in this)
GlobalThreadPool.submit(Callable { action(element) })}
46
![Page 47: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/47.jpg)
Sequences
• В Java 8 появились стримы — лениво вычисляемые потоки данных• В Котлине аналогичная штука называется Sequence
• Ленивый аналог Iterable• Можно делать все то же самое, но лениво!
47
![Page 48: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/48.jpg)
Sequences
public interface Sequence<out T> {public operator fun iterator(): Iterator<T>
}
public fun <T : Any> generateSequence(nextFunction: () -> T?): Sequence<T> = ...
public fun <T : Any> generateSequence(seed: T?, nextFunction: (T) -> T?): Sequence<T> = ...
48
![Page 49: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/49.jpg)
Basic FP built-ins
49
![Page 50: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/50.jpg)
Juicy insides
public inline fun <T, R> Iterable<T>.fold(initial: R, operation: (acc: R, T) -> R): R {var accumulator = initialfor (element in this)
accumulator = operation(accumulator, element)return accumulator
}
50
![Page 51: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/51.jpg)
Juicy insides
public operator fun <T> Iterable<T>.plus(elements: Array<out T>): List<T> {if (this is Collection) return this.plus(elements)val result = ArrayList<T>()result.addAll(this)result.addAll(elements)return result
}
51
![Page 52: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/52.jpg)
Juicy insides
public operator fun <T> Collection<T>.plus(elements: Array<out T>): List<T> {val result = ArrayList<T>(this.size + elements.size)result.addAll(this)result.addAll(elements)return result
}
52
![Page 53: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/53.jpg)
Juicy insides
public inline fun <T> List<T>.getOrElse(index: Int, defaultValue: (Int) -> T): T {return if (index >= 0 && index <= lastIndex) get(index)
else defaultValue(index)}
public fun <T> List<T>.getOrNull(index: Int): T? {return if (index >= 0 && index <= lastIndex) get(index)
else null}
53
![Page 54: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/54.jpg)
What I learned today?
54
![Page 55: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/55.jpg)
What I learned today?
• В Котлине есть функции высших порядков• Более того, есть функции с неявным this• А еще есть функции-расширения
Inline-функция-расширение, являющаяся оператором?Без проблем! ,
55
![Page 56: Kotlin и ФП: то, что вы всегда хотели в Java, но боялись ......Kotlin и ФП: то, что вы всегда хотели в Java, но боялись](https://reader033.vdocuments.pub/reader033/viewer/2022050420/5f8fb7e0d7db3d44e84e4c87/html5/thumbnails/56.jpg)
What’s next?
56