Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Functional Programming on Android: is it possible?

Functional Programming on Android: is it possible?

@ TDC São Paulo 2017

Lucas Albuquerque

July 19, 2017
Tweet

More Decks by Lucas Albuquerque

Other Decks in Programming

Transcript

  1. About • Android Developer @ M4U • Organizer @ Kotlin

    Rio Meetup Github: https://github.com/lalbuquerque Linkedin: www.linkedin.com/in/lucasalbuquerque Email: [email protected]
  2. 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
  3. "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
  4. "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
  5. fun plus2(x: Int): Int { val y = x +

    2 cache(y) return y } Impure
  6. "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
  7. 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 } }
  8. public inline fun <T, R> …Iterable<T>.map(transform: (T) -> (R)): …List<R>

    val myList = listOf(2, 4, 6, 8, 10, 12) val myNewList = myList.map { it * 2 } // [ 4, 8, 12, 16, 20, 24 ]
  9. none(…) val myList = listOf(2, 4, 6, 8, 10, 12)

    myList.none { it % 7 == 0 } // true
  10. filter(…) val myList = listOf(4, 8, 12, 16, 20, 24)

    myList.filter { it > 20 } // [ 24 ]
  11. forEach(…) val myList = listOf(2, 4, 6, 8, 10, 12)

    myList.forEach { Log.i(TAG, it.toString() }
  12. public List<ContributorCount> getContributorCounts(List<ArticleView> articleViews) { HashMap<String, Integer> contributorCounts = new

    HashMap<String, Integer>(); 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<ContributorCount> result = new ArrayList<ContributorCount>(); for (String contributor : contributorCounts.keySet()) { int count = contributorCounts.get(contributor); if (count > 1) result.add(new ContributorCount(contributor, contributorCounts.get(contributor))); } return result; }
  13. fun getContributorCounts(views: List<ArticleView>) = views.groupBy { it.contributor } .mapValues {

    it.value.size } .filter { it.value > 1 } .map { ContributorCount(it.key, it.value) }
  14. fun cosFixpoint(x: Double = 1.0): Double { while (true) {

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

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

    == cos(x)) x else f(cos(x)))