Digital Library

Functional Kotlin (Marcin Moskała)(Z-Library)

Share E-Book

Functional Kotlin (Marcin Moskała)(Z-Library)

Author

Rating 3.5 AI initial rating

Log in to rate

Programming Language
Language English

No Description

Format PDF
Size 7.4 MB
9
Views
(First 20 pages)

Registered users can read the full content for free

Register as a Gaohf Library member to read the complete e-book online for free and enjoy a better reading experience.

Page 1
(This page has no text content)
Page 2
Functional Kotlin MarcinMoskała This book is for sale at http://leanpub.com/kotlin_functional This versionwas published on 2023-06-26 This is a Leanpub book. Leanpub empowers authors and publisherswith the Lean Publishing process. Lean Publishing is the act of publishing an in-progress ebook using lightweight tools andmany iterations to get reader feedback, pivot until you have the right book and build traction once you do. © 2022 - 2023MarcinMoskała
Page 3
Contents Introduction 1 Who is this book for? 1 Whatwill be covered? 1 TheKotlin for Developers series 2 Code conventions 3 Acknowledgments 5 Introduction to functional programmingwith Kotlin 7 Why dowe need to use functions as objects? 10 Function types 14 Defining function types 14 Using function types 15 Named parameters 18 Type aliases 19 A function type is an interface 21 Anonymous functions 23 Lambda expressions 27 Tricky braces 27 Parameters 29 Trailing lambdas 31 Result values 32 Lambda expression examples 35 An implicit name for a single parameter 37 Closures 38 Lambda expressions vs anonymous functions 38 Function references 41 Top-level functions references 41 Method references 44 Extension function references 45 Method references and generic types 47
Page 4
CONTENTS Bounded function references 48 Constructor references 51 Bounded object declaration references 52 Function overloading and references 54 Property references 56 SAM Interface support in Kotlin 57 Support for Java SAM interfaces in Kotlin 57 Functional interfaces 59 Inline functions 62 Inline functions 63 Inline functionswith functional parameters 64 Non-local return 67 Crossinline and noinline 68 Reified type parameters 70 Inline properties 73 Costs of the inlinemodifier 74 Using inline functions 75 Collection processing 76 forEach and onEach 79 filter 82 map 85 flatMap 88 fold 90 reduce 95 sum 97 withIndex and indexed variants 99 take, takeLast, drop, dropLast and subList 101 Getting elements at certain positions 107 Finding an element 109 Counting: count 111 any, all and none 111 partition 117 groupBy 119 Associating: associate, associateBy and associate- With 122 distinct and distinctBy 126 Sorting: sorted, sortedBy and sortedWith 129 Sortingmutable collections 139 Maximumandminimum 139
Page 5
CONTENTS shuffled and random 142 zip and zipWithNext 143 Windowing 147 joinToString 152 Map, Set and String processing 153 Using them all together 155 Sequences 157 What is a sequence? 158 Order is important 160 Sequences do theminimumnumber of operations 163 Sequences can be infinite 166 Sequences do not create collections at every pro- cessing step 167 When aren’t sequences faster? 171 What about Java streams? 172 Kotlin Sequence debugging 173 Summary 174 Type Safe DSL Builders 176 A function typewith a receiver 182 Simple DSL builders 184 Using apply 187 Multi-level DSLs 188 DslMarker 191 Amore complex example 195 When shouldwe use DSLs? 203 Summary 204 Scope functions 205 let 205 also 213 takeIf and takeUnless 215 apply 216 The dangers of careless receiver overloading 217 with 218 run 219 Using scope functions 220 Context receivers 222 Extension function problems 223 Introducing context receivers 226 Use cases 229
Page 6
CONTENTS Classeswith context receivers 231 Concerns 232 Summary 235 A birds-eye view of Arrow 236 Functions andArrowCore 236 Testing higher-order functions 239 ErrorHandling 240 Data Immutabilitywith ArrowOptics 247
Page 7
Introduction 1 Introduction At the beginning of the 21st century, Java mostly dominated commercial programming. Therefore, the object-oriented paradigm ruled in our discipline.Many thought that the holy war between the two biggest paradigms - object-oriented and functional programming - was resolved, but then Scala showedus that theyhadneverneeded to fightwitheachother in the first place. A programming language can have both functional and object-oriented features that complement each other. This has started a renaissance in functional programming, as many functional programming features have been introduced inmany popular languages. Nowadays, most mainstream languages support both functional and object-oriented features, but the problem is that people often still don’t knowhow to use them effectively and efficiently. Thisbook isabout functionalprogrammingfeatures inKotlin. It first covers the essentials, and then it builds on them: it presents important and practical topics like collection pro- cessing, function references, scope functions, DSL usage and creation, and context receivers. Who is this book for? This book is dedicated to developers with basic experience in usingKotlin orwhohave readmyother bookKotlin Essentials. What will be covered? This book focuses onKotlin’s functional features, including: • function types, • anonymous functions, • lambda expressions, • function references, • functional interfaces,
Page 8
Introduction 2 • collection processing functions, • sequences, • DSL usage and creation, • scope functions, • context receivers. This book is based on aworkshop I conducted. The Kotlin for Developers series This book is a part of a series of books calledKotlin forDevelop- ers, which includes the following books: • Kotlin Essentials, which covers all the basic Kotlin fea- tures. • Functional Kotlin, which is dedicated to functional Kotlin features, including function types, lambda expressions, collection processing, DSLs, and scope functions. • Kotlin Coroutines, which covers all the features of Kotlin Coroutines, including how to use and test them, using flow, best practices, and the most common mistakes. • AdvancedKotlin, which is dedicated to advancedKotlin features, including generic variance modifiers, delega- tion, multiplatform programming, annotation process- ing, KSP, and compiler plugins. • Effective Kotlin,which is dedicated to the best practices of Kotlin programming. In this book, I assume that a reader has the knowledge pre- sented in Kotlin Essentials, which I reference explicitly. How- ever, readers with experience in Kotlin, or at least in Java, should be perfectly fine starting their adventure from this book.
Page 9
Introduction 3 Code conventions Most of the presented snippets are executable, so if you copy- paste them to a Kotlin file, you should be able to execute them. The source code of all the snippets is published in the following repository: https://github.com/MarcinMoskala/functional_kotlin_- sources I often use comments to explain what will be printed by a particular line. fun main() { val cheer: () -> Unit = fun() { println("Hello") } cheer.invoke() // Hello cheer() // Hello } Sometimes, I also move all such comments to the end of a snippet. fun main() { val cheer: () -> Unit = fun() { println("Hello") } cheer.invoke() cheer() } // Hello // Hello Occasionally, some parts of code or a result are shortened with /*...*/. In such cases, you can read it as “there should bemore here, but it is not relevant to the example”.
Page 10
Introduction 4 adapter.setOnSwipeListener { /*...*/ }
Page 11
Introduction 5 Acknowledgments This book would not be so good without the reviewers’ great suggestions and comments. I would like to thank all of them. Here is the whole list of reviewers, starting from those who influenced itmost. Owen Griffiths has been developing soft- ware since the mid 1990s and remembers theproductivityof languages suchasClip- per and Borland Delphi. Since 2001, He moved to Web, Server based Java and the Open Source revolution. With many years of commercial Java experience, He picked up on Kotlin in early 2015. After taking detours into Clojure and Scala, like Goldilocks, He thinks Kotlin is just right and tastes the best. Owen enthusiastically helps Kotlin developers continue to succeed. Endre Deak is a software architect build- ing AI infrastructure at Disco, a mar- ket leading legal tech company. He has 15 years of experience building complex, scalable systems, and he thinks Kotlin is one of the best programming languages ever created. Piotr Prus is an Android developer and mobile technology enthusiast since the firstMaemo andAndroid systems. Loves clean simple designs and readable code. Shares knowledge with the community by writing articles and speaking at con- ferences. Currently, KMMing and Composing all the things. Jacek Kotorowicz is an Android developer based in Lublin, graduated from UMCS. Wrote his Master’s thesis in C++ in VimandLaTeX. Later, fell in love-hate relationshipwith JVM languages andAndroid platform. First usedKotlin (or at least tried to do so) in versions before 1.0. Still learning how NOT to be a perfectionist and how to find time for learning and hobbies.
Page 12
Introduction 6 Anna Zharkova is a Lead Mobile developer with more than 8 years of experience. Kotlin GDE. Develop both native (iOS - Swift/Objective-c, Android - Kotlin/Java) and cross platform (Xamarin, Kotlin Multiplatform) applications. Design architectural solution in mobile projects. Leading mobile team, mentorship. Public speaker on conferences and meetups (Droidcon, Android Worldwide, SwiftHero, Mobius). Tutor in Otus. Writing articles about mobile development (especially KMMand Swift) Norbert Kiesel is a backend Kotlin and Java developer and architect who started using Kotlin 5 years ago as a “better Java” and never looked back. His initiative made Kotlin a recommended language in his company, and he helped its adoption by running a Kotlin user group. JanaJarolimova is anAndroiddeveloperatAvast.Shestarted her career teaching Java classes at Prague City University, before moving on to mobile development, which inevitably led to Kotlin and her love thereof. Aasif Sheikh and SunnyAditya. I would also like to thankMichael Timberlake, our language reviewer, for his excellent corrections to thewhole book.
Page 13
Introduction to functional programmingwith Kotlin 7 Introduction to functional programming with Kotlin What is functional programming? This is not an easy ques- tion to answer. There is a popular saying that if you ask two developers about what functional programming is, you will get at least three answers. I don’t think there is a single definition that everyone will agree on. However, there are several concepts that are often associated with functional programming, including: • treating functions as objects, • higher-order functions, • data immutability, • using statements as expressions¹, • lazy evaluation, • pattern-matching, • recursive function calls. There is also a way of thinking that stands behind functional programming. In the object-oriented approach, we see the world as a set of objects; in contrast, in a functional approach, we see the world as a set of functions. Think of a bedroom: is it a roomwith abed, anightstand, a bedside lamp, etc., or is it just a placewherewe sleep? Is Kotlin a functional language? One programmer will say “yes”, whereas another might say “no”. I am certain of two things: ¹In his presentation at Kotlin Dev Days 2022, Andrey Breslav claimed that he had asked Martin Odersky (the cre- ator of Scala) about what makes a language functional, and he answered that every statement is an expression. A state- ment is a single command that a programmer expresses in a programming language, typically a single line of code. An expression is something that returns a value.
Page 14
Introduction to functional programmingwith Kotlin 8 1. Kotlin has powerful support for many features that are typical of functional programming languages. 2. Kotlin is not a purely functional language. Kotlin has powerful support formany features that are typ- ical to functional programming languages. Let’s consider our previous list of concepts that are typical of functional programming and let’s look at howKotlin supports them. Feature Support Treating functions as objects Function types, lambda expressions, function references Higher-order functions Full support Data immutability val support, default collections are read-only, copy in data classes Expressions if-else, try-catch, when statements are expressions lazy evaluation lazy delegate. Pattern-matching when togetherwith smart casting Recursive function calls tailrecmodifier Kotlinwasdesigned to support functional programming (FP), but not asmuch asHaskell or Scala. However, there aremany functional programming features that it does not support. Wemightmention currying, partial function application, etc. Kotlin’s creatorswanted to take thebest features fromFP that they believed are best for practical applications without tak- ing features thatmightmake programsharder to understand or modify. Did they do a good job? Who knows, but it seems thatmany developers like the final result. Some developers miss some FP features that are not sup- portedbyKotlin, so theyhave implementedexternal libraries like Arrow to make at least some of them available. This
Page 15
Introduction to functional programmingwith Kotlin 9 bookconcentratesonthe functional featuresbuilt intoKotlin, but the last chapter presents an overview of the essential Arrow features. It was written by Alejandro Serrano Mena, Simon Vergauwen, and Raúl Raja Martínez, who are Arrow maintainers and co-creators. Kotlin is not apurely functional language. It has support for features that are typical of anObject-Oriented (OO) approach, and it is often used as a Java successor. Kotlin tries to take the best frombothOOP and FP. If you are reading this book, I assume that you already know the basic Kotlin features. No matter if you use Kotlin in your daily work as a developer, just learned the Kotlin basis, or finishedmyprevious bookKotlinEssentials. I assume that you knowwhat a data class is, what the difference is between val and var, how different statements can be used as expressions, etc. In this book, I will focus on what I believe is the essence of functional programming: using functions as objects. So, we will learn about function types, anonymous functions, lambda expressions, function references, etc. Then, I would like to focus on the most important practical application of using functions as objects: functional-style collections pro- cessing. Then, we will look at two other applications: type- safe DSL builders and scope functions. In my opinion, these are the most important aspects of Kotlin’s support for and application of functional programming. For now, let’s focus on what I find essential: using functions as objects in Kotlin.Why dowe need this?
Page 16
Introduction to functional programmingwith Kotlin 10 Why do we need to use functions as objects? Tounderstandwhyweneed touse functions as objects, take a look at these functions: fun sum(a: Int, b: Int): Int { var sum = 0 for (i in a..b) { sum += i } return sum } fun product(a: Int, b: Int): Int { var product = 1 for (i in a..b) { product *= i } return product } fun main() { sum(5, 10) // 45 product(5, 10) // 151200 } The first one calculates the sumof all the numbers in a range; the second one calculates a product. The bodies of these two functions are nearly identical: the only difference is in the initial value and the operation. Yet, without support for treating functions as objects, extracting the common parts would not make any sense. Just think about how it would look in Java before version 8. In such a case, we had to create classes to represent operations and interfaces to specifywhat you expect… Itwould be absurd.
Page 17
Introduction to functional programmingwith Kotlin 11 // Java 7 public class RangeOperations { public static int sum(int a, int b) { return fold(a, b, 0, new Operation() { @Override public int invoke(int left, int right) { return a + b; } } public static int product(int a, int b) { return fold(a, b, 1, new Operation() { @Override public int invoke(int left, int right) { return a * b; } } private interface Operation { int invoke(int left, int right); } private static int fold( int a, int b, int initial, Operation operation int acc = initial; for (int i = a; i <= b; i++) { acc = operation.invoke(acc, i); } return acc; } }
Page 18
Introduction to functional programmingwith Kotlin 12 This is where functional programming features come to the rescue. They allow us to easily create a function and pass it as an object. To create a function, we can use a lambda expression. To express what kind of function a parameter expects, we can use a function type. This is what our code might look like if we use lambda expressions and function types: fun sum(a: Int, b: Int) = fold(a, b, 0, { acc, i -> acc + i }) fun product(a: Int, b: Int) = fold(a, b, 1, { acc, i -> acc * i }) fun fold( a: Int, b: Int, initial: Int, operation: (Int, Int) -> Int ): Int { var acc = initial for (i in a..b) { acc = operation(acc, i) } return acc } Functional programmers noticed long ago that many repeti- tive codepatterns couldbe extracted into separated functions with the help of functional programming features. fold is a great example. Itsmore universal formwas defined years ago and and nowadays it is a part of the Kotlin Standard Library (stdlib). This is why we can define our sum and product in the followingway:
Page 19
Introduction to functional programmingwith Kotlin 13 fun sum(a: Int, b: Int) = (a..b).fold(0) { acc, i -> acc + i } fun product(a: Int, b: Int) = (a..b).fold(1) { acc, i -> acc * i } However, if we use function references, they can also be defined in the followingway: fun sum(a: Int, b: Int) = (a..b).fold(0, Int::plus) fun product(a: Int, b: Int) = (a..b).fold(1, Int::times) If youareacquaintedwith thecollectionprocessing functions well, you know that calculating the sumof all the numbers in an iterable can be donewith the summethod: fun sum(a: Int, b: Int) = (a..b).sum() fun product(a: Int, b: Int) = (a..b).fold(1, Int::times) In this book,wewill learn this andmuchmore. Does it sound interesting? So, let’s get started.
Page 20
Function types 14 Function types To represent functions as objects, we need a type to represent them. A type specifies what we can do with an object², for instanceby specifyingwhatmethods³ andproperties it has.A function type is a type that specifies that an object needs to be a function.We can call this function using the invokemethod. However, functions can have different parameters and result types, so there aremany possible function types. Defining function types A function type starts with a bracket, inside which it speci- fies the parameter types, separated with commas. After the bracket, theremust be anarrow (->) and the result type. Since all functions in Kotlin need to have a result type, a function that does not return anything significant should declare Unit⁴ as its result type. Herearea fewfunction types (in thenext chapters,wewill see them in use): • () -> Unit - the simplest function type, representing a ²More about types in Kotlin Essentials, Typing system chap- ter. ³Amethod is a function associated with a class; it is called on an object, so both member and extension functions are methods. ⁴Unit is an object with a single value that can be used within generic types. A function with the return type Unit is equivalent to a Javamethod that declares void.
The above is a preview of the first 20 pages. Register to read the complete e-book.

Recommended for You

Loading recommended books...
Failed to load, please try again later

Tip the Site

Scan the WeChat Pay or Alipay code to tip. No login required.

WeChat Pay
Alipay
← Back to List