Post on 05-Apr-2015
transcript
Higher Order Perl
Martin Busikmartin.busik@busik.de
Vortrag über das Buch von Marc Jason
Dominus
Martin Busik ● martin.busik@busik.de
Softwareentwicklung ist geprägt durch Hypes
Martin Busik ● martin.busik@busik.de
Sie als Perl-Programmierer sind starken Vorurteilen ausgesetzt
... perl is a write-once language
Martin Busik ● martin.busik@busik.de
Räumen Sie die Vorurteile aus, in dem sie Konzepte der FP nutzen
Martin Busik ● martin.busik@busik.de
Konzepte der Funktionalen Programmierung können in Perl verwendet werden
$asub = sub {...}
$csub = (...) ? $asub : \&bsub;
$esub = $csub->($dsub,sub{$_*2},..)
$esub->(...)
Martin Busik ● martin.busik@busik.de
Das HOP-Buch ändert Ihre Art zu programmieren
… vielleicht sogar ihr Verständnis der Programmierung
Martin Busik ● martin.busik@busik.de
Der Schlüssel zu FP in Perl sind Closures
sub add {my $a = shift;sub {
my $b = shift;$a + $b
}}
$add5 = add(5);print $add5->(7);
Martin Busik ● martin.busik@busik.de
Mit Closures können Sie globale Variablen eliminieren
$SIG{__WARN__} = commonLogging($opt->{L} || 3);
warn 5, " Starte xyz";
Martin Busik ● martin.busik@busik.de
Auch ohne globale Variablen haben Sie einen "Zustand"
*getNextId = sequenceGenerator(5);
$a = getNextId(); # $a enthält 5
$b = getNextId(); # $b enthält 6
Martin Busik ● martin.busik@busik.de
Trennen Sie Implementierung und Caching
sub rgb2cmyk {
my($r,$g,$b) = @_;
..
}
sub $rgb2cmyk_cached = wrap(\&rgb2cmyk);
$rgb2cmyk_cached->(@color)
Martin Busik ● martin.busik@busik.de
Nutzen Sie Memoization für rekursive Funktionen
sub asub {$n = shift;asub(--$n) if $n > 0
}*asub = wrap(\&asub);asub(5);
sub asub {$n = shift;asub(--$n) if $n > 0
}use Memoize;memoize ‘asub‘;asub(5);
Martin Busik ● martin.busik@busik.de
$dt = {
new => sub{...},
p => sub{...},
q => sub{...}};
$c = $dt->{$p};
die ".." unless
ref($c);
$c->();
Nutzen Sie Dispatch-Tabellen
if($p eq "new")
{...}
elsif($p eq "p")
{...}
elsif($p eq "q")
{...}
else { die ".." }
Martin Busik ● martin.busik@busik.de
Nutzen Sie Dispatch-Tabellen – mit und ohne Closures
sub asub {my (...) = @_;my $f1=sub {..}my $f2=sub {...$f1->(..)
}
my $dt = {fall1 => $f1,fall2 => $f2,}
$a = $dt->{$p};
$a->(...)
Martin Busik ● martin.busik@busik.de
Verwenden Sie Iteratoren
$i = erzeuge_iterator(...);
$e1 = $i->();
$e2 = $i->next();
$e3 = $i->('next');
$i->hasNext();
$i->('hasNext?');
while(my $e = $i->())
Martin Busik ● martin.busik@busik.de
Verwenden Sie Iteratoren... aber nicht nur als for-Ersatz
@s = (...)
for($i=0;$i<@s;$i++)
{operation($s[$i])}
@s = (...)
$i = arr_iter(@s)
while($e = $i->())
{operation($e)}
An dieser Stelle"weiss" man nicht mehr, das über ein Array iteriert wird.
Martin Busik ● martin.busik@busik.de
Verwenden Sie Iteratoren... eliminieren Sie Schleifen
@s = (...)$i = 0;while($i < @s) { op1($s[i++])
or last}while($i < @s) { op2($s[i++])
or last}
@s = (...)
$i = arr_iter(@s)
op1($i);
op2($i);
Martin Busik ● martin.busik@busik.de
Definieren Sie Operationen auf Iteratoren
igrep
imap
$i = igrep {$_->[0]=~/raute/i} $ai$e = $i->()
$i = imap {{inh => $_}} $ai$e = $i->()
Martin Busik ● martin.busik@busik.de
Wandeln Sie Rekursion in Iteration um
... wenn Sie die Abbruchbedinung erst zur Laufzeit formulieren wollen
... wenn die Ergebnismenge unendlich ist
Martin Busik ● martin.busik@busik.de
Currying kann zur Code-Wieder- verwendung genutzt werden
sub reduce (&;$@) {...}
$summe = reduce({$a+$b},0,@arr)
$produkt= reduce({$a*$b},1,@arr)
*sumF = reduce({$a+$b},0);
$summe = sumF(@arr);
$spF=reduce({[$a+$b,$a*$b]},[0,1])
Martin Busik ● martin.busik@busik.de
Einge Themen, die das Buch be- handelt, habe ich Ihnen vorenthalten
... Datenströme (Streams)... Parser
... Deklarative Programmierung
Martin Busik ● martin.busik@busik.de
Konzepte der Funktionalen Programmierung können in Perl verwendet werden
„Aptly named, this truly /is/ a Perl book of a higher order, and essential
reading for every serious Perl programmer“
Damian Conway
Martin Busik ● martin.busik@busik.de
Danke für Ihre Aufmerksamkeit!
martin.busik@busik.de