osfameron
Functional Pe(a)rls
Functional pearls
x5
Functional Pe(a)rls
5 min
Functional pearls
eeek!
1. map, grep, join
map
1. map
●my @names = qw/
Pippo Pluto Pinco /;
1. map
●Hello Pippo!●Hello Pluto!●Hello Pinco!
1. map
●my @greetings;●for (@names) {● push @greetings, "Hello $_!";
●}
1. map
●my @greetings = map { "Hello $_!" } @names
1. map, grep, join
grep
1. grep
●Names that contain “i”
–Pippo–Pinco
1. grep
●my @names_with_i;●for (@names) {● push @names_with_i, $_ if /i/;
●}
1. grep
●my @names_with_i =
grep /i/, @names;
1. map, grep, join
join
1. join
●Pippo, Pluto, Pinco
1. join
●my $joined = $names[0];● for (@names[1..$#names]) {● $joined .= ', ';● $joined .= $_;● }
1. join
●my $joined = join ', ' => @names;
More Complex
2. A sequence
● Debolaz, on #moose● a list of numbers like
–10, 25, 50,–100, 250, 500,–1000,etc
● without tracking any other state than the number itself
2. A sequence
1. (power of 10) Multiply by 2.5
2. Multiply by 23. Multiply by 2
2. A sequence
without tracking any other state
than the number itself
2. A sequence
/^1/
2. A sequence
/^1/ # power of 10
2. A sequence
●cycle [2.5, 2, 2]● 2.5, 2, 2,● 2.5, 2, 2, ...
2. A sequence
●Oops! ●Perl doesn't have infinite sequences
2. A sequence
Iterators
2. A sequence
● curry cycle (@list) {● my @curr = @list;● return sub {● @curr = @list unless @curr;● return shift @curr;● };● }
2. A sequence
●my $c = cycle [2.5, 2, 2];– say $c->(); # 2.5– say $c->(); # 2– say $c->(); # 2– say $c->(); # 2.5– ...
2. A sequence
● say for● take 12 =>● scan(● mk_seq( [2.5, 2, 2] ),● 10● );
2. A sequence
●curry mk_seq (@multipliers) {
● cycle [ map { times($_) } @multipliers ];
● };
2. A sequence
●curry times ($x,$y) { ● $x * $y ●};
3. Currying
●curry times ($x,$y) { ● $x * $y ●};
3. Currying
●my $triple = times(3);●say $triple->(10); ● # 30
3. Currying
●my $multiply = times;●say $multiply->(6, 8);
3. Currying
●my $multiply = \×●my $multiply = times;
3. Currying
●Sub::Curried
3. Currying
●Devel::Declare
Devel::Declare
●New syntax!● (But better than source filters)
– Currying
– Monads
– List comprehensions
– Functions that work on @arrays and lists
2. A sequence
● say for● take 12 =>● scan(● mk_seq( [2.5, 2, 2] ),● 10● );
2. A sequence
●http://greenokapi.net/blog/ 2008/07/27/ 102550-sequence-fun/
2. A sequence
●HOP::Stream●Scalar::Defer
2. A sequence
●HOP::Stream●Data::Lazy
2. A sequence
●HOP::Stream●Data::Thunk
4. Laziness
●my $x = lazy { 1/0 };
4. Laziness
●my $x = lazy { 1/0 };
● print $x; # OUCH!
5. Concurrency
Hard
5. Concurrency
Ugly
5. Concurrency
futures (Java)
5. Concurrency
parallel strategies (Haskell)
5. Concurrency
●my $x = forked {● expensive_code();● };
5. Concurrency
Lazy!
5. Concurrency
●wait on child only if we ask for $x
5. Concurrency
●my @list = map forked { ● sleep $_;● $_*2 ● }, 1..10;
5. Concurrency
●after 1 sec “2”●after 2 sec “4”●after 3 sec “6”●...
5. Concurrency
●sleep 5
5. Concurrency
●sleep 5● (5 of the values are now ready)
5. Concurrency
● sleep 5● say $_ for @list;
–2–4–6–8–10– ...
5. Concurrency
● sleep 5● say $_ for @list;
–2–4–6–8–10– ... (block till @list finished)
5. Concurrency
●Acme::Fork::Lazy
5. Concurrency
●Data::Thunk (etc.)
5. Concurrency
●YAML● (for marshalling)
5. Concurrency
●forks
5. Concurrency
●Problems?–retry on fail?– test if ready?–run only when preconditions ready?
5. Concurrency
●Acme::Fork::Lazy
5. Concurrency
●IO::Lambda
Grazie