rigor mortis
play

Rigor Mortis (avoiding) 1 Dave is an Old Fart - PDF document

Dave Thomas @/+pragdave Rigor Mortis (avoiding) 1 Dave is an Old Fart http://24.media.tumblr.com/tumblr_lr7ypweBfM1qa9b8ro1_500.png Old Farts Get Stuck in Their Ways


  1. Dave Thomas 
 @/+pragdave Rigor Mortis (avoiding) 1

  2. Dave is an Old Fart http://24.media.tumblr.com/tumblr_lr7ypweBfM1qa9b8ro1_500.png

  3. Old Farts Get Stuck in Their Ways http://www.runningheads.net/wp-content/uploads/2013/05/Curmudgeon_Logo.jpg

  4. So Do Young Ones 4 http://www.clipartbest.com/clipart-MTLL5pbac

  5. ����������� We Get 5 http://www.clker.com/cliparts/W/n/3/A/j/2/comfortable-man.svg

  6. ���� We Get 6 http://www.clker.com/cliparts/W/n/3/A/j/2/comfortable-man.svg

  7. ���� Maintenance Programmer 7 http://www.clker.com/cliparts/W/n/3/A/j/2/comfortable-man.svg

  8. ���� I Got 8 http://www.clker.com/cliparts/W/n/3/A/j/2/comfortable-man.svg

  9. The future is functional The future is concurrent 9

  10. Is teaching me a new vocabulary Is changing the way I think 10

  11. T oken Appeal to Authority 11

  12. Ludwig Wittgenstein 12

  13. Ludwig Wittgenstein Logico-Tractatus Philosophicus How far my efforts agree with those of other philosophers I will not decide. Indeed what I have here written makes no claim to novelty in points of detail; and therefore I give no sources, because it is indifferent to me whether what I have thought has already 
 been thought before me by another. 13

  14. Ludwig Wittgenstein 
 Logico-Tractatus Philosophicus How far my efforts agree with those of other philosophers I will not decide. Indeed what I have here written makes no claim to novelty in points of detail; and therefore I give no sources, because it is indifferent to me whether what I have thought has already 
 been thought before me by another. 14

  15. The limits of my 
 language are the 
 limits of my world Ludwig Wittgenstein— Logico-Tractatus Philosophicus 15

  16. 16

  17. How Has Learning Elixir Changed the Way I Think? 17

  18. Functional |> Concurrent |> Pragmatic |> Fun

  19. Functional |> Concurrent |> Pragmatic |> Fun Different

  20. Background • Pattern matching • Functions transform data 20

  21. Pattern Match a = 1 { c, d } = { 2, 3 } [ e, f, g ] = [ 4, 5, 6 ] "Elixir " <> rest = "Elixir Rocks!" # rest => "Rocks!" [ head | tail ] = [ 1, 2, 3, 4, 5, 6 ] # head => 1 # tail => [ 2,3,4,5,6 ] 21

  22. Pattern Match case File.open("myfile") do { :ok, device } -> IO.read(device, :line) { :error, reason } -> IO.puts "FAILED #{reason}" end 22

  23. Pattern Match my_fun = fn :plus, a, b -> a + b :times, a, b -> a * b end IO.puts my_fun.(:plus, 3, 4) # => 7 IO.puts my_fun.(:times, 3, 4) # => 12 def other_fun(:minus, a, b), do : a - b def other_fun(:divide, a, b), do : a/b 23

  24. Pattern Matching • Match based on shape and content • Destructure data • Recursive 24

  25. For example… • fib(0) → 0 • fib(1) → 1 • fib(n) → fib(n-1) + fib(n-2) 25

  26. Fibonacci defmodule Fib do def fib(0), do : 0 def fib(1), do : 1 def fib(n), do : fib(n-1) + fib(n-2) end IO.puts Fib.fib(10) 26

  27. defmodule Fib do def fib(0), do: 0 def fib(1), do : 1 def fib(n), do : fib(n-1) + fib(n-2) end • fib(0) → 0 • fib(1) → 1 • fib(n) → fib(n-1) + fib(n-2) 27

  28. Programs Reflect Specification 28

  29. Programs Reflect Specification Implementation Reflects Transformation 29

  30. Length of List • Length of empty list is zero • Length of list with head “h” and 
 tail “t” is 1 + length(t) 30

  31. • Length of empty list is zero • Length of list with head “h” and 
 tail “t” is 1 + length(t) defmodule MyList do def len([]), do : 0 def len([ _head | tail ]), do : 1 + len(tail) end IO.puts MyList.len [ 5, 4, 3 ] 31

  32. Map • Map of an empty list is an empty list • Map of list with head “h” and tail “t” 
 is a list whose head is func(h) and whose tail is map(t) 32

  33. • Map of an empty list is an empty list • Map of list with head “h” and tail “t” 
 is a list whose head is func(h) and whose tail is map(t) defmodule MyList do def map([], _func), do : [] def map([ h | t ], func), do : [ func.(h) | map(t, func) ] end MyList.map [ 1,2,3,4,5], & (&1*&1) 33

  34. 
 More Practical • Run-length encode a list of values: 
 Runs of two or more of the same value “v” are replaced with { v, count } [ 1, 2, 2, 2, 3, 4, 4, 5, 6, 6, 6, 6 ] → [ 1, {2, 3}, 3, {4, 2}, 5, {6, 4} ] 34

  35. [ 1, 2, 2, 2, 3, 4, 4, 5, 6, 6, 6, 6 ] → [ ] 35

  36. [ 2, 2, 2, 3, 4, 4, 5, 6, 6, 6, 6 ] → [ 1 ] 36

  37. [ {2,2}, 2, 3, 4, 4, 5, 6, 6, 6, 6 ] → [ 1 ] 37

  38. [ {2,3}, 3, 4, 4, 5, 6, 6, 6, 6 ] → [ 1 ] 38

  39. [ 3, 4, 4, 5, 6, 6, 6, 6 ] → [ {2, 3}, 1 ] 39

  40. [ 4, 4, 5, 6, 6, 6, 6 ] → [ 3, {2, 3}, 1 ] 40

  41. [ {4,2}, 5, 6, 6, 6, 6 ] → [ 3, {2, 3}, 1 ] 41

  42. [ 5, 6, 6, 6, 6 ] → [ {4,2} , 3, {2,3}, 1 ] 42

  43. RLE defmodule Rle do def encode(list), do: _encode(list, []) end RLE.encode [ 1, 2, 2, 2, 3, 4, 4, 5, 6, 6, 6, 6 ] 43

  44. RLE defmodule Rle do def encode(list), do: _encode(list, []) def _encode( [ a | tail ], result) do _encode(tail, [ a | result ]) end end RLE.encode [ 1, 2, 2, 2, 3, 4, 4, 5, 6, 6, 6, 6 ] 44

  45. RLE defmodule Rle do def encode(list), do: _encode(list, []) def _encode( [ {a, n}, a | tail ], result) do _encode( [ {a, n+1} | tail ], result ) end def _encode( [ a | tail ], result) do _encode(tail, [ a | result ]) end end RLE.encode [ 1, 2, 2, 2, 3, 4, 4, 5, 6, 6, 6, 6 ] 45

  46. RLE defmodule Rle do def encode(list), do: _encode(list, []) def _encode([ a, a | tail ], result) do _encode( [ {a, 2} | tail ], result ) end def _encode( [ {a, n}, a | tail ], result) do _encode( [ {a, n+1} | tail ], result ) end def _encode( [ a | tail ], result) do _encode(tail, [ a | result ]) end end RLE.encode [ 1, 2, 2, 2, 3, 4, 4, 5, 6, 6, 6, 6 ] 46

  47. RLE defmodule Rle do def encode(list), do: _encode(list, []) def _encode([], result), do: Enum.reverse(result) def _encode([ a, a | tail ], result) do _encode( [ {a, 2} | tail ], result ) end def _encode( [ {a, n}, a | tail ], result) do _encode( [ {a, n+1} | tail ], result ) end def _encode( [ a | tail ], result) do _encode(tail, [ a | result ]) end end RLE.encode [ 1, 2, 2, 2, 3, 4, 4, 5, 6, 6, 6, 6 ] 47

  48. RLE defmodule Rle do def encode(list), do: _encode(list, []) def _encode([], result), do: Enum.reverse(result) def _encode([ a, a | tail ], result) do _encode( [ {a, 2} | tail ], result ) end def _encode( [ {a, n}, a | tail ], result) do _encode( [ {a, n+1} | tail ], result ) end def _encode( [ a | tail ], result) do _encode(tail, [ a | result ]) end end RLE.encode [ 1, 2, 2, 2, 3, 4, 4, 5, 6, 6, 6, 6 ] 48

  49. RLE Input New input Result [] «done» → [ values ] [a,a,…] [ {a,2}, … ] → [ values ] [ {a,n+1}, … ] → [ values ] [{a,n}, a, … ] → [ b, values ] [b, …] [ … ] 49

  50. RLE State New State Result [] «done» → [ values ] [a,a,…] [ {a,2}, … ] → [ values ] [ {a,n+1}, … ] → [ values ] [{a,n}, a, … ] → [ b, values ] [b, …] [ … ] 50

  51. RLE defmodule Rle do def encode(list) do list |> Enum.reduce([], &_encode/2) |> Enum.reverse end def _encode(next, result) do case {next, result} do {a, [ a | rest ] } -> [ {a,2} | rest ] {a, [ {a,n} | rest ] } -> [ {a, n+1} | rest ] {a, rest } -> [ a | rest ] end end end 51

  52. Not New • Decision tables (1960s) • State Machines (1960s) • Blackboard systems (1980s) 52

  53. 1960s 53

  54. RLE Transformation defmodule Rle do def encode(list) do list |> Enum.reduce([], &_encode/2) |> Enum.reverse end def _encode(next, result) do case {next, result} do {a, [ a | rest ] } -> [ {a,2} | rest ] {a, [ {a,n} | rest ] } -> [ {a, n+1} | rest ] {a, rest } -> [ a | rest ] end end end 54

  55. RLE defmodule Rle do def encode(list) do list |> Enum.reduce([], &_encode/2) Event + State |> Enum.reverse end def _encode(next, result) do case {next, result} do {a, [ a | rest ] } -> [ {a,2} | rest ] {a, [ {a,n} | rest ] } -> [ {a, n+1} | rest ] {a, rest } -> [ a | rest ] end end end 55

  56. RLE defmodule Rle do def encode(list) do Transitions list |> Enum.reduce([], &_encode/2) |> Enum.reverse Event + State end def _encode(next, result) do case {next, result} do {a, [ a | rest ] } -> [ {a,2} | rest ] {a, [ {a,n} | rest ] } -> [ {a, n+1} | rest ] {a, rest } -> [ a | rest ] end end end 56

  57. Markdown System Types ============ These types reflect resources in the underlying Erlang VM. IDs and Ports ------------- A PID is a reference to a local or remote process, and a port is a reference to a resource (typically external to the application) that you'll be reading or writing. 57

  58. Markdown defp parse([ %Line.Blank{}, %Line.Text{content: heading}, %Line.SetextUnderlineHeading{level: level} | rest ], result) do parse(rest, [ %Heading{content: heading, level: level} | result ]) end 58

Recommend


More recommend