Overview
This is an intensive workshop for experienced developers who wish to enhance their functional programming skills. The delivery assumes knowledge of the Kotlin language and builds on this foundation, enabling developers to exploit the additional capabilities provided by the Arrow library.
Delegates will design and implement sample applications, which follow the declarative and immutable FP style. They will use functional types (such as Either, Validated and State) to improve safety and maintainability. Algorithms will be implemented using the more advanced FP operators, such as traverse and bimap. Immutable collections will be preferred, with Optics used to manage deeply nested data. By the end of the delivery, delegates will be using Effects to produce polymorphic programs that can be executed across multiple environments.
The courseware is focused on the Arrow 1.0 architecture, which makes heavy use of suspending functions to simplify the API and guarantee performance. However, concepts such as Higher Kinded Types and Typeclasses are also covered. These were part of the original Arrow concept, and remain central to equivalent libraries outside Kotlin (e.g. in Scala and Rust).
The outline below presents the topics in a sequential manner for review. Please note that, during a delivery, the topics will be covered iteratively and in increasing depth. Delegates will progress from 'mostly procedural' to 'fully functional' designs as their confidence grows.
Outline
Kotlin FP Fundamentals (Optional)
- Working with function references and lambdas
- Lambdas with receiver and patterns for DSLs
- Declaring functions as parameters and return types
- Understanding Partial Invocation and Currying
- Choosing between code blocks and local functions
- Common misunderstandings regarding enclosure
Advanced FP Concepts (Examples from Arrow 0.12)
- Programming using Algebraic Data Types in Kotlin
- Adding operators to data structures via Typeclasses
- Abstracting generic types via Higher Kinded Types
- Functional composition and rules for monadic types
- Combining different monadic types via Transformers
Functional Types Supported in Arrow
- The Identity type and situations where it is useful
- Why the Option and Try types are not needed in Kotlin
- Modelling exceptions and cached/default values via Either
- Collecting errors via the Validated type and Semigroups
- Using the Reader type to build a record across invocations
- Using the State / Writer type to pass data between calls
- Arrow wrappers to Kotlin collections and NonEmptyList
Additional Operators Supported by Arrow
- Inverting collections of monadic types via traverse
- Using Applicatives to hande multiple type instances
- Composition in Arrow using suspending functions
- Kleisli as an alternative means of composition
- Applying fold, bimap and swap to Monadic Types
Manipulating Immutable Data with Optics
- Problems posed by deep nesting in immutable collections
- Advantages and limits of data classes and the copy method
- Using Optics to focus on specific fields in nested data
- Different forms of Lens in Arrow, and how to create them
- Maintaining codebases that use the Optics library heavily
Building Purely Functional Designs with Effects
- Why pure functions are desirable but side effects inevitable
- How the IO type can be used to separate pure from impure code
- Effects libraries, delimited continuations and effectual coding
- Understanding Polymorphic Programs within functional designs
- How Arrow 1.x uses suspending functions instead of an IO type
- Emerging patterns for building applications using Effects
Requirements
Delegates must be confident Kotlin developers with several years experience in industry. They must have experience applying the standard FP operators (filter, map, flatMap, reduce etc...) to solve real world problems.