Friendly Functional Programming

Wiem Zine
Wiem Zine
Nov 3, 2018 · 5 min read

Programming is about solving real world problems, each program describes the different instructions, actions and events “What to do if..?” to deal with some problems.

Programming is like creating a life style following some rules which are defined by the programmer. We might be the author of the life story of someone who trusted us to make their life easier.

So we need to find a good destination, laws to follow, a new way of thinking, a right way to make our life and life of others better.

In imperative paradigm we get things done by giving a sequence of tasks and then execute them, in this blog we will learn another programming paradigm “Functional Programming”.

Functional programming

Functional programming is a beautiful declarative programming paradigm that can make us confident about our code. It separates between data and its functionality.

In FP we implement purely functional code to describe “what is this action?” in every step, it’s like we will create the story of each task in the form of functions.

Let’s get started!

The Data structures are like people or objects that have some behaviors:

case class Person(name: String, state: State)
sealed trait State
case object Happy extends State
case object Ok extends State //WARNING
case object Sad extends State
val value: String = "Hello"

in FP we call those Data Structures: Algebraic Data Structure (ADT):


Functions change the behavior of its input (ADTs)

In order to write pure functions we have to make sure that our function is:

Don’t do that!

def function(): 😇 = { 😈}

Hey function(), be honest about what you’re doing!

def function(): 😇 = { 😇}
or
def function(): 😈 = { 😈}

Each Coffee capsule has its own taste, when you put the same capsule many times you will get always the same taste without surprise.

A non-deterministic function in this case would produce this result:

Don’t do that!

def makeFriends(persons: List[Person], behaviors: Set[Behavior]): List[Person] = {
val friends: List[Person] =
persons.collect { case p if p.behavior.intersect(behaviors).size ==
behaviors.size => p }
this.kill //😱
friends
}

Do that:

def makeFriends(persons: List[Person], behaviors: Set[Behavior]): List[Person] = 
persons.collect { case p if p.behavior.intersect(behaviors).size == behaviors.size => p }

Referential transparency

If your function is deterministic and free of side effects, it is transparent. A function is pure if the expression function(x) is referentially transparent for all x. Which means we can replace the function(x) by the result of its evaluation without affecting the meaning of our program.

For example:

def addOne(x: Int) = x + 1

10 + 1 is an expression that applies the pure function addOne to the value 10 the evaluation of this function can be replaced by 11 without changing the meaning of our program.

Every time we can ensure that addOne(10) == 11

Function composition

In order to perform computations, in FP we combine two or more functions together. We create a composable programs using FP approach.

We perform different operations for a given input to produce different values.

In FP, we need to know about the whole story of our ADT behaviors. We deal with immutable Data Structures and we extract new data from existing one using compositions to make the scenario of the stories.

Example: The mathematic operations are functions, we use the result of the addition and then multiply it by 10.

    x = (14 + 23) * 10val x = mult(add(14, 23), 10)

First class functions : Higher-order-functions

In FP, you can pass functions as arguments in other functions and you can store them in Data Structures. You can define values of type function.

Sometimes we call: list(-1, 3).filter(_ > 0) => _ > 0 = a => a > 0 is actually an anonymous function “Lambda” : Int => Boolean we created a function without naming it, we can also define a function and apply it for each element of the List like this:

def verify(a: Int): Boolean = a > 0
List(-1, 3).filter(a => verify(a))

filter is a higher order function, because it takes a function as a parameter.

Lazy evaluation

In FP the computations are lazy which means the function is executed only when that value is itself needed for some further computation. The function will be called only if it’s really forced to show you a result.

Recursive functions

In FP, we use recursive functions to loop over the Data Structures or to evaluate a computations until it reaches the base cases (terminating condition). Recursive functions may throw StackoverFlowException, we can avoid that and implement tail recursion instead to perform the calculation first and at the end we call the recursive function.


Now you learned how to write purely functional code, there are many other things to learn. I’ll try to make them friendly and share them with you.

Check those project (work in progress) FP | FP-Mortals

I hope you have enjoyed reading this Blog and that you find it useful and quite funny. 👋

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store