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

Less Imperative with More Kotlin

Less Imperative with More Kotlin

Huyen's talk given at a Night Discussing Kotlin @ Foursquare HQ discussing basic definitions and terms related to Functional Programming and relating them to Kotlin.

Huyen Tue Dao

December 13, 2017
Tweet

More Decks by Huyen Tue Dao

Other Decks in Programming

Transcript

  1. 100 REM FIND THE SUM OF THE TWO NUMBERS 200

    LET X=9 300 LET Y=6 400 LET Z=X+Y 500 PRINT X,Y,Z 600 END
  2. fun average(numbers: List<Int>): Float { var total = 0f for

    (i in 0 until numbers.size) { total += numbers[i] } return total / numbers.size }
  3. CAVEAT you or someone you encounter on StackOverflow may find

    this too fluffy, simplistic, imprecise, ambiguous. that’s okay. let’s keep this chill and practical.
  4. fun average(numbers: List<Int>): Float {A var total = 0 forA(i

    in 0Auntil numbers.size) { total += numbers[i] } return total.toFloat() / numbers.size }A
  5. Take your first left. Continue straight 2 miles. Slight right

    onto Raynor St. Left onto Kerrigan Ave. Continue straight .2 miles. DECLARATIVE IMPERATIVE My address is 8 Kerrigan Ave Reference, CO 88888 Tyler McGinnis “How do I get to your house from here?”
  6. fun average(numbers: List<Int>): Float {A var total = 0 forA(i

    in 0Auntil numbers.size) { total += numbers[i] } return total.toFloat() / numbers.size }A
  7. fun average(numbers: List<Int>): Float {A var total = 0 forA(i

    in 0Auntil numbers.size) { total += numbers[i] } return total.toFloat() / numbers.size }A
  8. fun calculateAndCache(x: Int, y: Int): Int { val value =

    x + y val sharedPrefs = getPreferences(Context.MODE_PRIVATE) sharedPrefs .edit() .putInt("lastValue", value) .apply() return value }
  9. fun calculate(x: Int, y: Int): Int { val value =

    x + y + resources.getInteger(R.integer.some_important_integer) return value }
  10. but we need them. so we want to limit and

    control them. SIDE EFFECTS
  11. var count = 0 fun increment() { count++ // count

    = 1 count++ // count = 2 count++ // count = 3 count++ // count = 4 }
  12. var count = 0 fun calculate(x: Int, y: Int): Int

    {A return x + y }A val result = calculate(1, 2) // result = 3, count = 0
  13. var count = 0 fun calculate(x: Int, y: Int): Int

    { return x + y }A val result = 3 // result = 3, count = 0
  14. var count = 0 fun calculate(x: Int, y: Int): Int

    {A count++ return x + y }A val result = calculate(1, 2) // result = 3, count = 1
  15. var count = 0 fun calculate(x: Int, y: Int): Int

    {A count++ return x + y }A val result = 3 // result = 3, count = 0
  16. val films = listOf( Movie("Beauty and the Beast", 2017, 504.1f),

    Movie("Guardians of the Galaxy Vol. 2", 2017, 389.8f), Movie("Dunkirk", 2017, 188.5f), Movie("Rogue One", 2016, 532.18f), Movie("Finding Dory", 2016, 486.30f), Movie("Deadpool", 2016, 363.07f), Movie("Fantastic Beasts and Where to Find Them", 2016, 234.04f), Movie("Hidden Figures", 2016, 169.39f), Movie("Star Wars: The Force Awakens", 2015, 936.66f), Movie("Jurassic World", 2015, 652.27f), Movie("Avengers: Age of Ultron", 2015, 459.01f), Movie("Inside Out", 2015, 356.46f) )
  17. fun totalGross(films: List<Movie>): Float { var gross:Float = 0f for

    (film in films) { gross += film.gross } return gross }
  18. fun Iterable<T>.fold(initial: R, operation: (acc: R, T) -> R): R

    fun Iterable<T>.fold(initial: R, operation: (acc: R, T) -> R): R pure function
  19. let’s sprinkle on some sugar. fun totalGross(films: List<Movie>): Float {

    return films.fold(0f) { gross, film -> gross + film.gross } }
  20. fun moviesFrom2017(films: List<Movie>): List<Movie> { val results = mutableListOf<Movie>() for

    (film in films) { if (film.year == 2017) { results.add(film) } } return results }
  21. val greaterThan100M = { movie: Movie -> movie.gross > 100.0f

    } println("2016 Films = ${films.filter(greaterThan100M)}") starting to look like a strategy pattern
  22. val greaterThan100M = { movie: Movie -> movie.gross > 100.0f

    } println("2016 Films = ${films.filter(greaterThan100M)}") starting to look like a strategy pattern
  23. val names = films .filter { it.year == 2016 &&

    it.gross > 100f } .map { it.name } println("Name of 2016 Films Grossing More Than $100M = $names")
  24. interface Map<K, V> V computeIfAbsent(K key, Function<? super K,? extends

    V> mappingFunction) V computeIfPresent(K key, Function<? super K,? extends V> mappingFunction) let’s make our own and sprinkle on function types
  25. inline fun <K, V> MutableMap<K, V>.computeIf(key: K, predicate: (K, V?)

    -> Boolean, mappingFunction: (K, V?) -> V?): V? { val oldValue = get(key) if (!predicate(key, oldValue)) return oldValue val newValue = mappingFunction(key, oldValue) if (newValue == oldValue) return newValue if (newValue != null) put(key, newValue) else if (oldValue != null) remove(key) return newValue }
  26. inline fun <K, V> MutableMap<K, V>.computeIf(key: K, predicate: (K, V?)

    -> Boolean, mappingFunction: (K, V?) -> V?): V? { val oldValue = get(key) if (!predicate(key, oldValue)) return oldValue val newValue = mappingFunction(key, oldValue) if (newValue == oldValue) return newValue if (newValue != null) put(key, newValue) else if (oldValue != null) remove(key) return newValue } extension function
  27. inline fun <K, V> MutableMap<K, V>.computeIf(key: K, predicate: (K, V?)

    -> Boolean, mappingFunction: (K, V?) -> V?): V? { val oldValue = get(key) if (!predicate(key, oldValue)) return oldValue val newValue = mappingFunction(key, oldValue) if (newValue == oldValue) return newValue if (newValue != null) put(key, newValue) else if (oldValue != null) remove(key) return newValue } functions as inputs
  28. inline fun <K, V> MutableMap<K, V>.computeIf(key: K, predicate: (K, V?)

    -> Boolean, mappingFunction: (K, V?) -> V?): V? { val oldValue = get(key) if (!predicate(key, oldValue)) return oldValue val newValue = mappingFunction(key, oldValue) if (newValue == oldValue) return newValue if (newValue != null) put(key, newValue) else if (oldValue != null) remove(key) return newValue } all mutability hidden inside
  29. inline fun <K, V> MutableMap<K, V>.computeIf(key: K, predicate: (K, V?)

    -> Boolean, mappingFunction: (K, V?) -> V?): V? { val oldValue = get(key) if (!predicate(key, oldValue)) return oldValue val newValue = mappingFunction(key, oldValue) if (newValue == oldValue) return newValue if (newValue != null) put(key, newValue) else if (oldValue != null) remove(key) return newValue } blending programming paradigms
  30. REFERENCES 147 Wikipedia: Functional Programming | wikipedia.org/wiki/Functional_programming Functional Programming |

    https://wiki.haskell.org/Functional_programming What Is Functional Programming? | blog.jenkster.com/2015/12/what-is-functional-programming.html | @krisajenkins An introduction to functional programming | codewords.recurse.com/issues/one/an-introduction-to-functional-programming | @maryrosecook Imperative vs. Declarative Programming | https://tylermcginnis.com/imperative-vs-declarative-programming/ | @tylermcginnis Imperative Style | http://blog.agiledeveloper.com/2015/07/the-imperative-style.html | @venkat_s Declarative Style | http://blog.agiledeveloper.com/2015/07/the-declarative-style.html | @venkat_s Functional Style | http://blog.agiledeveloper.com/2015/08/the-functional-style.html | @venkat_s Benefits of Pure Functions: Offer Referential Transparency | blog.agiledeveloper.com/2016/01/benefits-of-pure-functions-offer.html | @venkat_s Functional Programming Favors Expressions over Statements | http://blog.agiledeveloper.com/2015/08/functional-programming- favors.html | @venkat_s What is function programming? | https://www.quora.com/What-is-functional-programming
  31. REFERENCES 148 Kotlin in Action | manning.com/books/kotlin-in-action WikiWikiWeb | wiki.c2.com/

    Why Functional Programming Matters | https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf | John Hughes, The University, Glasgow Kotlin purity and function memoization | https://medium.com/@JorgeCastilloPr/kotlin-purity-and-function-memoization- b12ab35d70a5 Kotlin Functional Programming: Does it make sense? | medium.com/@JorgeCastilloPr/kotlin-functional-programming-does-it-make- sense-36ad07e6bacf | @JorgeCastilloPr Functional, Declarative, Imperative Programming [closed] | https://stackoverflow.com/questions/602444/functional-declarative-and- imperative-programming What are monads in functional programming and why are they useful? | https://www.quora.com/What-are-monads-in-functional- programming-and-why-are-they-useful-Are-they-a-generic-solution-to-the-problem-of-state-in-FP-or-Haskell-specific-Are-they- specific-to-Haskell-or-are-they-encountered-in-other-FP-languages