Des Dulianto
Sysadmin and hobbyist coder, lifelong learning
Using functional concepts for building maintainable application
@desdulianto
(functional programming)
do this
do that
do something if this happened
do something else when that happened
repeat if not finish
obj = new Class
otherObj = new OtherClass
obj.doSomethingWith(otherObj)
f(x) = y
f1(a, b) = c
f2(d) = f1(d, f(d))
// 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)
}
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
Most of modern programming languages support functional programming
// 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));
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)
}
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
}
}
}
// 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)
}
// 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" }
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 }
// 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")
By Des Dulianto