Functional pe(a)rls: Huey's zipper

1,083 views

Published on

2014 edition of the Functional Pe(a)rls series, this time on purely functional Zippers with Moo, and self-balancing AA trees.

Published in: Technology
  • Be the first to comment

Functional pe(a)rls: Huey's zipper

  1. 1. FUNCTIONAL PE(A)RLS YAPC::EU::2014 София @osfameron Huey’s Zipper http://marinaneira.deviantart.com/art/Huey-Duck-317018337
  2. 2. FUNCTIONAL PE(A)RLS WORLD TOUR IPW 2008, Pisa  map/grep, lazy iterators, currying, Devel::Declar for pretty syntax, Concurrency (Acme::Fork::Lazy) LPW 2008, London  much of above, Monad tutorial, Devel::Declare, Imperative programming in Pure Perl! NWE.pm May 2009, Manchester  as above, possibly also pattern matching? YAPC::EU 2009, Lisbon  functions, operators, Devel::Declare, sections, partial application, Sub::Curried, composition IPW 2011, Turin  purely functional data structures, linked lists, http://www.slideshare.net/osfameron/
  3. 3. https://www.flickr.com/photos/qiaomeng/5540694558/
  4. 4. https://www.flickr.com/photos/hoyvinmayvin/4686704193/
  5. 5. IN THE BLUE CORNER… Mutable my $x = 10; … $x = 20; Immutable my $x = 10; … my $x2 = 20;
  6. 6. AND IN THE RED CORNER… Mutable sub c2f { my $temp=shift; $temp *= 9; $temp /= 5; $temp += 32; return $temp; } Immutable sub c2f { my $c=shift; my $t1 = $c * 9; my $t2 = $t1 / 5; my $f = $t2 + 32; return $f; }
  7. 7. AND IN THE RED CORNER… (redux) Mutable sub c2f { my $temp=shift; $temp *= 9/5; $temp += 32; return $temp; } Immutable sub c2f { my $c = shift; return ( ($c * 9/5) + 32 ) }
  8. 8. https://www.flickr.com/photos/redvers/532076662/
  9. 9. MUTABLE… CONSTANTS? 1 = 2; say 1 + 1; # 4
  10. 10. ACTION AT A DISTANCE my $one = 1; … sub bad_mutation { $one++; } sub naïve_expectations { say $one + $one; # 2? Or 4, 6, 10, etc.? }
  11. 11. CONSTANTS use constant ONE => 1; … sub on_the_defensive { say ONE + ONE; # 2 }
  12. 12. https://www.flickr.com/photos/jans_world/8985026701/
  13. 13. IMMUTABLE DATA STRUCTURES… my $users = { … }; my $users_with_addresses = frobnicate($users); send_emails($users_with_addresses); sub send_emails { my $in = shift; my $intermediate = doozle($in); … return $out }
  14. 14. IMMUTABLE DATA STRUCTURES… my $users = { … }; my $users_with_addresses = frobnicate($users); send_emails($users_with_addresses); sub send_emails { my $in = shift; my $intermediate = doozle($in); … return $out }
  15. 15. IMMUTABLE DATA STRUCTURES… my $users = { … }; my $users_with_addresses = frobnicate($users); send_emails($users_with_addresses); sub send_emails { my $in = shift; my $intermediate = doozle($in); … return $out }
  16. 16. https://www.flickr.com/photos/light_seeker/7571188852/
  17. 17. READONLY VARIABLES use Const::Fast; sub wibble { const my $in => shift; const my $out => $in * 2; return $out; }
  18. 18. READONLY VARIABLES const my %hash => ( foo => { bar => 1 } ); $hash{foo}{bar} = 2; # tee hee hee
  19. 19. READONLY VARIABLES const my %hash => ( foo => { bar => 1 } ); $hash{foo}{bar} = 2; # Modification of a read-only value attempted
  20. 20. COPIES OF VARIABLES? Mutable sub c2f { my $temp=shift; $temp *= 9; $temp /= 5; $temp += 32; return $temp; } Immutable sub c2f { my $c=shift; my $t1 = $c * 9; my $t2 = $t1 / 5; my $f = $t2 + 32; return $f; }
  21. 21. https://www.flickr.com/photos/historiska/13619294395
  22. 22. CREATURE COMFORTS package Creature; use Moo; use Types::Standard ‘:all’; has name => ( is => ‘ro’, isa => Str ); has type => ( is => ‘ro’, isa => Str ); has height => ( is => ‘ro’, isa => Num );
  23. 23. IF IT QUACKS LIKE A DUCK use Creature; my $donald = Creature->new( name => ‘Donald’, type => ‘duck’, height => 50, # cm );
  24. 24. RESEARCH http://wiki.answers.com/Q/How_tall_is_Donald_duck
  25. 25. RESEARCH https://www.google.co.uk/search?q=2+feet+in+cm
  26. 26. LET’S JUST CHANGE THAT THEN, OH… $donald->height( 60.96 );
  27. 27. CREATURE COMFORTS package Creature; use Moo; use Types::Standard ‘:all’; has name => ( is => ‘ro’, isa => Str ); has type => ( is => ‘ro’, isa => Str ); has height => ( is => ‘ro’, isa => Num );
  28. 28. CHAINED COPY… # using MooseX::Attribute::ChainedClone my $donald2 = $donald->height( 60.96 );
  29. 29. https://www.flickr.com/photos/dps/7161557/
  30. 30. CHAINED COPY… # using MooseX::Attribute::ChainedClone my $donald2 = $donald->height( 60.96 );
  31. 31. MooX::But package MooX::But; use Moo::Role; sub but { my $self = shift; return $self->new(%$self, @_); } # see https://github.com/haarg/MooX-CloneWith
  32. 32. CHAINED COPY… my $donald2 = $donald->but( height => 60.96 );
  33. 33. https://www.flickr.com/photos/randar/10337132166/
  34. 34. I’LL BE A MONKEY’S UNCLE package Creature; use Moo; use Types::Standard ‘:all’; has name => ( is => ‘ro’, isa => Str ); has type => ( is => ‘ro’, isa => Str ); has height => ( is => ‘ro’, isa => Num ); has uncle => ( is => ‘ro’, isa => InstanceOf[‘Creature’] );
  35. 35. COMPLEX CHAINED COPIES… Mutable $donald ->uncle ->height(52); Immutable $donald ->uncle ->but( height => 52 );
  36. 36. COMPLEX CHAINED COPIES… Mutable $donald ->uncle ->height(52); Immutable my … = $donald ->uncle ->but( height => 52 );
  37. 37. COMPLEX CHAINED COPIES… my $donald2 = $donald->but( uncle => $donald->uncle->but( height => 52 ) );
  38. 38. https://www.flickr.com/photos/81583603@N00/4099146279/
  39. 39. EVEN MOAR COMPLEX CHAINED COPIES… my $huey = $huey->but( uncle => $huey->uncle->but( uncle => $huey->uncle->uncle->but( height => 52, ) ) );
  40. 40. https://en.wikipedia.org/wiki/Clan_McDuck#Family_tree
  41. 41. http://pixdaus.com/super-squirrel-squirrel/items/view/97702/
  42. 42. THE ZIPPER my $zipper = $huey->zip;
  43. 43. THE ZIPPER my $zipper = $huey->zip ->go(‘uncle’);
  44. 44. THE ZIPPER my $zipper = $huey->zip ->go(‘uncle’) ->go(‘uncle’);
  45. 45. https://www.flickr.com/photos/nics_events/2349632625/
  46. 46. MODIFYING “IN-PLACE” my $zipper = $huey->zip ->go(‘uncle’) ->go(‘uncle’) ->set( height => 51 );
  47. 47. BACK UP THE ZIPPER my $zipper = $huey->zip ->go(‘uncle’) ->go(‘uncle’) ->set( height => 51 ) ->up;
  48. 48. BACK UP THE ZIPPER my $zipper = $huey->zip ->go(‘uncle’) ->go(‘uncle’) ->set( height => 51 ) ->up ->up;
  49. 49. https://www.flickr.com/photos/123755251@N04/13969035991
  50. 50. UNZIPPING my $huey2 = $huey->zip ->go(‘uncle’) ->go(‘uncle’) ->set( height => 51 ) ->up ->up ->unzip;
  51. 51. UNZIPPING my $huey2 = $huey->zip ->go(‘uncle’) ->go(‘uncle’) ->set( height => 51 ) ->up ->up ->unzip;
  52. 52. UNZIPPING my $huey2 = $huey->zip ->dive(‘uncle’, ‘uncle’) ->set( height => 51 ) ->unzip;
  53. 53. UNZIPPING my $huey2 = $huey->doZipper( sub { $_ ->dive(‘uncle’, ‘uncle’) ->set( height => 51 ) } );
  54. 54. REMATCH Mutable $huey ->uncle ->uncle ->height(51); Immutable my $huey2 = $huey ->doZipper(sub { $_->uncle ->uncle ->set(height=>51) });
  55. 55. REMATCH Mutable $huey ->uncle ->uncle ->height(51); Immutable my $huey2 = $huey ->doZipper(sub { $_->uncle ->uncle ->set(height=>51) });
  56. 56. https://www.flickr.com/photos/phunk/1460508385/
  57. 57. https://www.flickr.com/photos/mukumbura/3845329580/
  58. 58. https://www.flickr.com/photos/93081182@N02/12853918764/
  59. 59. https://www.flickr.com/photos/intherough/3470183543/
  60. 60. https://www.flickr.com/photos/ruthanddave/1760267748/
  61. 61. RED BLACK TREES https://en.wikipedia.org/wiki/Red%E2%80%93black_tree
  62. 62. https://www.flickr.com/photos/bunnyrel/3970251151/
  63. 63. TYPICAL RED-BLACK TREE CASES https://en.wikipedia.org/wiki/AA_tree
  64. 64. http://www.quickmeme.com/Engineering-Professor/page/43/
  65. 65. AA TREE CASES https://en.wikipedia.org/wiki/AA_tree
  66. 66. https://www.flickr.com/photos/wwarby/7127632463/
  67. 67. BALANCING ROTATIONS Skew Split
  68. 68. ZIPPER WITHIN AA-TREE CODE # split return $R->but( left => $self->but( right => $R->left, ), level => $R->level + 1, );
  69. 69. ZIPPER WITHIN AA-TREE CODE # split return $R->but( left => $self->but( right => $R->left, ), level => $R->level + 1, );
  70. 70. ZIPPER WITHIN AA-TREE CODE # split return $R->zip ->set( level => $R->level + 1) ->left->set( right => $R->left ) ->unzip;
  71. 71. ZIPPER WITHIN AA-TREE CODE # split return $R->zip ->inc(‘level’) ->left->set( right => $R->left ) ->unzip;
  72. 72. https://www.flickr.com/photos/jimmiehomeschoolmom/5066802611
  73. 73. ZIPPER WITHIN AA-TREE CODE # in delete $tree = $tree->zip ->set( level => $min_level ) ->right->set( level => $min_level2 ) ->top->skew->right->skew->right->skew ->top->split->right->split ->unzip;
  74. 74. ZIPPER WITHIN AA-TREE CODE # in delete $tree = $tree->zip ->set( level => $min_level ) ->right->set( level => $min_level2 ) ->top->skew->right->skew->right->skew ->top->split->right->split ->unzip;
  75. 75. ZIPPER WITHIN AA-TREE CODE # in delete $tree = $tree->zip ->set( level => $min_level ) ->go(‘right’)->set( level => $min_level2 ) ->top->skew->go(‘right’)->skew->go (‘right’)->s ->top->split->go(‘right’)->split ->unzip;
  76. 76. ZIPPER WITHIN AA-TREE CODE # in delete $tree = $tree->zip ->set( level => $min_level ) ->right->set( level => $min_level2 ) ->top->skew->right->skew->right->skew ->top->split->right->split ->unzip;
  77. 77. LendingMemo.com - https://www.flickr.com/photos/lendingmemo/11702093735/
  78. 78. https://www.flickr.com/photos/wwworks/4759535950/

×