SlideShare a Scribd company logo
Functional pe(a)rls London Perl Workshop 29/11/2008 version 2 osfameron
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
A sequence 1.  (power of 10)     * 2.5  2.  * 2 3.  * 2
A sequence without tracking any other state than the number itself
A sequence /^1/
A sequence /^1/   # power of 10
A sequence cycle [2.5, 2, 2]
A sequence cycle [2.5, 2, 2] 2.5 2 2 2.5 ...
A sequence Oops!  Perl doesn't have infinite sequences
A sequence Iterators
A sequence curry cycle (@list) { my @curr = @list; return sub { @curr = @list  unless @curr; return shift @curr; }; }
A sequence my $c = cycle    [2.5, 2, 2];
A sequence my $c = cycle    [2.5, 2, 2]; say $c->();  # 2.5 say $c->();  # 2 say $c->();  # 2 say $c->();  # 2.5 ...
A sequence cycle [2.5, 2, 2];
A sequence 10, cycle [2.5, 2, 2];
A sequence   mult,  10, cycle [2.5, 2, 2];
(curry)‏ curry mult ($x,$y) {  $x * $y  }
(curry)‏ say mult( 3, 4 ); # 12
(curry)‏ my $triple = mult(3); say $triple->(10); # 30
(curry)‏ my $multiply = mult; say $multiply->(6, 8);
(curry)‏ my $multiply = \&mult; my $multiply = mult;
A sequence   mult ,  10, cycle [2.5, 2, 2];
A sequence scan    mult,  10, cycle [2.5, 2, 2];
(Scanning)‏ scan  add,  1, [2, 3, 4]; # [1, 3, 6, 10]
A sequence scan    mult,  10, cycle  [2.5, 2, 2];
A sequence take 12 =>  scan    mult,  10, cycle [2.5, 2, 2];
A sequence say for  take 12 =>  scan    mult,  10, cycle [2.5, 2, 2];
A sequence 10 25 50 100 250 500 ...
How? Iterators (HOP)‏ HOP::Stream Lazy variables
How? Iterators (HOP)‏ FP (scan, take)‏
How? Iterators (HOP)‏ FP (scan, take)‏ Sub::Curried
How? Iterators (HOP)‏ FP (scan, take)‏ Sub::Curried Devel::Declare
Devel::Declare curry mult ($x,$y) {  $x * $y  }
Devel::Declare New syntax! (But better than source filters)‏
Devel::Declare New syntax! (But better than source filters)‏ Method declaration MooseX::Declare Sub::Auto
Devel::Declare New syntax! (But better than source filters)‏ Currying Monads Pattern Matching List comprehensions Functions that work on @arrays and lists
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++
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 "$x * $y = $z"  };
Sequencing my @seq = sub { my $x = 1 }, sub { my $y = 2 }, sub { my $z = $x * $y }, sub { say "$x * $y = $z"  }; # Global symbol "$x" 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 "$x * $y = $z"; }->() }->() }->() }->();
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 Scope::Guard 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! YAY?
So... We can now sequence commands! OK, so this was big news in Haskell in 1990s
So... We can now sequence commands! 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
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 Continuations (real resumable ones)‏
Wants monads now! Techniques are valuable now Nicely wrapped implementation will be ready soon....
Thanks! questions?

More Related Content

What's hot (20)

PDF
Descobrindo a linguagem Perl
garux
 
PDF
The Perl6 Type System
abrummett
 
PPT
PHP and MySQL
Sanketkumar Biswas
 
PDF
Perl 6 in Context
lichtkind
 
PDF
RxSwift 시작하기
Suyeol Jeon
 
PDF
Introdução ao Perl 6
garux
 
PDF
Programming Lisp Clojure - 2장 : 클로저 둘러보기
JangHyuk You
 
PDF
Perl 6 by example
Andrew Shitov
 
PPT
An Elephant of a Different Colour: Hack
Vic Metcalfe
 
PDF
Perl.Hacks.On.Vim
Lin Yo-An
 
KEY
Good Evils In Perl (Yapc Asia)
Kang-min Liu
 
PPTX
Perl6 a whistle stop tour
Simon Proctor
 
PDF
Perl6 a whistle stop tour
Simon Proctor
 
KEY
Can't Miss Features of PHP 5.3 and 5.4
Jeff Carouth
 
