Functional Programming Fundamentals in Kotlin with Arrow
This session has ended. But you can still take this and other courses at the 47 Degrees Academy.
In this intensive course, we’ll cover Functional Programming essentials in Kotlin over four days / 16-hrs total. By the end of this course, you will have a solid grasp on the course concepts.
Please note that this course is currently being updated to support Arrow v1.0.0 and the syllabus will be changing to account for those updates.
Course Dates:
- Monday, May 24th - 14:00 - 18:00 UTC
- Tuesday, May 25th - 14:00 - 18:00 UTC
- Wednesday, May 26th - 14:00 - 18:00 UTC
- Thursday, May 27th - 14:00 - 18:00 UTC
Course content
Lesson 1: Functional Programming
Functional programming fundamentals.
- What is it, what is it good for.
- Pure functions.
- Side effects.
- Referential transparency & substitution model.
- Local reasoning.
- Is Kotlin a functional language?
- Higher order functions.
- Deferring execution.
- Exercises.
Lesson 2: Domain Modeling
Modeling our domain from a functional perspective.
- Kotlin type system. Leveraging compiler aid via types.
- Modeling concerns and making them explicit with types.
- Unit and Nothing to model meaningful scenarios.
- Inline classes for type safety and preciseness.
- Algebraic Data Types: Product and Sum types.
- Complexity of ADTs.
- Modeling choice and control flow with sum types.
- Arrow data types as ADTs.
- Eliminating bugs and tests for invariants via type safety.
- Exercises.
Lesson 3: Immutable Data and Optics
Optimizing reusability and composition for immutable data structures using Optics.
- Immutability.
- Issues with Kotlin data class
copy
. - Optics for working efficiently with nested immutable data.
- Optics composition and reusability.
- The Optics DSL.
- Stacking optics to create more powerful ones 🔭
Lens
for reading / modifying nested data.Prism
for conditional reading / modification.Optional
as the composition of Lens and Prism.Every
for working over lists of elements.FilterIndex
for working over lists of elements based on a predicate.Index
for reading or modifying elements obtained by their index.Iso
for isomorphic conversions.- Exercises.
Lesson 4: Domain Modeling II - Error Handling
Learning how to model and handle errors in functional programs.
- Railway oriented programming 🚂 - Happy path vs alternative path.
- Making errors vs success explicit with types.
- The
Either
datatype. - Exhaustive evaluation.
Either
composition and computational blocks (bindings).Either
bias towards the happy case.- Capturing third party library errors.
- Mapping third party errors to strongly typed domain errors.
- Error accumulation.
Validated
andValidatedNel
.Either
andValidated
, when to use each? Fail fast vs error accumulation.Either
andValidated
interoperability.- Flattening lists of
Either
orValidated
. Either
orValidated
for domain model validation.- Modeling potential absence of a value.
- Exercises.
Lesson 5: Functional Effects
Keeping side effects under control.
- Recap on side effects.
Suspend
for tracking effects at compile time.- The benefits of modeling effects with
suspend
. - Making effect declaration pure.
- Concern separation - pure logics vs runtime.
- Internals of
suspend
- Continuation passing style. - The impact of
suspend
in architecture. - Leveraging
Either
andValidated
in suspended contexts. - Arrow integration with KotlinX Coroutines.
- Structured concurrency & cancellation via KotlinX Coroutines.
- Providing a runtime for our suspended program.
- Functional effect operators via Arrow Fx.
- Parallel computations, races, repeating and retrying suspended effects.
- Handling errors in suspended contexts.
- Exercises.
Lesson 6: Safe Resource Handling
Functional operators to work safely with resources across boundaries.
- What is a resource?
- The issues of working with resources in concurrent contexts.
- Why
try / catch
is not enough. - Acquiring, using, and releasing a resource.
- Abstraction as a means to leverage composability.
- Ensuring resource disposal to avoid leaks.
bracket
andbracketCase
operators.guarantee
andguaranteeCase
operators.- Limitations of
bracket
andbracketCase
. Resource
data type.Resource
andbracket
to work with third party libraries.- Exercises.
Lesson 7: Functional Streams
Streams able to embed and evaluate functional effects.
- The need for streams.
- The need for
suspend
support in streams. - Streams in Kotlin via
Flow
data type. - Modeling functional effects within a
Flow
. Flow
s are cold.- Consuming functional streams safely -
suspend
terminal operators. Flow
integration with Arrow Fx operators.- Cancellation of streams with functional effects via structured concurrency.
- Sneak peek into
Flow
builders and operators. - Composing
Flow
s together. - Error path vs happy path in the context of a
Flow
. - Retrying
Flows
. - Exercises.
Lesson 8: Functional Architecture
How to organize and structure functional programs.
- Concern separation from an architecture perspective.
- Keeping architecture pure edge to edge.
- The concept of algebras.
- Isolating side effects, pushing them to the edges.
- Dependency injection in functional codebases.
- Replacing side effects with test doubles.
- The importance of pure functions and determinism for testing.
- The importance of a precise self validated domain for testing.
- Removing tests for invariants with proper types.
- Testing functional codebases.
- Sneak peek into Property Based Testing (PBT) with Kotest.
- Generating input data for our tests.
- Failure shrinking to track down failing cases.
- Detecting edge cases thanks to PBT.
- Exercises.