functional pe(a)rls: huey's zipper

Post on 11-Jan-2015

266 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

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

TRANSCRIPT

FUNCTIONAL PE(A)RLSYAPC::EU::2014 София

@osfameron

Huey’s Zipper

http://marinaneira.deviantart.com/art/Huey-Duck-317018337

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/

https://www.flickr.com/photos/qiaomeng/5540694558/

https://www.flickr.com/photos/hoyvinmayvin/4686704193/

IN THE BLUE CORNER…

Mutable

my $x = 10;

$x = 20;

Immutable

my $x = 10;

my $x2 = 20;

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;

}

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

)}

https://www.flickr.com/photos/redvers/532076662/

MUTABLE… CONSTANTS?

1 = 2;

say 1 + 1; # 4

ACTION AT A DISTANCE

my $one = 1;

sub bad_mutation {$one++;

}

sub naïve_expectations {say $one + $one; # 2? Or 4, 6, 10, etc.?

}

CONSTANTS

use constant ONE => 1;

sub on_the_defensive {say ONE + ONE; # 2

}

https://www.flickr.com/photos/jans_world/8985026701/

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

}

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

}

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

}

https://www.flickr.com/photos/light_seeker/7571188852/

READONLY VARIABLES

use Const::Fast;

sub wibble {const my $in => shift;const my $out => $in * 2;return $out;

}

READONLY VARIABLES

const my %hash => (foo => {

bar => 1}

);

$hash{foo}{bar} = 2; # tee hee hee

READONLY VARIABLES

const my %hash => (foo => {

bar => 1}

);

$hash{foo}{bar} = 2;

# Modification of a read-only value attempted

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;

}

https://www.flickr.com/photos/historiska/13619294395

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 );

IF IT QUACKS LIKE A DUCK

use Creature;

my $donald = Creature->new(name => ‘Donald’,type => ‘duck’,height => 50, # cm

);

RESEARCH

http://wiki.answers.com/Q/How_tall_is_Donald_duck

RESEARCH

https://www.google.co.uk/search?q=2+feet+in+cm

LET’S JUST CHANGE THAT THEN, OH…

$donald->height( 60.96 );

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 );

CHAINED COPY…

# using MooseX::Attribute::ChainedClone

my $donald2 = $donald->height( 60.96 );

https://www.flickr.com/photos/dps/7161557/

CHAINED COPY…

# using MooseX::Attribute::ChainedClone

my $donald2 = $donald->height( 60.96 );

MooX::But

package MooX::But;

use Moo::Role;

sub but {

my $self = shift;

return $self->new(%$self, @_);

}

# see https://github.com/haarg/MooX-CloneWith

CHAINED COPY…

my $donald2 = $donald->but( height => 60.96 );

https://www.flickr.com/photos/randar/10337132166/

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’] );

COMPLEX CHAINED COPIES…

Mutable

$donald->uncle->height(52);

Immutable

$donald->uncle->but(height => 52

);

COMPLEX CHAINED COPIES…

Mutable

$donald->uncle->height(52);

Immutable

my … = $donald->uncle->but(height => 52

);

COMPLEX CHAINED COPIES…

my $donald2 = $donald->but(uncle => $donald->uncle->but(

height => 52)

);

https://www.flickr.com/photos/81583603@N00/4099146279/

EVEN MOAR COMPLEX CHAINED COPIES…

my $huey = $huey->but(uncle => $huey->uncle->but(

uncle => $huey->uncle->uncle->but(height => 52,

))

);

https://en.wikipedia.org/wiki/Clan_McDuck#Family_tree

http://pixdaus.com/super-squirrel-squirrel/items/view/97702/

THE ZIPPER

my $zipper = $huey->zip;

THE ZIPPER

my $zipper = $huey->zip->go(‘uncle’);

THE ZIPPER

my $zipper = $huey->zip->go(‘uncle’)->go(‘uncle’);

https://www.flickr.com/photos/nics_events/2349632625/

MODIFYING “IN-PLACE”

my $zipper = $huey->zip->go(‘uncle’)->go(‘uncle’)->set( height => 51 );

BACK UP THE ZIPPER

my $zipper = $huey->zip->go(‘uncle’)->go(‘uncle’)->set( height => 51 )->up;

BACK UP THE ZIPPER

my $zipper = $huey->zip->go(‘uncle’)->go(‘uncle’)->set( height => 51 )->up->up;

https://www.flickr.com/photos/123755251@N04/13969035991

UNZIPPING

my $huey2 = $huey->zip->go(‘uncle’)->go(‘uncle’)->set( height => 51 )->up->up->unzip;

UNZIPPING

my $huey2 = $huey->zip->go(‘uncle’)->go(‘uncle’)->set( height => 51 )->up->up->unzip;

UNZIPPING

my $huey2 = $huey->zip->dive(‘uncle’, ‘uncle’)->set( height => 51 )->unzip;

UNZIPPING

my $huey2 = $huey->doZipper( sub { $_->dive(‘uncle’, ‘uncle’)->set( height => 51 ) } );

REMATCH

Mutable

$huey->uncle->uncle->height(51);

Immutable

my $huey2 = $huey->doZipper(sub {

$_->uncle->uncle->set(height=>51)

});

REMATCH

Mutable

$huey->uncle->uncle->height(51);

Immutable

my $huey2 = $huey->doZipper(sub {

$_->uncle->uncle->set(height=>51)

});

https://www.flickr.com/photos/phunk/1460508385/

https://www.flickr.com/photos/mukumbura/3845329580/

https://www.flickr.com/photos/93081182@N02/12853918764/

https://www.flickr.com/photos/intherough/3470183543/

https://www.flickr.com/photos/ruthanddave/1760267748/

RED BLACK TREES

https://en.wikipedia.org/wiki/Red%E2%80%93black_tree

https://www.flickr.com/photos/bunnyrel/3970251151/

TYPICAL RED-BLACK TREE CASES

https://en.wikipedia.org/wiki/AA_tree

http://www.quickmeme.com/Engineering-Professor/page/43/

AA TREE CASES

https://en.wikipedia.org/wiki/AA_tree

https://www.flickr.com/photos/wwarby/7127632463/

BALANCING ROTATIONS

Skew Split

ZIPPER WITHIN AA-TREE CODE

# split

return $R->but(

left => $self->but(

right => $R->left,

),

level => $R->level + 1,

);

ZIPPER WITHIN AA-TREE CODE

# split

return $R->but(

left => $self->but(

right => $R->left,

),

level => $R->level + 1,

);

ZIPPER WITHIN AA-TREE CODE

# split

return $R->zip

->set( level => $R->level + 1)

->left->set( right => $R->left )

->unzip;

ZIPPER WITHIN AA-TREE CODE

# split

return $R->zip

->inc(‘level’)

->left->set( right => $R->left )

->unzip;

https://www.flickr.com/photos/jimmiehomeschoolmom/5066802611

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;

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;

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’)->skew

->top->split->go(‘right’)->split

->unzip;

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;

LendingMemo.com - https://www.flickr.com/photos/lendingmemo/11702093735/

https://www.flickr.com/photos/wwworks/4759535950/

top related