Slide 1

Slide 1 text

Functional Programming on Android: is it possible?

Slide 2

Slide 2 text

About • Android Developer @ M4U • Organizer @ Kotlin Rio Meetup Github: https://github.com/lalbuquerque Linkedin: www.linkedin.com/in/lucasalbuquerque Email: [email protected]

Slide 3

Slide 3 text

TALK “FUNCTIONAL PROGRAMMING ON ANDROID: IS IT POSSIBLE?” someData.map(it + 2) .filter(it > 10) .sort(…) .reduce(…) .group(…) .flatMap(…) .just(…) .jointTo(…) .fold(…) .slice(…) .takeLastWhile(…) EXPECTATION data class MyObject(val name: String) REALITY

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

https://msdn.microsoft.com/en-us/library/hh242985(v=vs.103).aspx

Slide 7

Slide 7 text

"Functional code is characterised by one thing: the absence of side effects. It doesn’t rely on data outside the current function, and it doesn’t change data that exists outside the current function. Every other “functional” thing can be derived from this property. Use it as a guide rope as you learn.” - - Mary Rose Cook - https://maryrosecook.com/blog/post/a-practical-introduction-to-functional- programming

Slide 8

Slide 8 text

SO I CAN GO FUNCTIONAL WITH JAVA?

Slide 9

Slide 9 text

Lisp | John McCarthy and Steve Russell | 1958

Slide 10

Slide 10 text

Immutability

Slide 11

Slide 11 text

Read-Modify-Write

Slide 12

Slide 12 text

class Car(var noOfDrivers: Int)

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

class Car(val noOfDrivers: Int)

Slide 15

Slide 15 text

No content

Slide 16

Slide 16 text

Using functions right

Slide 17

Slide 17 text

No content

Slide 18

Slide 18 text

"A pure function is a function that, given the same input, will always return the same output and does not have any observable side effect." - Professor Franklin Risby's - Mostly Adequate Guide to Functional Programming

Slide 19

Slide 19 text

fun add(x: Int): Int { val y: Int = readNumFromFile() return x + y } Impure

Slide 20

Slide 20 text

fun add(x: Int, y: Int) = x + y Pure

Slide 21

Slide 21 text

fun plus2(x: Int): Int { val y = x + 2 cache(y) return y } Impure

Slide 22

Slide 22 text

fun plus2(x: Int) = x + 2 Pure

Slide 23

Slide 23 text

"The name of a variable, function or class should answer the big questions such as why it exists, what it does, how it is used." Aiden Mc Raft commenting Robert C. Martin’s Clean Code: A Handbook of Agile Software Craftsmanship

Slide 24

Slide 24 text

Demystifying functions

Slide 25

Slide 25 text

fun add(x: Int, y: Int) = x + y

Slide 26

Slide 26 text

val add = fun add(x: Int, y: Int) = x + y

Slide 27

Slide 27 text

fun doSomething(function: (Int, Int) -> Int) { … }

Slide 28

Slide 28 text

data class User(val name: String, val amount: Int, val onClick: (User) -> Unit)

Slide 29

Slide 29 text

with(user) { holder.itemView.setOnClickListener { onClick(this) } }

Slide 30

Slide 30 text

enum class Operation { ADD, SUB }

Slide 31

Slide 31 text

fun applyOperation(operation: Operation): (Int, Int) -> Int { val add = fun (x: Int, y: Int) = x + y val sub = fun (x: Int, y: Int) = x - y when (operation) { Operation.ADD -> return add Operation.SUB -> return sub } }

Slide 32

Slide 32 text

applyOperation(Operation.ADD) (1, 3)

Slide 33

Slide 33 text

Functional Operators

Slide 34

Slide 34 text

public inline fun …Iterable.map(transform: (T) -> (R)): …List val myList = listOf(2, 4, 6, 8, 10, 12) val myNewList = myList.map { it * 2 } // [ 4, 8, 12, 16, 20, 24 ]

Slide 35

Slide 35 text

none(…) val myList = listOf(2, 4, 6, 8, 10, 12) myList.none { it % 7 == 0 } // true

Slide 36

Slide 36 text

filter(…) val myList = listOf(4, 8, 12, 16, 20, 24) myList.filter { it > 20 } // [ 24 ]

Slide 37

Slide 37 text

forEach(…) val myList = listOf(2, 4, 6, 8, 10, 12) myList.forEach { Log.i(TAG, it.toString() }

Slide 38

Slide 38 text

fun returnBiggerNames(names: MutableList): MutableList { names .filter { it.length < 10 } .forEach { names.remove(it) } return names } Impure

Slide 39

Slide 39 text

fun returnBiggerNames(names: List) = names.filter { it.length > 10 } Pure

Slide 40

Slide 40 text

public List getContributorCounts(List articleViews) { HashMap contributorCounts = new HashMap(); for (ArticleView articleView : articleViews) { Integer count = contributorCounts.get(articleView.contributor); if (count == null) contributorCounts.put(articleView.contributor, 1); else contributorCounts.put(articleView.contributor, count + 1); } List result = new ArrayList(); for (String contributor : contributorCounts.keySet()) { int count = contributorCounts.get(contributor); if (count > 1) result.add(new ContributorCount(contributor, contributorCounts.get(contributor))); } return result; }

Slide 41

Slide 41 text

fun getContributorCounts(views: List) = views.groupBy { it.contributor } .mapValues { it.value.size } .filter { it.value > 1 } .map { ContributorCount(it.key, it.value) }

Slide 42

Slide 42 text

Recursion

Slide 43

Slide 43 text

fun cosFixpoint(x: Double = 1.0): Double { while (true) { val y = Math.cos(x) if (x == y) return y x = y } }

Slide 44

Slide 44 text

tailrec fun cosFixpoint(x: Double = 1.0): Double { val y = Math.cos(x) return if (x == y) x else cosFixpoint(y) }

Slide 45

Slide 45 text

tailrec fun f(x: Double = 1.0): Double = if (x == cos(x)) x else f(cos(x)))

Slide 46

Slide 46 text

Thank you!

Slide 47

Slide 47 text

Bibliography 1. https://drboolean.gitbooks.io/mostly-adequate-guide 2. https://www.theguardian.com/info/developer-blog/2014/dec/ 11/functional-android 3. https://medium.com/@anupcowkur/functional-programming- for-android-developers-part-3-f9e521e96788 4. https://blog.plan99.net/kotlin-fp-3bf63a17d64a