Functional in Action

Using functional concepts for building maintainable application

@desdulianto

Agenda

  • What is
  • How to use
  • Why use

(functional programming)

Functional Programming is

  • programming paradigm
  • coding style
  • mindset

Programming Paradigms

Procedural

do this
do that
do something if this happened
do something else when that happened
repeat if not finish

Object Oriented

obj = new Class
otherObj = new OtherClass
obj.doSomethingWith(otherObj)

Functional

f(x) = y
f1(a, b) = c
f2(d) = f1(d, f(d))

Coding Style

Imperative

  • consists of statements
  • depends on order
  • defines "how"

Declarative

  • consists of expressions
  • order by group
  • defines "what"
// imperative sum list of integers
fun sum(ints: List<Int>): Int {
    var result = 0
    for (i in ints) {
        result += i
    }
    return result
}
// declarative sum list of integers
fun sum(n: Int): Int = 
    when {
        n == 0 -> 0
        else -> n + sum(n-1)
    }

Mindset

Composition

Abstraction

def function(param1, param2):
    result = function1(param1, function2(param2))
    function3(result, param2)

def function1(param):
    ...


def function2(param):
    ...

def function3(param1, param2):
    ...
function(function1(x), function2(y))
program | program1 | program2

How to use

Programming Languages

Most of modern programming languages support functional programming

Iterator

// Classic for loop
for (int i = 0; i < names.length; i++) {
    System.out.println(names[i]);
}
// Loop using iterator
for (String name: names) {
    System.out.println(name);
}
// Using stream and lambda
Arrays.asList(names).stream().forEach(name -> System.out.println(name));

Function

  • Receive argument as input
  • Return value as output
  • No side effect
fun add(a: Int, b: Int): Int {
    return a + b
}

fun subtract(a: Int, b: Int): Int {
    return a - b
}

fun times(a: Int, b: Int): Int {
    return a * b
}

fun a_times_b_substract_c (a: Int, b: Int, c: Int): Int {
    substract(times(a, b), c)
}

Recursion

fun fibonacci(n: Int): Int {
    return when {
        n <= 0 -> 0
        n == 1 -> 1
        else -> fibonacci(n-1) + fibonacci(n-2)
    }
// with memoization
val memo = mutableMapOf<Int, Int>()
fun fibonacci(n: Int): Int {
    return memo[n] ?: when {
        n <= 0 -> {
            memo[0] = 0
            0
        }
        n == 1 -> {
            memo[1] = 1
            1
        }
        else -> {
            val f = fibonacci(n-1) + fibonacci(n-2)
            memo[n] = f
            f
        }
    }
}

Tail Recursion

// res accumulate result between recursive calls
tailrec fun sum_acc(n: Int, res: Int = 0): Int {
    return when {
        n <= 0 -> res
        else -> {
            sum_acc(n-1, n+res)
        }
    }
}
// declarative sum list of integers
fun sum(n: Int): Int = 
    when {
        n == 0 -> 0
        else -> n + sum(n-1)
    }

First Class & Higher Order Function

  • Function is a value
  • Can be written as literal
    • anonymous function
    • lambda (λ)
  • Can be passed as argument
  • Can be return as value

Function is a value

// ordinary function
fun greet(name: String): String {
    return "Hello, $name"
}

// save it to a variable
val greet1 = ::greet

// function defined as evaluation of expression
fun greet2(name: String): String = "Hello, $name"

// anonymous function
val greet3 = fun(name: String): String = "Hello, $name"

// lambda
val greet4 = { name: String -> "Hello, $name" }

Function as argument

fun evenNumber(n: List<Int>): List<Int> {
    val result = mutableListOf<Int>()
    for (i in n) {
        if (i % 2 == 0) {
            result.add(i)
        }
    }
    return result
}
fun oddNumber(n: List<Int>): List<Int> {
    val result = mutableListOf<Int>()
    for (i in n) {
        if (i % 2 != 0) {
            result.add(i)
        }
    }
    return result
}
fun numberHigherThan(n: List<Int>, x: Int): List<Int> {
    val result = mutableListOf<Int>()
    for (i in n) {
        if (i > x) {
            result.add(i)
        }
    }
    return result
}
// receive predicate function with 1 parameter (Int) and returns Boolean
fun filterNumber(n: List<Int>, predicate: (Int) -> Boolean): List<Int> {
    val result = mutableListOf<Int>()
    for (i in n) {
        if (predicate(i)) {
            result.add(i)
        }
    }
    return result
}

fun evenNumber(n: Int): Boolean = n % 2 == 0

val even = filterNumber(someNumber, ::evenNumber)

val even1 = filterNumber(someNumber, { x: Int -> x % 2 == 0 })

val even2 = filterNumber(someNumber) { x: Int -> x % 2 == 0 }

val evenNumberHigherThan10 = filterNumber(someNumber) { x: Int -> x > 10 && x % 2 == 0 }

Function as return value

// closure, returns function
// that receive 1 parameter (String) and returns String
fun greet(greeting: String): (String) -> String {
    return fun(name: String): String {
        return "$greeting, $name"
    }
}

val selamat = greet("Selamat")
val hello = greet("Hello")
val apakabar = greet("Apa kabar")

selamat("Budi")
hello("Budi")
apakabar("Budi")

Why use functional programming?

  • easier to reason
  • easier to test
  • safer
  • asynchronous
  • concurrent & parallel programming

Why it's difficult

  • must unlearn before learn
  • foreign syntax
  • abstract concepts
  • dense code

Where to Learn

  • https://medium.com/@cscalfani/so-you-want-to-be-a-functional-programmer-part-1-1f15e387e536
  • https://www.youtube.com/watch?v=e-5obm1G_FY&t=1363s
  • http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html
  • https://caiorss.github.io/Functional-Programming/haskell/Functional_Programming_Concepts.html
  • Telegram group: @KongkowITMedan

Questions?

Thank you!

Functional in Action

By Des Dulianto

Functional in Action

  • 709