Functional Programming Made Me a Better Perl Developer

7330b65ea54e1b90a987a552e5c5cf32?s=47 Mark Allen
October 13, 2016

Functional Programming Made Me a Better Perl Developer

In this talk, I discuss how learning functional programming list processing idioms made me a more confident and fluent Perl programmer.

7330b65ea54e1b90a987a552e5c5cf32?s=128

Mark Allen

October 13, 2016
Tweet

Transcript

  1. Functional Programming Made Me a Better Perl Developer Mark Allen

    | mrallen1@yahoo.com | @bytemeorg
  2. Agenda šFunctional Programming: What is it? šAll you need is

    fold šProgramming Perl in a Functional Style @bytemeorg
  3. What is Functional Programming? A programming paradigm which aims to

    express computation using functions that avoid (as much as possible) side-effects. @bytemeorg
  4. Why is that a good thing? Make all state change

    explicit All functions behave deterministically (given a function and its inputs, it always returns the same output) @bytemeorg
  5. How are these things manifested? Immutable variable bindings (in a

    scope) 3 crucial higher order functions: filter, map, fold (reduce) Recursively operate on lists @bytemeorg
  6. fold right let rec foldr f a lst = match

    lst with | [] -> a | hd::tl -> f hd (foldr f a tl);; @bytemeorg
  7. fold right example foldr (+) 0 [1;2;3;];; (* output: -

    : int = 6 *) (* same as: f 1 (f 2 (f 3 0)) *) (* same as: 1 + ( 2 + (3 + 0) ) = 6 *) @bytemeorg
  8. another fold right example foldr (-) 0 [1;2;3;];; (* what

    is this value? *) @bytemeorg
  9. another fold right example foldr (-) 0 [1;2;3;];; (* output:

    - int = 2 *) (* why? 1-(2-(3-0)) = 1 - -1 = 2 *) @bytemeorg
  10. fold left let rec foldl f a lst = match

    lst with | [] -> a | hd::tl -> foldl f (f a hd) tl;; @bytemeorg
  11. fold left example foldl (+) 0 [1;2;3;];; (* output: -

    int = 6 *) (* same as: ((1+0)+2)+3 *) @bytemeorg
  12. another fold left example foldl (-) 0 [1;2;3;];; (* what

    is this value? *) @bytemeorg
  13. another fold left example foldl (-) 0 [1;2;3;];; (* output:

    - int = -6 *) (* same as: ((0-1)-2)-3 *) @bytemeorg
  14. map let map f = foldr (fun x lst-> (f

    x)::lst) [];; @bytemeorg
  15. map example map (fun x-> x*2) [ 1; 2; 3;

    ];; (* output: - : int list = [2; 4; 6] *) @bytemeorg
  16. map example (Erlang list comprehension) [ X * X ||

    X <- lists:seq(1,5) ]. % [1,4,9,16,25] @bytemeorg
  17. filter let filter p = foldr (fun x a ->

    if p x then x::a else a) [];; @bytemeorg
  18. filter example filter (fun x -> (x mod 2) ==

    0) [1;2;3;4;];; (* output: - : int list = [2;4] *) @bytemeorg
  19. filtermap example [ X * X || X <- lists:seq(1,5),

    X rem 2 == 0 ]. % [4,16] @bytemeorg
  20. Higher Order Perl http://hop.perl.plover.com/book/ @bytemeorg

  21. List processing primitives in Perl grep map reduce (List::Util added

    to core in 5.7.3) @bytemeorg
  22. grep example (filter) # filter (fun x -> (x mod

    2) == 0) [1;2;3;4;];; # perl –E 'say join ", ", ...' grep {; $_ % 2 == 0 } 1..10; # 2, 4, 6, 8, 10 @bytemeorg
  23. map example # map (fun x-> x*2) [ 1; 2;

    3; ];; # perl –E 'say join ", ", ...' map {; $_ * 2 } 1..3; # 2, 4, 6 @bytemeorg
  24. filtermap example # [ X * X || X <-

    lists:seq(1,5), X rem 2 == 0 ]. # perl –E 'say join ", ", ...' map {; $_ * $_ } grep {; $_ % 2 == 0 } 1..5; # 4, 16 @bytemeorg
  25. reduce (fold) example # perl –MList::Util=reduce –E 'say ...' reduce

    {; $a + $b } 0, 1..3; # 6 @bytemeorg
  26. reduce (fold) example # perl –MList::Util=reduce –E 'say ...' reduce

    {; $a - $b } 0, 1..3; # what is this value? @bytemeorg
  27. reduce (fold) example # perl –MList::Util=reduce –E 'say ...' reduce

    {; $a - $b } 0, 1..3; # -6 @bytemeorg
  28. reduce is foldl reduce {; $a - $b } 0,

    1..3; # -6 foldl (-) 0 [1;2;3;];; (* -6 *) @bytemeorg
  29. real world example use JSON::PP; my $json = qq|{"foo": true,

    "bar": 42, "qux": 3.14159, "baz": ["hoge", "wak", "jib"]}|; my $hr = decode_json($json); @bytemeorg
  30. real world example # make a new hash with keys

    that start with 'b' my %newhr = map { $_ => $hr->{$_} } grep {; /\Ab/ } keys %{$hr}; # also works great for DBI results @bytemeorg
  31. Thank you! Questions? Mark Allen | mrallen1@yahoo.com | @bytemeorg

  32. references š Why Functional Programming Matters, Hughes, J, 1990: http://www.cse.chalmers.se/~rjmh/Papers/whyfp.pdf

    š Investigating fold in OCaml: https://www.matt- mcdonnell.com/code/code_ocaml/ocaml_fold/ocaml_fold.html š Free Introduction to OCaml Online Class: https://www.fun- mooc.fr/courses/parisdiderot/56002S02/session02/about š https://metacpan.org/pod/List::Util#reduce š All You Need is Fold (Midwest.io 2015): https://www.youtube.com/watch?v=bzHKp6p-Rlk