PDF
Zend Certification Preparation Tutorial
Lorna Mitchell
 
KEY
groovy & grails - lecture 3
Alexandre Masselot
 
PDF
Static Optimization of PHP bytecode (PHPSC 2017)
Nikita Popov
 
PDF
"How was it to switch from beautiful Perl to horrible JavaScript", Viktor Tur...
Fwdays
 
PDF
Swift 함수 커링 사용하기
진성 오
 
PDF
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
James Titcumb
 
Descobrindo a linguagem Perl
garux
 
The Perl6 Type System
abrummett
 
PHP and MySQL
Sanketkumar Biswas
 
Perl 6 in Context
lichtkind
 
RxSwift 시작하기
Suyeol Jeon
 
Introdução ao Perl 6
garux
 
Programming Lisp Clojure - 2장 : 클로저 둘러보기
JangHyuk You
 
Perl 6 by example
Andrew Shitov
 
An Elephant of a Different Colour: Hack
Vic Metcalfe
 
Perl.Hacks.On.Vim
Lin Yo-An
 
Good Evils In Perl (Yapc Asia)
Kang-min Liu
 
Perl6 a whistle stop tour
Simon Proctor
 
Perl6 a whistle stop tour
Simon Proctor
 
Can't Miss Features of PHP 5.3 and 5.4
Jeff Carouth
 
Zend Certification Preparation Tutorial
Lorna Mitchell
 
groovy & grails - lecture 3
Alexandre Masselot
 
Static Optimization of PHP bytecode (PHPSC 2017)
Nikita Popov
 
"How was it to switch from beautiful Perl to horrible JavaScript", Viktor Tur...
Fwdays
 
Swift 함수 커링 사용하기
진성 오
 
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
James Titcumb
 

Similar to Functional Pe(a)rls version 2 (20)

ODP
Functional Pearls 4 (YAPC::EU::2009 remix)
osfameron
 
PDF
Good Evils In Perl
Kang-min Liu
 
PDF
Monads in perl
Masahiro Honma
 
PPT
Haskell retrospective
chenge2k
 
PPT
Cleancode
hendrikvb
 
PDF
Scripting3
Nao Dara
 
PDF
Our Friends the Utils: A highway traveled by wheels we didn't re-invent.
Workhorse Computing
 
ODP
Modern Perl
Marcos Rebelo
 
PPTX
Perl slid
pacatarpit
 
PDF
Functional Concepts for OOP Developers
brweber2
 
ODP
Introduction to Perl - Day 2
Dave Cross
 
PDF
Helvetia
ESUG
 
PPTX
Lecture 3 Perl & FreeBSD administration
Mohammed Farrag
 
PDF
Erlang Introduction Bcberlin3
guesta3202
 
PPT
Dealing with Legacy Perl Code - Peter Scott
O'Reilly Media
 
PDF
Learning Perl 6
brian d foy
 
KEY
Five Languages in a Moment
Sergio Gil
 
PPTX
C to perl binding
Shmuel Fomberg
 
Functional Pearls 4 (YAPC::EU::2009 remix)
osfameron
 
Good Evils In Perl
Kang-min Liu
 
Monads in perl
Masahiro Honma
 
Haskell retrospective
chenge2k
 
Cleancode
hendrikvb
 
Scripting3
Nao Dara
 
Our Friends the Utils: A highway traveled by wheels we didn't re-invent.
Workhorse Computing
 
Modern Perl
Marcos Rebelo
 
Perl slid
pacatarpit
 
Functional Concepts for OOP Developers
brweber2
 
Introduction to Perl - Day 2
Dave Cross
 
Helvetia
ESUG
 
Lecture 3 Perl & FreeBSD administration
Mohammed Farrag
 
Erlang Introduction Bcberlin3
guesta3202
 
Dealing with Legacy Perl Code - Peter Scott
O'Reilly Media
 
Learning Perl 6
brian d foy
 
Five Languages in a Moment
Sergio Gil
 
C to perl binding
Shmuel Fomberg
 
Ad

More from osfameron (11)

PDF
Writing a Tile-Matching Game - FP Style
osfameron
 
PPTX
Data Structures for Text Editors
osfameron
 
PDF
Rewriting the Apocalypse
osfameron
 
