Your SlideShare is downloading. ×
0
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Functional Pe(a)rls version 2

2,195

Published on

Some techniques from the heady world of Functional Programming implemented in idiomatic Perl using various techniques: closures, iterators, Devel::Declare, and some distilled evil. New version now …

Some techniques from the heady world of Functional Programming implemented in idiomatic Perl using various techniques: closures, iterators, Devel::Declare, and some distilled evil. New version now with monads! (As presented at http://conferences.yapceurope.org/lpw2008/ )

Published in: Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,195
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
41
Comments
0
Likes
2
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Functional pe(a)rls <ul><ul><li>London Perl Workshop </li></ul></ul><ul><ul><li>29/11/2008 </li></ul></ul><ul><ul><li>version 2 </li></ul></ul><ul><ul><li>osfameron </li></ul></ul>
  • 2. A sequence <ul><li>Debolaz, on #moose </li></ul><ul><li>a list of numbers like </li></ul><ul><ul><li>10, 25, 50, </li></ul></ul><ul><ul><li>100, 250, 500, </li></ul></ul><ul><ul><li>1000, etc </li></ul></ul><ul><li>without tracking any other state than the number itself </li></ul>
  • 3. A sequence <ul><li>1. (power of 10) * 2.5 </li></ul><ul><li>2. * 2 </li></ul><ul><li>3. * 2 </li></ul>
  • 4. A sequence <ul><ul><li>without tracking any other state than the number itself </li></ul></ul>
  • 5. A sequence <ul><ul><li>/^1/ </li></ul></ul>
  • 6. A sequence <ul><ul><li>/^1/ # power of 10 </li></ul></ul>
  • 7. A sequence <ul><li>cycle [2.5, 2, 2] </li></ul>
  • 8. A sequence <ul><li>cycle [2.5, 2, 2] </li></ul><ul><ul><li>2.5 </li></ul></ul><ul><ul><li>2 </li></ul></ul><ul><ul><li>2 </li></ul></ul><ul><ul><li>2.5 </li></ul></ul><ul><ul><li>... </li></ul></ul>
  • 9. A sequence <ul><li>Oops! </li></ul><ul><li>Perl doesn't have infinite sequences </li></ul>
  • 10. A sequence <ul><ul><li>Iterators </li></ul></ul>
  • 11. A sequence <ul><ul><li>curry cycle (@list) { </li></ul></ul><ul><ul><li>my @curr = @list; </li></ul></ul><ul><ul><li>return sub { </li></ul></ul><ul><ul><li>@curr = @list </li></ul></ul><ul><ul><li>unless @curr; </li></ul></ul><ul><ul><li>return shift @curr; </li></ul></ul><ul><ul><li>}; </li></ul></ul><ul><ul><li>} </li></ul></ul>
  • 12. A sequence <ul><li>my $c = cycle [2.5, 2, 2]; </li></ul>
  • 13. A sequence <ul><li>my $c = cycle [2.5, 2, 2]; </li></ul><ul><ul><li>say $c->(); # 2.5 </li></ul></ul><ul><ul><li>say $c->(); # 2 </li></ul></ul><ul><ul><li>say $c->(); # 2 </li></ul></ul><ul><ul><li>say $c->(); # 2.5 </li></ul></ul><ul><ul><li>... </li></ul></ul>
  • 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)‏ <ul><ul><li>curry mult ($x,$y) { </li></ul></ul><ul><ul><li>$x * $y </li></ul></ul><ul><ul><li>} </li></ul></ul>
  • 18. (curry)‏ <ul><ul><li>say mult( 3, 4 ); </li></ul></ul><ul><ul><li># 12 </li></ul></ul>
  • 19. (curry)‏ <ul><ul><li>my $triple = mult(3); </li></ul></ul><ul><ul><li>say $triple->(10); </li></ul></ul><ul><ul><li># 30 </li></ul></ul>
  • 20. (curry)‏ <ul><ul><li>my $multiply = mult; </li></ul></ul><ul><ul><li>say $multiply->(6, 8); </li></ul></ul>
  • 21. (curry)‏ <ul><ul><li>my $multiply = &mult; </li></ul></ul><ul><ul><li>my $multiply = mult; </li></ul></ul>
  • 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 <ul><li>10 </li></ul><ul><li>25 </li></ul><ul><li>50 </li></ul><ul><li>100 </li></ul><ul><li>250 </li></ul><ul><li>500 </li></ul><ul><li>... </li></ul>
  • 29. How? <ul><li>Iterators (HOP)‏ </li></ul><ul><ul><li>HOP::Stream </li></ul></ul><ul><ul><li>Lazy variables </li></ul></ul>
  • 30. How? <ul><li>Iterators (HOP)‏ </li></ul><ul><li>FP (scan, take)‏ </li></ul>
  • 31. How? <ul><li>Iterators (HOP)‏ </li></ul><ul><li>FP (scan, take)‏ </li></ul><ul><li>Sub::Curried </li></ul>
  • 32. How? <ul><li>Iterators (HOP)‏ </li></ul><ul><li>FP (scan, take)‏ </li></ul><ul><li>Sub::Curried </li></ul><ul><li>Devel::Declare </li></ul>
  • 33. Devel::Declare <ul><ul><li>curry mult ($x,$y) { </li></ul></ul><ul><ul><li>$x * $y </li></ul></ul><ul><ul><li>} </li></ul></ul>
  • 34. Devel::Declare <ul><li>New syntax! </li></ul><ul><li>(But better than source filters)‏ </li></ul>
  • 35. Devel::Declare <ul><li>New syntax! </li></ul><ul><li>(But better than source filters)‏ </li></ul><ul><ul><li>Method declaration </li></ul></ul><ul><ul><li>MooseX::Declare </li></ul></ul><ul><ul><li>Sub::Auto </li></ul></ul>
  • 36. Devel::Declare <ul><li>New syntax! </li></ul><ul><li>(But better than source filters)‏ </li></ul><ul><ul><li>Currying </li></ul></ul><ul><ul><li>Monads </li></ul></ul><ul><ul><li>Pattern Matching </li></ul></ul><ul><ul><li>List comprehensions </li></ul></ul><ul><ul><li>Functions that work on @arrays and lists </li></ul></ul>
  • 37. Devel::Declare <ul><li>In Perl! </li></ul><ul><li>(With a bit of scary XS magic)‏ </li></ul><ul><ul><li>hooks into the compiler </li></ul></ul><ul><ul><li>changing the source as you compile </li></ul></ul><ul><ul><li>horrible perl tricks to get methods installed, and braces closed </li></ul></ul><ul><ul><li>mst++, rafl++ </li></ul></ul>
  • 38. Some light relief
  • 39. Some light relief Monads
  • 40. Monads <ul><li>Come from maths </li></ul><ul><li>“ Category theory” </li></ul>
  • 41. Monads <ul><li>Come from maths </li></ul><ul><li>“ Category theory” </li></ul><ul><li>Very clever people rave about them being useful </li></ul>
  • 42. Monads <ul><li>Come from maths </li></ul><ul><li>“ Category theory” </li></ul><ul><li>Very clever people rave about them being useful </li></ul><ul><li>Have a reputation for being hard to understand </li></ul>
  • 43. Monad tutorials
  • 44. Monad tutorials
  • 45. Monad tutorials
  • 46. Monad tutorials
  • 47. Monad tutorials Step 1: Write Monad Tutorial
  • 48. Monad tutorials Step 2: ???
  • 49. Monad tutorials Step 3: Profit!
  • 50. Monads <ul><li>You already use monads </li></ul>
  • 51. Monads <ul><li>You already use monads </li></ul><ul><li>YAY! </li></ul>
  • 52. Monads <ul><li>You already use monads </li></ul><ul><li>Sequences of commands? </li></ul>
  • 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 <ul><li>Source filters! </li></ul><ul><ul><li>http://sleepingsquirrel.org/monads/monads.html </li></ul></ul>
  • 61. Monads made pretty <ul><li>Source filters! </li></ul><ul><ul><li>http://sleepingsquirrel.org/monads/monads.html </li></ul></ul><ul><li>Source tree manipulation (B::OP magic)‏ </li></ul><ul><li>Deparse and source text munging </li></ul>
  • 62. Monads made pretty <ul><li>We want a syntax like </li></ul><ul><li>mdo { my $x = mbind(1); my $y = mbind(2); my $z = mbind($x + $y); say “$x * $y = $z”; } </li></ul>
  • 63. Monads made pretty <ul><li>We want a syntax like </li></ul><ul><li>mdo { my $x = mbind(1); my $y = mbind(2); my $z = mbind($x + $y); say “$x * $y = $z”; } </li></ul><ul><li>mdo introduces the block </li></ul><ul><li>mbind gives us a hook to rotate around </li></ul>
  • 64. Optree munging <ul><li>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 </li></ul><ul><li># : 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 </li></ul>
  • 65. Optree munging <ul><li>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 </li></ul><ul><li># : 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 </li></ul>KABOOM
  • 66. Source deparsing <ul><li>Works surprisingly well </li></ul>
  • 67. Source deparsing <ul><li>Works surprisingly well </li></ul><ul><li>for trivial cases </li></ul><ul><li>(a bit fragile)‏ </li></ul>
  • 68. Source deparsing <ul><li>Works surprisingly well </li></ul><ul><li>for trivial cases </li></ul><ul><li>(a bit fragile)‏ </li></ul><ul><li>though localised to mdo { ... } </li></ul>
  • 69. Devel::Declare <ul><li>Even nicer syntax </li></ul><ul><li>mdo { mbind $x = 1; mbind $y = 2; mbind $z = $x + $y; say “$x * $y = $z”; } </li></ul>
  • 70. Devel::Declare <ul><li>And cuter implementation: </li></ul><ul><li>mdo { mbind $x = 1; mbind $y = 2; mbind $z = $x + $y; say “$x * $y = $z”; } </li></ul>
  • 71. Devel::Declare <ul><li>The problem: </li></ul><ul><li>mdo { mbind 1, sub { my $x = shift; mbind 2, sub { my $y = shift; mbind $x + $y, sub { my $z = shift; say “$x * $y = $z”; } ... </li></ul>
  • 72. Devel::Declare <ul><li>No need to count nesting: </li></ul><ul><li>scope_inject </li></ul><ul><li>Scope::Guard </li></ul><ul><li>Use to inject a ; at the end of method declarations: </li></ul><ul><li>method foo ($x) { print $x; } # look Ma, no semicolon! </li></ul>
  • 73. Devel::Declare <ul><li>mbind's scope_inject adds a “}” </li></ul><ul><li>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 } </li></ul>
  • 74. Devel::Declare <ul><li>mbind's scope_inject adds a “}” </li></ul><ul><li>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 } </li></ul>
  • 75. Devel::Declare <ul><li>mbind's scope_inject adds a “}” </li></ul><ul><li>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 } </li></ul>
  • 76. Devel::Declare <ul><li>mbind's scope_inject adds a “}” </li></ul><ul><li>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 </li></ul>
  • 77. So... <ul><li>We can now sequence commands! </li></ul><ul><li>mdo { mbind $x = 1; mbind $y = 2; mbind $z = $x + $y; say “$x * $y = $z”; } </li></ul>
  • 78. So... <ul><li>We can now sequence commands! </li></ul><ul><li>YAY? </li></ul>
  • 79. So... <ul><li>We can now sequence commands! </li></ul><ul><li>OK, so this was big news in Haskell in 1990s </li></ul>
  • 80. So... <ul><li>We can now sequence commands! </li></ul><ul><li>OK, so this was big news in Haskell in 1990s </li></ul><ul><li>Imperative languages have always done this </li></ul>
  • 81. What else can monads do ? <ul><li>Sequencing </li></ul><ul><li>mdo { mbind $x = 1; mbind $y = 2; mbind $z = $x + $y; say “$x * $y = $z”; } </li></ul>
  • 82. What else can monads do ? <ul><li>Sequencing </li></ul><ul><li>mdo { mbind $x = 1; mbind $y = 2; mbind $z = $x + $y; say “$x * $y = $z”; } </li></ul>
  • 83. What else can monads do ? <ul><li>Sequencing </li></ul><ul><li>mdo { mbind $x = 1 ; mbind $y = 2 ; mbind $z = $x + $y ; say “$x * $y = $z”; } </li></ul>
  • 84. What else can monads do ? <ul><li>Sequencing </li></ul><ul><li>mdo { mbind $x = 1 ; mbind $y = 2 ; mbind $z = $x + $y ; say “$x * $y = $z”; } </li></ul><ul><li>Programmable semicolon! </li></ul>
  • 85. Maybe <ul><li>Success/Failure </li></ul><ul><li>mdo (Maybe) { mbind $FH = m_open('<', $file) ; mbind $line = <$FH> ; mbind $val = lookup(h, $line) ; say “Found $val!”; } </li></ul>
  • 86. Maybe <ul><li>Success/Failure </li></ul><ul><li>mdo (Maybe) { mbind $FH = m_open('<', $file) ; mbind $line = <$FH> ; mbind $val = lookup(h, $line) ; say “Found $val!”; } </li></ul><ul><li>Will give up if can't open file, read a line from it, or look it up in a hash </li></ul>
  • 87. Maybe <ul><li>Success/Failure </li></ul><ul><li>mdo (Maybe) { mbind $FH = m_open('<', $file) ; mbind $line = <$FH> ; mbind $val = lookup(h, $line) ; say “Found $val!”; } </li></ul><ul><li>Compare chain of if (foo) { if (bar) { ... </li></ul><ul><li>or eval { ... } </li></ul>
  • 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”
  • 90. Sequence
  • 91. Maybe ? ? ?
  • 92. Multiple (List)‏
  • 93. List $x = [1..10] $y = [1..10] guard $x+$y == 10 say “$x+$y=10”
  • 94. List <ul><li>Cartesian product </li></ul><ul><li>mdo { mbind $x = [1..10] ; mbind $y = [1..10] ; mbind guard $x+$y == 10 ; say “$x+$y=10”; } </li></ul><ul><li>Run every $x against every $y and filter </li></ul>
  • 95. List <ul><li>Cartesian product </li></ul><ul><li>mdo { mbind $x = [1..10] ; mbind $y = [1..10] ; mbind guard $x+$y == 10 ; say “$x+$y=10”; } </li></ul><ul><li>1+9=10 </li></ul><ul><li>2+8=10 </li></ul><ul><li>... </li></ul>
  • 96. List <ul><li>Cartesian product </li></ul><ul><li>mdo { mbind $x = [1..10] ; mbind $y = [1..10] ; mbind guard $x+$y == 10 ; say “$x+$y=10”; } </li></ul><ul><li>just like SQL </li></ul><ul><li>or LINQ </li></ul>
  • 97. List comprehension <ul><li>More compact syntax </li></ul><ul><li>mcomp ($x <- [1..10]; $y <- [1..10]; $x+y==10) { say “$x+$y=10” } </li></ul>
  • 98. List <ul><li>mdo { mbind $x = [1..10] ; mbind $y = [1..10] ; mbind guard $x+$y == 10; say “$x+$y=10”; } </li></ul><ul><li>We're actually calling mbind on a list </li></ul>
  • 99. List <ul><li>mdo { mbind $x = [1..10] ; mbind $y = [1..10] ; mbind guard $x+$y == 10; say “$x+$y=10”; } </li></ul><ul><li>We're actually calling mbind on a list </li></ul><ul><li>autobox </li></ul>
  • 100. Perl++ <ul><li>Not really a functional language... </li></ul><ul><li>But you can take it surprisingly far </li></ul><ul><li>(CPAN++)‏ </li></ul>
  • 101. What else can I do with monads? <ul><li>Parsing </li></ul><ul><li>Error handling </li></ul><ul><li>SQL generation </li></ul><ul><li>Continuations (real resumable ones)‏ </li></ul>
  • 102. Wants monads now! <ul><li>Techniques are valuable now </li></ul><ul><li>Nicely wrapped implementation will be ready soon.... </li></ul>
  • 103. Thanks! <ul><li>questions? </li></ul>

×