Transcript
Page 1: Functional Pe(a)rls - the Purely Functional Datastructures edition

Functional Pe(a)rls

osfameron @ IPW2011, Turinosfameron @ IPW2011, Turinthe “purely functional data structures” the “purely functional data structures”

editionedition

http://www.fickr.com/photos/jef_saf/3493852795/

Page 2: Functional Pe(a)rls - the Purely Functional Datastructures edition

previously on Functional Pe(a)rls...

(IPW, LPW, YAPC::EU, nwe.pm)currying

operator references: op(+)Acme::MonadsDevel::Declare

Page 3: Functional Pe(a)rls - the Purely Functional Datastructures edition

C I A O

C I A O

vs.

Page 4: Functional Pe(a)rls - the Purely Functional Datastructures edition

0 1 2 3

C I A O

Page 5: Functional Pe(a)rls - the Purely Functional Datastructures edition

0 1 2 3

0th element

C I A O

Page 6: Functional Pe(a)rls - the Purely Functional Datastructures edition

0 1 2 3

0th element

M I A OM I A OM I A O

Page 7: Functional Pe(a)rls - the Purely Functional Datastructures edition

0 1 2 3

0th element

M I A OM I A OM I A O

no kittens were harmed during the making of

this presentation

Page 8: Functional Pe(a)rls - the Purely Functional Datastructures edition

0 1 2 3

2nd element

M I A O

Page 9: Functional Pe(a)rls - the Purely Functional Datastructures edition

0 1 2 3

4th element

M I A O

Page 10: Functional Pe(a)rls - the Purely Functional Datastructures edition

0 1 2 3

max: 3

M I A O

Page 11: Functional Pe(a)rls - the Purely Functional Datastructures edition

0 1 2 3

max: 3

M I A O

Page 12: Functional Pe(a)rls - the Purely Functional Datastructures edition

0 1 2 3

max: 4

M I A O W

4th element

4

Page 13: Functional Pe(a)rls - the Purely Functional Datastructures edition

0 1 2 3

max: 3

M I A O …

100,000

Page 14: Functional Pe(a)rls - the Purely Functional Datastructures edition

0 1 2 3

max: 3

M I A O

Page 15: Functional Pe(a)rls - the Purely Functional Datastructures edition

0 1 2 3

max: 4

M I A O W4

0 1 2 3

max: 5

M I A O W !4 5

Page 16: Functional Pe(a)rls - the Purely Functional Datastructures edition

40 1 2 3

max: 4

M I A O W

0 1 2 3

max: 5

M I A O W !4 5

Page 17: Functional Pe(a)rls - the Purely Functional Datastructures edition

C I A O

C I A O

vs.

Arrays

Page 18: Functional Pe(a)rls - the Purely Functional Datastructures edition

C I A O

C I A O

vs.

Perl @arrays“dynamic array”

Page 19: Functional Pe(a)rls - the Purely Functional Datastructures edition

C I A O

Page 20: Functional Pe(a)rls - the Purely Functional Datastructures edition

C I A O

Page 21: Functional Pe(a)rls - the Purely Functional Datastructures edition

C I A O

Head

Page 22: Functional Pe(a)rls - the Purely Functional Datastructures edition

C I A O

Tail

Page 23: Functional Pe(a)rls - the Purely Functional Datastructures edition

C I A O

Page 24: Functional Pe(a)rls - the Purely Functional Datastructures edition

C I A O

Page 25: Functional Pe(a)rls - the Purely Functional Datastructures edition

I A O

Page 26: Functional Pe(a)rls - the Purely Functional Datastructures edition

A O

Page 27: Functional Pe(a)rls - the Purely Functional Datastructures edition

O

Page 28: Functional Pe(a)rls - the Purely Functional Datastructures edition

C I A O

0th

Page 29: Functional Pe(a)rls - the Purely Functional Datastructures edition

C A O

nth - 1

I

Page 30: Functional Pe(a)rls - the Purely Functional Datastructures edition

C A O

nth[2]?

I

nth[1]?

Page 31: Functional Pe(a)rls - the Purely Functional Datastructures edition

C A OI

nth[0]!nth[2]?

Page 32: Functional Pe(a)rls - the Purely Functional Datastructures edition

C I A O ?

Page 33: Functional Pe(a)rls - the Purely Functional Datastructures edition

C I A O ?● tail “ciao” → “iao”

Page 34: Functional Pe(a)rls - the Purely Functional Datastructures edition