PDF
Global Civic Hacking 101 (lightning talk)
osfameron
 
PDF
Adventures in civic hacking
osfameron
 
PDF
Haskell in the Real World
osfameron
 
PDF
Oyster: an incubator for perls in the cloud
osfameron
 
PDF
Semantic Pipes (London Perl Workshop 2009)
osfameron
 
PDF
Functional Pe(a)rls
osfameron
 
PDF
Readable Perl
osfameron
 
PDF
Bigbadwolf
osfameron
 
Writing a Tile-Matching Game - FP Style
osfameron
 
Data Structures for Text Editors
osfameron
 
Rewriting the Apocalypse
osfameron
 
Global Civic Hacking 101 (lightning talk)
osfameron
 
Adventures in civic hacking
osfameron
 
Haskell in the Real World
osfameron
 
Oyster: an incubator for perls in the cloud
osfameron
 
Semantic Pipes (London Perl Workshop 2009)
osfameron
 
Functional Pe(a)rls
osfameron
 
Readable Perl
osfameron
 
Bigbadwolf
osfameron
 
Ad

Recently uploaded (20)

PDF
CIFDAQ Market Insights for July 7th 2025
CIFDAQ
 
PDF
July Patch Tuesday
Ivanti
 
PDF
Fl Studio 24.2.2 Build 4597 Crack for Windows Free Download 2025
faizk77g
 
PPTX
Webinar: Introduction to LF Energy EVerest
DanBrown980551
 
PDF
CIFDAQ Market Wrap for the week of 4th July 2025
CIFDAQ
 
PDF
"Beyond English: Navigating the Challenges of Building a Ukrainian-language R...
Fwdays
 
PDF
Achieving Consistent and Reliable AI Code Generation - Medusa AI
medusaaico
 
PDF
LLMs.txt: Easily Control How AI Crawls Your Site
Keploy
 
