Learning functional programming at Twitter’s #Hackweek #1

Raul Hernandez Lopez
5 min readJun 13, 2018

--

(This article was featured at Kotlin #98 Weekly)

This week is for us Twitter’s HackWeek!

I just came from holidays yesterday, today Hackweek has started for me, I can’t wait to see how much I can learn about functional programming!

— This is actually my first hackweek / hackathon ever, so I can’t wait to genuinely learn from this experience —

So hands on with a little intro of what I’ve done until now about functional programming so far and highlight my objective. What I really want for these three days is to learn a little bit of functional programming, a subject I have started to learn from last/this year veeery slowly.

Baby steps: I got during 2017 a couple of well known and recommended books:

  • “Functional and Reactive Domain Modeling” by Debasish Ghosh
  • “Functional Programming in Scala” by Paul Chiusano & Rúnar Bjanason

I didn’t have much time to read them, so I barely read first episodes of them. I want to remark as well the fact that both books use Scala language for examples to better explain concepts and ideas. Therefore I will try to focus on the common areas applicable to any functional ready language (as Kotlin truly is).

Also this year at Freakend Mobile 2018 I was listening several brilliant talks about Functional programming, which honestly enhanced my interest and improved my understanding of the subject:

“Algebra architecture” by @raulraja
“Category theory” by @fede_fdz & @rafaparadela

Well, now I will start with some findings during this first day of the Hackweek.

For today, I just want to make sure I really understand and remember the main concepts and good practices which enable to build a robust functional programming style.

To make this possible I want to summarise the main points about the required design theory towards Functional programming using a Reactive Domain Modeling (hence the first book).

During Chapter 1, this book talks about the what and how, and makes sense about the main following points, the ones which are the foundations when breaking into a reactive domain, and / or concurrency / distributed systems:

Avoid shared mutable state within your model

To better use concurrency, the approach must be deterministic, therefore using shared mutable state drives to complicated situations, very difficult to handle.

Referential transparency

when most of your model behaviors are built out of pure functions, you get the power of compositionality

In a sentence:

Building larger functions out of smaller ones through composition.

Organic growth

Talking about functional design, the model grows organically, since

it is pure can be treated mathematically

So this helps to reason about itself.

Focus on the core domain

When you build your model by using the principles of domain-driven design, you have entities, value objects, and services organised around patterns like repositories and factories.

Mainly this means, the fact that any of the previously mentioned artifacts can become functional. However, mutability makes sometimes our code faster, drives to non deterministic statuses, whereas the previous point mentioned, makes it difficult to reason about.

Functional makes reactive easier

Talking again about concurrency, the fact of managing data across different threads / jobs / tasks without being affected by means of a mutable shared state, makes our life easier. This properly enables reactive programming.

Design for failure

At the book he made a point about something we, as developers, always should take care about:

Never assume that things won’t fail

Design with resiliency, for instance by decoupling error / exception management from business logic modules.

Event-based modeling complements the functional model

Event-based programming delineates the “what” from the “how” of your model.

  • Events are basically the “what
  • The handler is basically the “how”.

Reading these principles again, IMO they are absolutely applicable both for backend systems development as well as any kind of client web / mobile applications.

Going back to the concepts that make a strong functional domain Chapter 2 talks about purity, what does it mean?

Purity

A function is pure if it doesn’t have any side effects.

Then what is a side effect?

Side effect

It’s something that’s not within the control if the function that you implement.

Side effect in a nutshell, for instance is: writing a new register at your DB, communicating with a server and saving those values on RAM memory and so on…

Then linking those concepts with the main points above, formally speaking, pure code has a name:

Referentially transparent

Referentially transparent

The book shows a very good example: “a banking entity transformation”. Let’s say we have a list of accounts x, to be transformed to a net interest (x performs two transformations g & f). The intermediate step is to become a list of interest, so this mathematically speaking could be g(f(x)).

This would be like:

val listOfNetInterest =
getListOfAccounts()
.map(AccountMapper::mapToInterest)
.map(InterestMapper::mapToNetInterest)

Returning a List of net interest. So this can be optimised by doing a map with composition of computeInterest and deductTax to directly pass from a List of accounts to a List of net interest.

Once we achieve to decouple all transformations from their side effects those functions can become pure, and therefore referentially transparent.

Testability

The fact of having functions free of any side effect also enables a better testing, or better said, making our unit tests deterministic and easy to read and build upon.

Algebraic data types (ADT) and immutability

I am going to start learning about ADT giving as an example Either data type.

This one has two type of parameters:

  • Left — has an error / exception
  • Right — has the expected result if any

Using Arrow with Kotlin like the documentation tells:

val valueToCheck = doSomethingWithNumber("2")
val valueGiven = when(valueToCheck) {
is Either.Left -> when (valueTocheck.givesSmth){
is NumberFormatException -> "Not a number!"
is IllegalArgumentException -> "Can't take a value!"
else -> "Unknown error"
}
is Either.Right -> "Got number value: ${valueToCheck.read}"
}
valueGiven
// for instance the output would be:
// Got number value: 10000202

Arrow documentation for Either

The use of ADTs encourages immutability, for instance since we get our Either, this should be read-only, by having our right and/or left values already defined, thus avoiding side effects on our code basis.

High order functions & Lambdas

A higher-order function is a function that takes functions as parameters, or returns a function.

Kotlin supports functions as first-class citizens

Kotlin functions are first-class, which means that they can be stored in variables and data structures, passed as arguments to and returned from other higher-order functions. You can operate with functions in any way that is possible for other non-function values.

This means lambdas are natively supported by the language.

Using functions as first-class abstractions, we can implement business logic, which at the same time is referentially transparent and thus compositional.

I already have learnt, read and refreshed some basic but hugely important concepts to start creating or using functional at a code base.

How do I plan to do it? This is my finding today:

I started learning about how to modeling by means of combining Functional and Reactive Domain, to apply this in practice, I will use a combination of the Kotlin language with Arrow library. Summarised in one single line:

val functionalOutput = f(Kotlin + Arrow) = f(Reactive + Functional)

--

--

Raul Hernandez Lopez
Raul Hernandez Lopez

Written by Raul Hernandez Lopez

Senior Staff Software Engineer. Continuous learner, sometimes runner, some time speaker & open minded. Opinions my own.

Responses (1)

Write a response