• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Functional Pearls 4 (YAPC::EU::2009 remix)
 

Functional Pearls 4 (YAPC::EU::2009 remix)

on

  • 3,342 views

The YAPC::EU::2009 (Lisbon) remix of my Functional Pe(a)rls talk.

The YAPC::EU::2009 (Lisbon) remix of my Functional Pe(a)rls talk.

Statistics

Views

Total Views
3,342
Views on SlideShare
3,339
Embed Views
3

Actions

Likes
1
Downloads
23
Comments
0

2 Embeds 3

http://www.slideshare.net 2
http://www.linkedin.com 1

Accessibility

Categories

Upload Details

Uploaded via as OpenOffice

Usage Rights

CC Attribution-NonCommercial-ShareAlike LicenseCC Attribution-NonCommercial-ShareAlike LicenseCC Attribution-NonCommercial-ShareAlike License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Functional Pearls 4 (YAPC::EU::2009 remix) Functional Pearls 4 (YAPC::EU::2009 remix) Presentation Transcript

    • osfameron Functional Pe(a)rls
    • Functional pe(a)rls World tour! IPW 2008 LPW 2008 NWE.pm May 2009 YAPC::EU Lisbon 2009 version 4 Osfameron
    • Functional Programming What is it?
    • Functional Programming About functions?
    • Functional Programming About functions? (like Object-oriented is about objects?)
    • Functional Programming everything's a function!
    • Functional Programming 1 + 2
    • Functional Programming 1 + 2 Spot the function?
    • Functional Programming 1 + 2 Spot the function?
    • Functional Programming 1 + 2 first class?
    • Functional Programming 1 + 2 +
    • Functional Programming 1 + 2 op<+>
    • OPERATORS UNITE! STOP this discrimation now!
    • What now?
      • Protest!
      • Cry!
      • Steal from Haskell!
    • What now?
      • Steal from Haskell!
      • (+) ← ref to add
    • Wrapping operators
      • sub op ($op) { return sub ($left, $right) { eval “$left $op $right” ; }; }
    • Wrapping operators
      • my $add = op('+');
      • $add->(1, 2); # 3
    • YAY!
    • YAY?
      • Still uglier than Haskell
        • (+)
        • op('+')
    • Devel::Declare
      • New syntax!
      • (But better than source filters)
    • Devel::Declare
      • New syntax!
      • (But better than source filters)
        • Method declaration
        • MooseX::Declare
        • Sub::Auto
    • Sub::Section
      • on github
      • Gives nice syntax, using Devel::Declare
      • op (+)
    • Sub::Section
      • on github
      • Gives nice syntax, using Devel::Declare
      • op (Bwahaha!) (+)
      Devel::Declare custom parser hook can inject code etc.
    • Sub::Section
      • on github
      • Gives nice syntax, using Devel::Declare
      • op (Bwahaha!) ('+')
    • Sub::Section
      • on github
      • Gives nice syntax, using Devel::Declare
      • Op ('+') # Perl is none the wiser
      Tee hee!
    • Devel::Declare
      • In Perl!
      • (With a bit of scary XS magic)
        • hooks into the compiler
        • changing the source as you compile
        • horrible perl tricks to get methods installed, and braces closed
        • mst++, rafl++
    • Sections
    • Sections
      • (+) isn't really a section
    • Sections
      • (+) isn't really a section
      • (+1) is
    • Sections
      • (+) 10, 5 # 15
      • (+1) 8 # 9
    • Currying
      • Partial application
    • Currying
      • Partial application
      • 1 arg at a time
    • Currying
      • sub add ($left, $right) { return $left + $right; }
    • Currying
      • sub add ($left, $right) { return $left + $right; }
      • (That's 2 arguments)
    • Curried functions
      • sub add ($left, $right) { return $left + $right; }
      • (That's 2 arguments)
      • add(5) ...
    • Curried functions
      • sub add ($left, $right) { return $left + $right; }
      • (That's 2 arguments)
      • add(5) # $left is bound to 5
    • Curried functions
      • sub add ($left, $right) { return $left + $right; }
      • (That's 2 arguments)
      • add(5) # $left is bound to 5 ->(6); # 11
    • Implement in Perl
      • Quite simple to do with closures:
      • sub add { my $left = shift; return sub { my $right = shift; return $left + $right; } }
    • Implement in Perl
      • Quite simple to do with closures:
      • sub add { my $left = shift; return sub { my $right = shift; return $left + $right; } }
      • Not pretty or convenient though
    • Sub::Curried
      • on CPAN
      • Gives nice syntax, using Devel::Declare
      • sub add ($left, $right) { return $left + $right; }
    • Sub::Curried
      • on CPAN
      • Gives nice syntax, using Devel::Declare
      • curry add ($left, $right) { return $left + $right; }
    • Sub::Curried
      • on CPAN
      • Gives nice syntax, using Devel::Declare
      • curry (bwahaha!) add ($left, $right) { return $left + $right; }
    • Sub::Curried
      • Turn into something like
      • curry add { return ROUTINE unless @_; check_args(2, @_); my $f = sub { my $f = sub { ... } $f = $f->(shift) for @_; return $f; }
    • Sub::Curried
      • Turn into something like
      • curry add { return ROUTINE unless @_ ; check_args(2, @_); my $f = sub { my $f = sub { ... } $f = $f->(shift) for @_; return $f; }
    • Sub::Curried
      • add(5,6); # 11
    • Sub::Curried
      • add(5,6); # 11
      • add(5); # function that adds 5
    • Sub::Curried
      • add(5,6); # 11
      • add(5); # function that adds 5
      • add(); # function that adds...
    • Sub::Curried
      • add(5,6); # 11
      • add(5); # function that adds 5
      • add(); # function that adds...
      • i.e = &add
    • Sub::Curried
      • Turn into something like
      • curry add { return ROUTINE unless @_; check_args(2 , @_); my $f = sub { my $f = sub { ... } $f = $f->(shift) for @_; return $f; }
    • Sub::Curried
      • Give diagnostics if called with too many arguments
    • Sub::Curried
      • Turn into something like
      • curry add { return ROUTINE unless @_; check_args(2, @_); my $f = sub { my $f = sub { ... } $f = $f->(shift) for @_; return $f; }
    • Sub::Curried
      • Handle
        • add(1,2)
        • add(1)->(2)
    • Why?
      • Partial application
    • Why?
      • Automatic partial application everywhere
    • Why?
      • Automatic partial application everywhere
      • ... turns out to be useful/elegant in Haskell
    • Why?
      • Automatic partial application everywhere
      • ... turns out to be useful/elegant in Haskell
      • (actually, similar techniques are used in Perl)
    • Currying the Invocant
      • package My::Class use base 'Class::Accessor'; __PACKAGE__->add_accessor('foo'); __PACKAGE__->add_accessor('bar'); __PACKAGE__->add_accessor('baz');
    • Currying the Invocant
      • package My::Class use base 'Class::Accessor'; My::Class ->add_accessor('foo'); My::Class ->add_accessor('bar'); My::Class ->add_accessor('baz');
    • Currying the Invocant
      • package My::Class use base 'Class::Accessor'; My::Class ->add_accessor('foo'); My::Class ->add_accessor('bar'); My::Class ->add_accessor('baz');
      • sub add_accessor { my ( $self , $accessor) = @_; ....
    • Currying the Invocant
      • Perl importing
        • *{$CALLER::has} = &has;
    • Currying the Invocant
      • Perl importing
        • *{$CALLER::has} = &has;
        • *{$CALLER::has} = mk_has();
    • Currying the Invocant
      • Perl importing
        • *{$CALLER::has} = &has;
        • *{$CALLER::has} = mk_has();
        • *{$CALLER::has} = has($CALLER);
    • Currying the Invocant
      • Moose!
        • package My::Class; use Moose; # imports has=has('My::Class') has 'foo'; has 'bar'; has 'baz';
    • Currying the Invocant
      • Moose!
        • package My::Class; use Moose; # imports has=has('My::Class') has 'foo'; has 'bar'; has 'baz';
      • (handwave)
    • Where were we?
      • my $add = +; # FAIL
    • Where were we?
      • my $add = +; # FAIL
      • my $add = op(+); # YAY
    • Where were we?
      • my $add = +; # FAIL
      • my $add = op(+); # YAY
      • my $add2 = op(+2); # take THAT, Haskell!
    • But...
      • (-1)
    • But...
      • (-1)
      • (1-)
    • But...
      • (-1)
      • (1-) # minus(1)
    • But...
      • (-1) # minus(???)->(1)
      • (1-) # minus(1)
    • But...
      • (-1) # (flip(minus))->(1)
      • (1-) # minus(1)
    • Flip
      • curry flip ($fn, $left, $right) { $fn->($right, $left); }
    • Flip
      • curry flip ($fn, $left, $right ) { $fn->($right, $left); }
      • Minus (3, 1) # 2
      • flip(minus)->(3, 1) # -2;
    • Flip
      • … and with currying
      • my $prev = flip(minus)->(1);
      • $prev->( 5 );
        • $left = 1
        • $right = 5
        • minus($right=5, $left=1); # 4
    • Sub::Section
      • More cool stuff
    • Sub::Section
      • my $greet = op(“Hello ” .);
    • Sub::Section
      • my $greet = op(“Hello ” .);
      • $greet->(“World”); # “Hello World”
    • Sub::Section
      • map op(*2), @numbers;
        • (1,2,3,4)
        • > (2,4,6,8)
    • Sub::Section
      • map op(*2), @numbers;
        • (1,2,3,4)
        • > (2,4,6,8)
    • Sub::Section
      • Perl map doesn't take functions...
    • Sub::Section
      • Perl map doesn't take functions...
      • map op(*2) ->($_) , @numbers;
        • (1,2,3,4)
        • > (2,4,6,8)
    • (rant)
      • Perl's map is not functional
    • (rant)
      • Perl's map is not functional
        • We took a feature from FP... and made it not take functions.
    • (rant)
      • Perl's map is not functional
      • Perl's $_ is a horrible hack around not doing currying properly
    • (rant)
      • Perl's map is not functional
      • Perl's $_ is a horrible hack around not doing currying properly
      • Why am I still programming this silly language? ;-)
    • (yay!)
      • Perl's map is not functional
      • Perl's $_ is a horrible hack around not doing currying properly
      • Why am I still programming this silly language? ;-)
      • Oh yes! - because I can change it.
    • TODO: Functional::Map
      • fmap &some_func, @list;
      • fmap sub { … }, @list;
      • fmap op(+2), @list;
    • TODO: Functional::Map
      • fmap &some_func, @list;
      • fmap sub { … }, @list;
      • fmap op(+2), @list;
      • (those will all work anyway)
    • TODO: Functional::Map
      • fmap &some_func, @list;
      • fmap sub { … }, @list;
      • fmap op(+2), @list;
      • (those will all work anyway)
      • fmap { uc } @list;
    • TODO: Functional::Map
      • fmap &some_func, @list;
      • fmap sub { … }, @list;
      • fmap op(+2), @list;
      • (those will all work anyway)
      • fmap (bwahahaha!) { uc } @list;
    • TODO: Functional::Map
      • fmap &some_func, @list;
      • fmap sub { … }, @list;
      • fmap op(+2), @list;
      • (those will all work anyway)
      • fmap sub { uc } , @list;
    • TODO: Functional::Map
      • fmap &some_func, @list;
      • fmap sub { … }, @list;
      • fmap op(+2), @list;
      • (those will all work anyway)
      • fmap underscorify( sub { uc } ) , @list;
    • TODO: Functional::Map
      • Dear lazyYAPC...
    • Sub::Section
      • my $contains_foo = op(=~/foo/);
    • More complex examples
      • centigrade = (fahrenheit-32)*5/9
    • More complex examples
      • centigrade = (fahrenheit-32)*5/9
      • my $f2c = sub { op(*5/9)->( op(-32)->(shift)) };
    • More complex examples
      • centigrade = (fahrenheit-32)*5/9
      • my $f2c = sub { op(*5/9)->( op(-32)->(shift)) };
      • MY EYES!
    • More complex examples
      • centigrade = (fahrenheit-32)*5/9
      • my $f2c = sub { op(*5/9) ->( op(-32) ->(shift)) };
    • More complex examples
      • centigrade = (fahrenheit-32)*5/9
      • my $f2c = sub { op(*5/9) ->( op(-32) ->(shift)) };
      • Never mind the boilerplate...
    • More complex examples
      • centigrade = (fahrenheit-32)*5/9
      • my $f2c = op(*5/9) << op(-32)
      • Composition
    • More complex examples
      • centigrade = (fahrenheit-32)*5/9
      • my $f2c = op(*5/9) << op(-32)
      • Sub::Compose
    • More complex examples
      • centigrade = (fahrenheit-32)*5/9
      • my $f2c = op(*5/9) << op(-32)
      • Sub::Compose
        • base class for Sub::Curried, Sub::Section
    • More complex examples
      • centigrade = (fahrenheit-32)*5/9
      • my $f2c = op(*5/9) << op(-32)
      • Sub::Compose
        • base class for Sub::Curried, Sub::Section
        • ... autobox?
    • Point-free!
      • Or point less programming
      • (obfu for maths types)
    • Point-free!
      • my $square = op(*) << dup;
      • $square->(4); # 16
    • Point-free!
      • curry dup ($arg) { ($arg)x 2 }
      • my $square = op(*) << dup;
      • $square->(4); # 16
    • Point-free!
      • curry dup ($arg) { ($arg)x 2 }
      • my $dup = op(x 2); # ?
    • Point-free!
      • curry dup ($arg) { ($arg)x 2 }
      • my $dup = op(x 2); “$arg$arg”
    • Point-free!
      • curry dup ($arg) { ($arg)x 2 }
      • my $dup = op(x 2); “$arg$arg”
        • TODO: alternate syntax for list context:
        • op[x 2] # thanks mst
    • Some light relief
    • Some light relief Monads
    • Monads
      • Come from maths
      • “Category theory”
    • Monads
      • Come from maths
      • “Category theory”
      • Very clever people rave about them being useful
    • Monads
      • Come from maths
      • “Category theory”
      • Very clever people rave about them being useful
      • Have a reputation for being hard to understand
    • Monad tutorials
    • Monad tutorials
    • Monad tutorials
    • Monad tutorials
    • Monad tutorials Step 1: Write Monad Tutorial
    • Monad tutorials Step 2: ???
    • Monad tutorials Step 3: Profit!
    • Monads
      • You already use monads
    • Monads
      • You already use monads
      • YAY!
    • Monads
      • You already use monads
      • Sequences of commands?
    • Sequencing my $x = 1; my $y = 2; my $z = $x * $y; say “$x * $y = $z”;
    • Sequencing my $x = 1; my $y = 2; my $z = $x * $y; say “$x * $y = $z”;
    • Sequencing my $x = 1; my $y = 2; my $z = $x * $y; say “$x * $y = $z”;
    • Sequencing my @seq = sub { my $x = 1 }, sub { my $y = 2 }, sub { my $z = $x * $y }, sub { say &quot;$x * $y = $z&quot; };
    • Sequencing my @seq = sub { my $x = 1 }, sub { my $y = 2 }, sub { my $z = $x * $y }, sub { say &quot;$x * $y = $z&quot; }; # Global symbol &quot;$x&quot; requires explicit package name at ...
    • Nesting my $x = 1; my $y = 2; my $z = $x * $y; say “$x * $y = $z”;
    • Nesting sub { my $x = 1; sub { my $y = 2; sub { my $z = $x * $y; sub { say &quot;$x * $y = $z&quot;; }->() }->() }->() }->();
    • Monadic programming is impractical in Perl... only because of syntactic issues – Mark Jason Dominus http://perl.plover.com/classes/fp/samples/slide027.html
    • Monads made pretty
      • Source filters!
        • http://sleepingsquirrel.org/monads/monads.html
    • Monads made pretty
      • Source filters!
        • http://sleepingsquirrel.org/monads/monads.html
      • Source tree manipulation (B::OP magic)
      • Deparse and source text munging
    • Monads made pretty
      • We want a syntax like
      • mdo { my $x = mbind(1); my $y = mbind(2); my $z = mbind($x + $y); say “$x * $y = $z”; }
    • Monads made pretty
      • We want a syntax like
      • mdo { my $x = mbind(1); my $y = mbind(2); my $z = mbind($x + $y); say “$x * $y = $z”; }
      • mdo introduces the block
      • mbind gives us a hook to rotate around
    • Optree munging
      • 19: my $x << Just 2; ... n <;> nextstate(main 2078 b.pl:19) v:*,&,$ ->o t <2> left_shift[t3] vK ->u o <0> padsv[$x:2078,2080] sM/LVINTRO ->p s <1> entersub[t2] sKS/TARG,3 ->t - <1> ex-list sK ->s p <0> pushmark s ->q q <$> const(IV 2) sM ->r - <1> ex-rv2cv sK/130 ->- r <$> gv(*Just) s ->s u <;> nextstate(main 2079 b.pl:20) v:*,&,$ ->v
      • # : mbind (Just 2), sub { my $x = shift; ... }; <;> nextstate(main b.pl:) v:*,&,{,$ -> <@> list K -> <0> pushmark s -> <1> entersub[t2] KS/TARG,3 -> - <1> ex-list K -> <0> pushmark s -> <1> entersub[t1] lKMS/NO(),TARG,INARGS,3 -> - <1> ex-list lK -> <0> pushmark s -> <$> const(IV 2) sM -> - <1> ex-rv2cv sK/130 ->- <$> gv(*Just) s -> - <1> ex-rv2cv sK/2 ->- # mbind instead of >> <$> gv(*mbind) s -> <1> refgen K/1 -> - <1> ex-list lKRM -> <0> pushmark sRM -> <$> anoncode[CV ] lRM -> # ??? set up anon sub # my $x = shift <0> padsv[$x:2078,2080] sM/LVINTRO ->p # the next ; is moved into this new lambda! <;> nextstate(main 2079 b.pl:20) v:*,&,$ ->v
    • Optree munging
      • 19: my $x << Just 2; ... n <;> nextstate(main 2078 b.pl:19) v:*,&,$ ->o t <2> left_shift[t3] vK ->u o <0> padsv[$x:2078,2080] sM/LVINTRO ->p s <1> entersub[t2] sKS/TARG,3 ->t - <1> ex-list sK ->s p <0> pushmark s ->q q <$> const(IV 2) sM ->r - <1> ex-rv2cv sK/130 ->- r <$> gv(*Just) s ->s u <;> nextstate(main 2079 b.pl:20) v:*,&,$ ->v
      • # : mbind (Just 2), sub { my $x = shift; ... }; <;> nextstate(main b.pl:) v:*,&,{,$ -> <@> list K -> <0> pushmark s -> <1> entersub[t2] KS/TARG,3 -> - <1> ex-list K -> <0> pushmark s -> <1> entersub[t1] lKMS/NO(),TARG,INARGS,3 -> - <1> ex-list lK -> <0> pushmark s -> <$> const(IV 2) sM -> - <1> ex-rv2cv sK/130 ->- <$> gv(*Just) s -> - <1> ex-rv2cv sK/2 ->- # mbind instead of >> <$> gv(*mbind) s -> <1> refgen K/1 -> - <1> ex-list lKRM -> <0> pushmark sRM -> <$> anoncode[CV ] lRM -> # ??? set up anon sub # my $x = shift <0> padsv[$x:2078,2080] sM/LVINTRO ->p # the next ; is moved into this new lambda! <;> nextstate(main 2079 b.pl:20) v:*,&,$ ->v
      KABOOM
    • Source deparsing
      • Works surprisingly well
    • Source deparsing
      • Works surprisingly well
      • for trivial cases
      • (a bit fragile)
    • Source deparsing
      • Works surprisingly well
      • for trivial cases
      • (a bit fragile)
      • though localised to mdo { ... }
    • Devel::Declare
      • Even nicer syntax
      • mdo { mbind $x = 1; mbind $y = 2; mbind $z = $x + $y; say “$x * $y = $z”; }
    • Devel::Declare
      • And cuter implementation:
      • mdo { mbind $x = 1; mbind $y = 2; mbind $z = $x + $y; say “$x * $y = $z”; }
    • Devel::Declare
      • The problem:
      • mdo { mbind 1, sub { my $x = shift; mbind 2, sub { my $y = shift; mbind $x + $y, sub { my $z = shift; say “$x * $y = $z”; } ...
    • Devel::Declare
      • No need to count nesting:
      • scope_inject
      • B::Hooks::EndOfScope
      • Use to inject a ; at the end of method declarations:
      • method foo ($x) { print $x; } # look Ma, no semicolon!
    • Devel::Declare
      • mbind's scope_inject adds a “}”
      • mdo { mbind 1, sub { my $x = shift; mbind 2, sub { my $y = shift; mbind $x + $y, sub { my $z = shift; say “$x * $y = $z”; } # adds a closing brace }
    • Devel::Declare
      • mbind's scope_inject adds a “}”
      • mdo { mbind 1, sub { my $x = shift; mbind 2, sub { my $y = shift; mbind $x + $y, sub { my $z = shift; say “$x * $y = $z”; } } # adds a closing brace }
    • Devel::Declare
      • mbind's scope_inject adds a “}”
      • mdo { mbind 1, sub { my $x = shift; mbind 2, sub { my $y = shift; mbind $x + $y, sub { my $z = shift; say “$x * $y = $z”; } } } # adds a closing brace }
    • Devel::Declare
      • mbind's scope_inject adds a “}”
      • mdo { mbind 1, sub { my $x = shift; mbind 2, sub { my $y = shift; mbind $x + $y, sub { my $z = shift; say “$x * $y = $z”; } } } } # closes block
    • So...
      • We can now sequence commands!
      • mdo { mbind $x = 1; mbind $y = 2; mbind $z = $x + $y; say “$x * $y = $z”; }
    • So...
      • We can now sequence commands!
      • in pure Perl!
    • So...
      • OK, so this was big news in Haskell in 1990s
    • So...
      • OK, so this was big news in Haskell in 1990s
      • Imperative languages have always done this
    • What else can monads do ?
      • Sequencing
      • mdo { mbind $x = 1; mbind $y = 2; mbind $z = $x + $y; say “$x * $y = $z”; }
    • What else can monads do ?
      • Sequencing
      • mdo { mbind $x = 1; mbind $y = 2; mbind $z = $x + $y; say “$x * $y = $z”; }
    • What else can monads do ?
      • Sequencing
      • mdo { mbind $x = 1 ; mbind $y = 2 ; mbind $z = $x + $y ; say “$x * $y = $z”; }
    • What else can monads do ?
      • Sequencing
      • mdo { mbind $x = 1 ; mbind $y = 2 ; mbind $z = $x + $y ; say “$x * $y = $z”; }
      • Programmable semicolon!
    • Maybe
      • Success/Failure
      • mdo (Maybe) { mbind $FH = m_open('<', $file) ; mbind $line = <$FH> ; mbind $val = lookup(h, $line) ; say “Found $val!”; }
    • Maybe
      • Success/Failure
      • mdo (Maybe) { mbind $FH = m_open('<', $file) ; mbind $line = <$FH> ; mbind $val = lookup(h, $line) ; say “Found $val!”; }
      • Will give up if can't open file, read a line from it, or look it up in a hash
    • Maybe
      • Success/Failure
      • mdo (Maybe) { mbind $FH = m_open('<', $file) ; mbind $line = <$FH> ; mbind $val = lookup(h, $line) ; say “Found $val!”; }
      • Compare chain of if (foo) { if (bar) { ...
      • or eval { ... }
    • Maybe $FH = open($file) $line = <$FH> $val = lookup ( $line ) say “Found $val”
    • Maybe $FH = open($file) $line = <$FH> $val = lookup ( $line ) say “Found $val” ?
    • Sequence
    • Maybe ? ? ?
    • Multiple (List)
    • List $x = [1..10] $y = [1..10] guard $x+$y == 10 say “$x+$y=10”
    • List
      • Cartesian product
      • mdo { mbind $x = [1..10] ; mbind $y = [1..10] ; mbind guard $x+$y == 10 ; say “$x+$y=10”; }
      • Run every $x against every $y and filter
    • List
      • Cartesian product
      • mdo { mbind $x = [1..10] ; mbind $y = [1..10] ; mbind guard $x+$y == 10 ; say “$x+$y=10”; }
      • 1+9=10
      • 2+8=10
      • ...
    • List
      • Cartesian product
      • mdo { mbind $x = [1..10] ; mbind $y = [1..10] ; mbind guard $x+$y == 10 ; say “$x+$y=10”; }
      • just like SQL
      • or LINQ
    • List comprehension
      • More compact syntax
      • mcomp ($x <- [1..10]; $y <- [1..10]; $x+y==10) { say “$x+$y=10” }
    • List
      • mdo { mbind $x = [1..10] ; mbind $y = [1..10] ; mbind guard $x+$y == 10 ; say “$x+$y=10”; }
      • We're actually calling mbind on a list
    • List
      • mdo { mbind $x = [1..10] ; mbind $y = [1..10] ; mbind guard $x+$y == 10 ; say “$x+$y=10”; }
      • We're actually calling mbind on a list
      • autobox
    • Continuations call_cc (&somefunc, ... ... ... )
    • Continuations somefunc
    • (clonable!) Continuations Somefunc for 1..3 {...}
    • Next steps?
      • Devel::Declare + PPI
        • (parse till end of statement)
    • Next steps?
      • Devel::Declare + PPI
        • (parse till end of statement)
        • $x ← foo(); # monadic
        • bar(); # also monadic!
        • my $x = 12; # “normal” value
        • (e.g. no more 'mbind' keyword)
    • Perl++
      • Not really a functional language...
      • But you can take it surprisingly far
      • (CPAN++)
    • What else can I do with monads?
      • Parsing
      • Error handling
      • SQL generation
    • Wants monads now!
      • Techniques are valuable now
      • Nicely wrapped implementation will be ready soon....
    • Wants monads now!
      • Techniques are valuable now
      • Nicely wrapped implementation will be ready soon....
      • Github: Acme::Monads – patches welcome
    • Thanks!
      • questions?
    • Thanks!
      • osfameron,
        • #london.pm, #perl.it, #northwestengland.pm
        • CPAN
        • github
      • Images
        • Red pepper section, by docman http://www.flickr.com/photos/docman/107252072/ (cc-by-nc)