PDF
HCIP-Data Center Facility Deployment V2.0 Training Material (Without Remarks ...
mcastillo49
 
PDF
Transcript: New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
PDF
The Rise of AI and IoT in Mobile App Tech.pdf
IMG Global Infotech
 
PDF
Newgen Beyond Frankenstein_Build vs Buy_Digital_version.pdf
darshakparmar
 
PDF
DevBcn - Building 10x Organizations Using Modern Productivity Metrics
Justin Reock
 
PDF
Empower Inclusion Through Accessible Java Applications
Ana-Maria Mihalceanu
 
PDF
From Code to Challenge: Crafting Skill-Based Games That Engage and Reward
aiyshauae
 
PDF
Newgen 2022-Forrester Newgen TEI_13 05 2022-The-Total-Economic-Impact-Newgen-...
darshakparmar
 
PDF
Using FME to Develop Self-Service CAD Applications for a Major UK Police Force
Safe Software
 
PPTX
COMPARISON OF RASTER ANALYSIS TOOLS OF QGIS AND ARCGIS
Sharanya Sarkar
 
PDF
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
PDF
[Newgen] NewgenONE Marvin Brochure 1.pdf
darshakparmar
 
CIFDAQ Market Insights for July 7th 2025
CIFDAQ
 
July Patch Tuesday
Ivanti
 
Fl Studio 24.2.2 Build 4597 Crack for Windows Free Download 2025
faizk77g
 
Webinar: Introduction to LF Energy EVerest
DanBrown980551
 
CIFDAQ Market Wrap for the week of 4th July 2025
CIFDAQ
 
"Beyond English: Navigating the Challenges of Building a Ukrainian-language R...
Fwdays
 
Achieving Consistent and Reliable AI Code Generation - Medusa AI
medusaaico
 
LLMs.txt: Easily Control How AI Crawls Your Site
Keploy
 
HCIP-Data Center Facility Deployment V2.0 Training Material (Without Remarks ...
mcastillo49
 
Transcript: New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
The Rise of AI and IoT in Mobile App Tech.pdf
IMG Global Infotech
 
Newgen Beyond Frankenstein_Build vs Buy_Digital_version.pdf
darshakparmar
 
DevBcn - Building 10x Organizations Using Modern Productivity Metrics
Justin Reock
 
Empower Inclusion Through Accessible Java Applications
Ana-Maria Mihalceanu
 
From Code to Challenge: Crafting Skill-Based Games That Engage and Reward
aiyshauae
 
Newgen 2022-Forrester Newgen TEI_13 05 2022-The-Total-Economic-Impact-Newgen-...
darshakparmar
 
Using FME to Develop Self-Service CAD Applications for a Major UK Police Force
Safe Software
 
COMPARISON OF RASTER ANALYSIS TOOLS OF QGIS AND ARCGIS
Sharanya Sarkar
 
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
[Newgen] NewgenONE Marvin Brochure 1.pdf
darshakparmar
 

Functional Pe(a)rls version 2

  • 1. Functional pe(a)rls London Perl Workshop 29/11/2008 version 2 osfameron
  • 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
  • 3. A sequence 1. (power of 10) * 2.5 2. * 2 3. * 2
  • 4. A sequence without tracking any other state than the number itself
  • 6. A sequence /^1/ # power of 10
  • 7. A sequence cycle [2.5, 2, 2]
  • 8. A sequence cycle [2.5, 2, 2] 2.5 2 2 2.5 ...
  • 9. A sequence Oops! Perl doesn't have infinite sequences
  • 11. A sequence curry cycle (@list) { my @curr = @list; return sub { @curr = @list unless @curr; return shift @curr; }; }
  • 12. A sequence my $c = cycle [2.5, 2, 2];
  • 13. A sequence my $c = cycle [2.5, 2, 2]; say $c->(); # 2.5 say $c->(); # 2 say $c->(); # 2 say $c->(); # 2.5 ...
  • 14. A sequence cycle [2.5, 2, 2];
  • 15. A sequence 10, cycle [2.5, 2, 2];
  • 16. A sequence mult, 10, cycle [2.5, 2, 2];
  • 17. (curry)‏ curry mult ($x,$y) { $x * $y }
  • 18. (curry)‏ say mult( 3, 4 ); # 12
  • 19. (curry)‏ my $triple = mult(3); say $triple->(10); # 30
  • 20. (curry)‏ my $multiply = mult; say $multiply->(6, 8);
  • 21. (curry)‏ my $multiply = \&mult; my $multiply = mult;
  • 22. A sequence mult , 10, cycle [2.5, 2, 2];
  • 23. A sequence scan mult, 10, cycle [2.5, 2, 2];
  • 24. (Scanning)‏ scan add, 1, [2, 3, 4]; # [1, 3, 6, 10]
  • 25. A sequence scan mult, 10, cycle [2.5, 2, 2];
  • 26. A sequence take 12 => scan mult, 10, cycle [2.5, 2, 2];
  • 27. A sequence say for take 12 => scan mult, 10, cycle [2.5, 2, 2];
  • 28. A sequence 10 25 50 100 250 500 ...
  • 29. How? Iterators (HOP)‏ HOP::Stream Lazy variables
  • 30. How? Iterators (HOP)‏ FP (scan, take)‏
  • 31. How? Iterators (HOP)‏ FP (scan, take)‏ Sub::Curried
  • 32. How? Iterators (HOP)‏ FP (scan, take)‏ Sub::Curried Devel::Declare
  • 33. Devel::Declare curry mult ($x,$y) { $x * $y }
  • 34. Devel::Declare New syntax! (But better than source filters)‏
  • 35. Devel::Declare New syntax! (But better than source filters)‏ Method declaration MooseX::Declare Sub::Auto
  • 36. Devel::Declare New syntax! (But better than source filters)‏ Currying Monads Pattern Matching List comprehensions Functions that work on @arrays and lists
  • 37. 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++
  • 40. Monads Come from maths “ Category theory”
  • 41. Monads Come from maths “ Category theory” Very clever people rave about them being useful
  • 42. Monads Come from maths “ Category theory” Very clever people rave about them being useful Have a reputation for being hard to understand
  • 47. Monad tutorials Step 1: Write Monad Tutorial
  • 49. Monad tutorials Step 3: Profit!
  • 50. Monads You already use monads
  • 51. Monads You already use monads YAY!
  • 52. Monads You already use monads Sequences of commands?
  • 53. Sequencing my $x = 1; my $y = 2; my $z = $x * $y; say “$x * $y = $z”;
  • 54. Sequencing my $x = 1; my $y = 2; my $z = $x * $y; say “$x * $y = $z”;
  • 55. Sequencing my $x = 1; my $y = 2; my $z = $x * $y; say “$x * $y = $z”;
  • 56. Sequencing my @seq = sub { my $x = 1 }, sub { my $y = 2 }, sub { my $z = $x * $y }, sub { say &quot;$x * $y = $z&quot; };
  • 57. 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 ...
  • 58. Nesting my $x = 1; my $y = 2; my $z = $x * $y; say “$x * $y = $z”;
  • 59. Nesting sub { my $x = 1; sub { my $y = 2; sub { my $z = $x * $y; sub { say &quot;$x * $y = $z&quot;; }->() }->() }->() }->();
  • 60. Monads made pretty Source filters! http://sleepingsquirrel.org/monads/monads.html
  • 61. Monads made pretty Source filters! http://sleepingsquirrel.org/monads/monads.html Source tree manipulation (B::OP magic)‏ Deparse and source text munging
  • 62. 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”; }
  • 63. 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
  • 64. 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
  • 65. 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
  • 66. Source deparsing Works surprisingly well
  • 67. Source deparsing Works surprisingly well for trivial cases (a bit fragile)‏
  • 68. Source deparsing Works surprisingly well for trivial cases (a bit fragile)‏ though localised to mdo { ... }
  • 69. Devel::Declare Even nicer syntax mdo { mbind $x = 1; mbind $y = 2; mbind $z = $x + $y; say “$x * $y = $z”; }
  • 70. Devel::Declare And cuter implementation: mdo { mbind $x = 1; mbind $y = 2; mbind $z = $x + $y; say “$x * $y = $z”; }
  • 71. 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”; } ...
  • 72. Devel::Declare No need to count nesting: scope_inject Scope::Guard Use to inject a ; at the end of method declarations: method foo ($x) { print $x; } # look Ma, no semicolon!
  • 73. 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 }
  • 74. 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 }
  • 75. 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 }
  • 76. 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
  • 77. So... We can now sequence commands! mdo { mbind $x = 1; mbind $y = 2; mbind $z = $x + $y; say “$x * $y = $z”; }
  • 78. So... We can now sequence commands! YAY?
  • 79. So... We can now sequence commands! OK, so this was big news in Haskell in 1990s
  • 80. So... We can now sequence commands! OK, so this was big news in Haskell in 1990s Imperative languages have always done this
  • 81. What else can monads do ? Sequencing mdo { mbind $x = 1; mbind $y = 2; mbind $z = $x + $y; say “$x * $y = $z”; }
  • 82. What else can monads do ? Sequencing mdo { mbind $x = 1; mbind $y = 2; mbind $z = $x + $y; say “$x * $y = $z”; }
  • 83. What else can monads do ? Sequencing mdo { mbind $x = 1 ; mbind $y = 2 ; mbind $z = $x + $y ; say “$x * $y = $z”; }
  • 84. What else can monads do ? Sequencing mdo { mbind $x = 1 ; mbind $y = 2 ; mbind $z = $x + $y ; say “$x * $y = $z”; } Programmable semicolon!
  • 85. Maybe Success/Failure mdo (Maybe) { mbind $FH = m_open('<', $file) ; mbind $line = <$FH> ; mbind $val = lookup(\%h, $line) ; say “Found $val!”; }
  • 86. 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
  • 87. 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 { ... }
  • 88. Maybe $FH = open($file)‏ $line = <$FH> $val = lookup ( $line )‏ say “Found $val”
  • 89. Maybe $FH = open($file)‏ $line = <$FH> $val = lookup ( $line )‏ say “Found $val”
  • 93. List $x = [1..10] $y = [1..10] guard $x+$y == 10 say “$x+$y=10”
  • 94. 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
  • 95. 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 ...
  • 96. 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
  • 97. List comprehension More compact syntax mcomp ($x <- [1..10]; $y <- [1..10]; $x+y==10) { say “$x+$y=10” }
  • 98. 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
  • 99. 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
  • 100. Perl++ Not really a functional language... But you can take it surprisingly far (CPAN++)‏
  • 101. What else can I do with monads? Parsing Error handling SQL generation Continuations (real resumable ones)‏
  • 102. Wants monads now! Techniques are valuable now Nicely wrapped implementation will be ready soon....