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

state_of_functional_programming.pdf

 state_of_functional_programming.pdf

Leif Gensert

September 24, 2020
Tweet

More Decks by Leif Gensert

Other Decks in Programming

Transcript

  1. The State of
    Functional Programming

    View Slide

  2. • Leif Gensert
    • Web Developer
    •Trying to get better at FP

    View Slide

  3. • Code in Ruby and Elixir
    • Small amount of stdlib
    • Not all code is runnable

    View Slide

  4. What is Functional Programming?
    fraction1 = Fraction.new(1, 2) # 1/2
    fraction2 = Fraction.new(3, 4) # 3/4
    new_fraction = fraction1.add(fraction2)
    new_fraction # 5/4
    OR
    fraction1.add(fraction2)
    fraction1 # 5/4
    fraction1 = Fraction.new(1, 2) # 1/2
    fraction2 = Fraction.new(3, 4) # 3/4
    new_fraction = add(fraction1, fraction2)
    new_fraction # 5/4
    OR?

    View Slide

  5. fraction = Fraction.new(1, 2)
    fraction # 2/3
    magic_function(fraction, 2, 3)
    fraction = Fraction.new(2, 3)
    fraction.numerator = 2
    fraction.denominator = 3
    fraction.set_numerator(2)
    fraction.set_denominator(3)

    View Slide

  6. Functional Programming
    Immutable Data Structures

    View Slide

  7. fraction = Fraction.new(1, 2)
    do_something(fraction)
    fraction
    Downside of Mutable Data Structures

    View Slide

  8. Immutable
    Other Mutable

    View Slide

  9. fav_albums1 = [ ]
    fav_albums2 = List.delete_at(fav_albums1, 0)
    fav_albums2 = [ ]

    View Slide

  10. fav_albums1
    fav_albums2
    *
    Persistent Data
    Structures

    View Slide

  11. Challenge

    View Slide

  12. View Slide

  13. Artist Album
    Green Day Dookie
    Green Day American Idiot
    Britney Spears … Baby One More Time
    Britney Spears In The Zone
    Britney Spears Circus
    {
    "Green Day" => [
    "Dookie",
    "American Idiot"
    ],
    "Britney Spears" => [
    "... Baby One More Time",
    "In The Zone",
    "Circus"
    ],
    }

    View Slide

  14. {
    "Green Day" => [
    "Dookie",
    "American Idiot"
    ],
    "Britney Spears" => [
    "... Baby One More Time",
    "In The Zone",
    "Circus"
    ],
    }
    [
    ["Green Day", "Dookie"],
    ["Green Day", "American Idiot"],
    ["Britney Spears", "... Baby One More Time"],
    ["Britney Spears", "In The Zone"],
    ["Britney Spears", "Circus"],
    ]

    View Slide

  15. 1 def make_map(albums_list)
    2 albums_map = {}
    3
    4 for i in (0..albums_list.length - 1) do
    5 artist, album = albums_list[i]
    6

    7 cur_albums = albums_map[artist]
    8 if cur_albums
    9 cur_albums << album
    10 albums_map[artist] = cur_albums
    11 else
    12 albums_map[artist] = [album]
    13 end
    14 end
    15
    16 albums_map
    17 end

    View Slide

  16. View Slide

  17. 1 def make_map(albums_list, map) do
    2 if album_list == [] do
    3 map
    4 else
    5 [ head | rest] = albums_list
    6
    7 [artist, album] = head
    8
    9 cur_albums = Map.get(map, artist)
    10
    11 if cur_albums do
    12 new_albums = [ album | cur_albums ]
    13 new_map = Map.put(map, artist, new_albums)
    14 make_map(rest, new_map)
    15 else
    16 new_map = Map.put(map, artist, [album])
    17 make_map(rest, new_map)
    18 end
    19 end
    20 end

    View Slide

  18. 1 def make_map(albums_list, map) do
    2 if album_list == [] do
    3 map
    4 else
    5 [ head | rest] = albums_list
    6
    7 [artist, album] = head
    8
    9 cur_albums = Map.get(map, artist)
    10
    11 if cur_albums do
    12 new_albums = [ album | cur_albums ]
    13 new_map = Map.put(map, artist, new_albums)
    14 make_map(rest, new_map)
    15 else
    16 new_map = Map.put(map, artist, [album])
    17 make_map(rest, new_map)
    18 end
    19 end
    20 end

    View Slide

  19. map filter reduce

    View Slide

  20. filter
    &britney?
    13
    11
    13
    map
    &num_of_tracks
    37
    reduce
    &sum_each(0)

    View Slide

  21. The Big Picture

    View Slide

  22. Global State

    View Slide

  23. class Database
    @store = {}
    def self.get(key)
    @store[key]
    end
    def self.insert(key, value)
    @store[key] = value
    end
    def self.drop
    @store = {}
    end
    end
    Database.insert("Green Day", ["Dookie"])
    Database.get("Green Day") # ["Dookie"]

    View Slide

  24. Message Passing

    View Slide

  25. else if message == {"insert", key, value} do
    Map.put(store, key, value)
    send(from, "ok")
    end
    *Pseudocode
    def run(store) do
    receive from, message do
    end
    end
    reference = spawn run(%{"Green Day" => ["Dookie"]})
    send(reference, {"get", "Green Day"}) # ["Dookie"]
    if message == {"get", key} do
    send(from, Map.get(store, key))

    View Slide

  26. def run(store) do
    receive from, message do
    if message == {"get", key} do
    send(from, Map.get(store, key))
    else if message == {"insert", key, value} do
    new_store = Map.put(store, key, value)
    send(from, "ok")
    end
    end
    end
    reference = spawn run(%{})
    send(reference, {"insert", "Green Day", ["Dookie"]})
    send(reference, {"get", "Green Day", ["Dookie"]}) # ["Dookie"]
    run(new_store)
    run(store)

    View Slide

  27. Elixir.Agent

    View Slide

  28. {:ok, reference} = Agent.start_link(fn -> %{} end)
    Agent.update(
    reference,
    fn store -> Map.put(store, "Green Day", ["Dookie"]) end
    )
    Agent.get(
    reference,
    fn store -> Map.get(store, "Green Day") end
    )

    View Slide

  29. Agent.start_link(fn -> %{} end, name: :albums)
    Agent.update(
    :albums,
    fn store -> Map.put(store, "Green Day", ["Dookie"]) end
    )
    Agent.get(
    :albums,
    fn store -> Map.get(store, "Green Day") end
    )

    View Slide

  30. • Functional Programming Immutability
    • Get used to recursion
    • State can be stored in Functions

    View Slide

  31. View Slide