C I A O ?● tail “ciao” → “iao”● tail “iao” → “ao”● tail “ao” → “o”● tail “o” → ?

Page 35: Functional Pe(a)rls - the Purely Functional Datastructures edition

C I A O ?● tail “ciao” → “iao”● tail “iao” → “ao”● tail “ao” → “o”● tail “o” → “” (the empty string)

Page 36: Functional Pe(a)rls - the Purely Functional Datastructures edition

C I A O

Page 37: Functional Pe(a)rls - the Purely Functional Datastructures edition

Head

List =

Tail(another List)

or...

Page 38: Functional Pe(a)rls - the Purely Functional Datastructures edition

Here comes the science^wPerl!

Page 39: Functional Pe(a)rls - the Purely Functional Datastructures edition

use MooseX::Declare;

BEGIN { role_type 'List' }

role List { requires 'head'; requires 'tail';}

Moose(X::Declare)

Page 40: Functional Pe(a)rls - the Purely Functional Datastructures edition

List::Link

class List::Link with List { has head => (

is => 'ro', isa => 'Any'

); has tail => (

is => 'ro', isa => 'List'

), }

Page 41: Functional Pe(a)rls - the Purely Functional Datastructures edition

List::Link

class List::Link with List { has head => (

is => 'ro', isa => 'Any'

); has tail => (

is => 'ro', isa => 'List'

), }

Page 42: Functional Pe(a)rls - the Purely Functional Datastructures edition

List::Link

class List::Link with List { has head => (

is => 'ro', isa => 'Any'

); has tail => (

is => 'ro', isa => 'List'

), }

Page 43: Functional Pe(a)rls - the Purely Functional Datastructures edition

List::Empty

class List::Empty with List { method head {

die "Can't take head of empty list!" } method tail { die "Can't take tail of empty list!" } }

Page 44: Functional Pe(a)rls - the Purely Functional Datastructures edition

So we can write:

my $list = List::Link->new( head => 'c', tail => List::Link->new( head => 'i', tail => List::Link->new(...

Page 45: Functional Pe(a)rls - the Purely Functional Datastructures edition

Sugar!

my $list = List->fromArray(qw/ c i a o /);

Page 46: Functional Pe(a)rls - the Purely Functional Datastructures edition

Multimethods

use MooseX::MultiMethods;

multi method fromArray ($class:) { return List::Empty->new; }

Page 47: Functional Pe(a)rls - the Purely Functional Datastructures edition

Multimethods

use MooseX::MultiMethods;

multi method fromArray ($class:) { return List::Empty->new; }

Page 48: Functional Pe(a)rls - the Purely Functional Datastructures edition

Multimethods multi method fromArray ($class: $head, @tail) { return List::Link->new( head => $head, tail => $class->fromArray(@tail), ); }

Page 49: Functional Pe(a)rls - the Purely Functional Datastructures edition

Eeek! Recursion!

my $list = List::fromArray(1..1000000);

Page 50: Functional Pe(a)rls - the Purely Functional Datastructures edition

Eeek! Recursion!

my $list = List::fromArray(1..1000000);

Deep recursion on subroutine "List::fromArray" at foo.pl line 20

Page 51: Functional Pe(a)rls - the Purely Functional Datastructures edition

Eeek! Recursion! multi method fromArray ($class: $head, @tail) { return List::Link->new( head => $head, tail => $class->fromArray(@tail), ); }

Page 52: Functional Pe(a)rls - the Purely Functional Datastructures edition

Eeek! Recursion!

fromArray

Page 53: Functional Pe(a)rls - the Purely Functional Datastructures edition

Eeek! Recursion!

fromArray

List::Link->new(..., fromArray)

Page 54: Functional Pe(a)rls - the Purely Functional Datastructures edition

Eeek! Recursion!

fromArray

List::Link->new(..., fromArray)

List::Link->new(..., fromArray)

Page 55: Functional Pe(a)rls - the Purely Functional Datastructures edition

Eeek! Recursion!

fromArray

List::Link->new(..., fromArray)

List::Link->new(..., fromArray)

List::Link->new(..., fromArray)

Page 56: Functional Pe(a)rls - the Purely Functional Datastructures edition

Eeek! Recursion!

fromArray

List::Link->new(..., fromArray)

List::Link->new(..., fromArray)

List::Link->new(..., fromArray)

List::Link->new(..., fromArray)

Page 57: Functional Pe(a)rls - the Purely Functional Datastructures edition

Eeek! Recursion!

fromArray

List::Link->new(..., fromArray)

List::Link->new(..., fromArray)

List::Link->new(..., fromArray)

List::Link->new(..., fromArray) $list=

Page 58: Functional Pe(a)rls - the Purely Functional Datastructures edition

Eeek! Recursion!

fromArray

List::Link->new(..., fromArray)

List::Link->new(..., fromArray)

List::Link->new(..., fromArray) $list=

Page 59: Functional Pe(a)rls - the Purely Functional Datastructures edition

Eeek! Recursion!

fromArray

List::Link->new(..., fromArray)

List::Link->new(..., fromArray) $list=

Page 60: Functional Pe(a)rls - the Purely Functional Datastructures edition

Eeek! Recursion!

fromArray

List::Link->new(..., fromArray) $list=

Page 61: Functional Pe(a)rls - the Purely Functional Datastructures edition

Eeek! Recursion!

fromArray $list=

Page 62: Functional Pe(a)rls - the Purely Functional Datastructures edition

Eeek! Recursion!

no warnings 'recursion';$DB::deep = 100_000_000;

Page 63: Functional Pe(a)rls - the Purely Functional Datastructures edition

Eeek! Recursion!

no warnings 'recursion';$DB::deep = 100_000_000;

Papering over the cracks

Page 64: Functional Pe(a)rls - the Purely Functional Datastructures edition

Tail Call Elimination

Sub::Call::TailSub::Call::Recur

by nothingmuch

Page 65: Functional Pe(a)rls - the Purely Functional Datastructures edition

Tail call elimination

fromArray

Page 66: Functional Pe(a)rls - the Purely Functional Datastructures edition

Tail call elimination

List::Link->new(..., fromArray)

Page 67: Functional Pe(a)rls - the Purely Functional Datastructures edition

Tail call elimination

List::Link->new(..., fromArray)

Page 68: Functional Pe(a)rls - the Purely Functional Datastructures edition

Tail call elimination

List::Link->new(..., fromArray)

Page 69: Functional Pe(a)rls - the Purely Functional Datastructures edition

Tail call elimination

List::Link->new(..., fromArray)

Page 70: Functional Pe(a)rls - the Purely Functional Datastructures edition

Tail call elimination

List::Link->new(..., fromArray) $list=

Page 71: Functional Pe(a)rls - the Purely Functional Datastructures edition

Tail Call Elimination

use Sub::Import 'Sub::Call::Tail' tail => { -as => 'tail_call' };

multi method fromArray ($self: $head, @tail) { tail_call List::Link->new( head => $head, tail => $self->fromArray(@tail), );}

Page 72: Functional Pe(a)rls - the Purely Functional Datastructures edition

Indexing into List

multi method nth (List::Empty $self: Int $pos)

{ die "Can't index into an Empty list"; }

Page 73: Functional Pe(a)rls - the Purely Functional Datastructures edition

Indexing into List

multi method nth (Int $pos where { $_ == 0 })

{ return $self->head; }

Page 74: Functional Pe(a)rls - the Purely Functional Datastructures edition

Indexing into List

multi method nth (Int $pos where { $_ > 0 })

{ tail_call $self->tail->nth( $pos - 1 ); }

Page 75: Functional Pe(a)rls - the Purely Functional Datastructures edition

C I A O

M

Page 76: Functional Pe(a)rls - the Purely Functional Datastructures edition

C I A O

M W

Page 77: Functional Pe(a)rls - the Purely Functional Datastructures edition

C I A O

M WMutation leads to bugs (and misspellings!)

Page 78: Functional Pe(a)rls - the Purely Functional Datastructures edition

C I A O

M WI A O

Page 79: Functional Pe(a)rls - the Purely Functional Datastructures edition

C I A O

C I B

Page 80: Functional Pe(a)rls - the Purely Functional Datastructures edition

C I A O

C I B

Copy everything upstream of a changeDownstream of changes can be shared

Page 81: Functional Pe(a)rls - the Purely Functional Datastructures edition

C I A O

C I B

Doubly linked lists have no downstream!

O

Page 82: Functional Pe(a)rls - the Purely Functional Datastructures edition

pure-fp-book

● https://github.com/osfameron/pure-fp-book● Purely Functional Data Structures for the...

● Impure● Perl Programmer● Working Programmer● Mutable, Rank-Scented Many


Top Related