Slide 1

Slide 1 text

Reactive Programming
 in Perl6 Shoichi Kaji

Slide 2

Slide 2 text

Me • Shoichi Kaji • pause/github: skaji • Perl5: cpm, App::FatPacker::Simple, Mojo::SlackRTM • Perl6: mi6, Frinfon, evalbot in Slack

Slide 3

Slide 3 text

Perl6ʹ Plack͸͋Δͷ?

Slide 4

Slide 4 text

Yes

Slide 5

Slide 5 text

Crust https://github.com/tokuhirom/p6-Crust

Slide 6

Slide 6 text

$ crustup -e '-> $e {200, [], ["hello world"]}' http server is ready: http://127.0.0.1:5000/ $ curl http://localhost:5000 hello world

Slide 7

Slide 7 text

# app.p6 use v6; use Frinfon; get "/" => sub ($c) { $c.render-text("hello world\n"); }; get "/:user" => sub ($c) { my $user = $c.captured; $c.render-json: { message => "hello $user!" }; }; app; $ crustup app.p6 http server is ready: http://127.0.0.1:5000/ minimal sinatra΋͋Δ

Slide 8

Slide 8 text

ͱ͜ΖͰ

Slide 9

Slide 9 text

Perl6ͱPerl5ͷ ໌֬ͳҧ͍͸ʁ

Slide 10

Slide 10 text

Perl6͸૊ΈࠐΈͰ ฒߦɾඇಉظϓϩάϥϛϯάΛ αϙʔτ͍ͯ͠Δ

Slide 11

Slide 11 text

ΞδΣϯμ • Perl6ͰϦΞΫςΟϒϓϩάϥϛϯά͕Ͱ͖Δʁ • ͦ΋ͦ΋ϦΞΫςΟϒϓϩάϥϛϯάͬͯʁ • ྫ • Perl6Ͱ͸ ετϦʔϜ = Supply • Supplyৄࡉ • ࣮͢͜͠ફతͳྫ • Perl-ish • ݁࿦

Slide 12

Slide 12 text

Perl6ͰϦΞΫςΟϒϓ ϩάϥϛϯά͕Ͱ͖Δʁ

Slide 13

Slide 13 text

Ͱ͖Δ

Slide 14

Slide 14 text

ϦΞΫςΟϒ ϓϩάϥϛϯάͬͯʁ • ࢀߟURL • (A) ͳͥϦΞΫςΟϒϓϩάϥϛϯά͸ॏཁ͔ɻhttp://d.hatena.ne.jp/ pokarim/20101226 • (B) The introduction to Reactive Programming you've been missing https://gist.github.com/staltz/868e7e9bc2a7b8c1f754 • (C) What is (functional) reactive programming? http:// stackoverflow.com/questions/1028250/what-is-functional-reactive- programming • ͜ΕΒʹΑΔͱϦΞΫςΟϒϓϩάϥϛϯάͱ͸
 ࣌ؒͱͱ΋ʹมԽ͠͏Δ஋ = ࣌ؒॱʹฒΜͩΠϕϯτͷྻ = ετϦʔϜ
 Λத৺ʹͦ͑ͯϓϩάϥϛϯά͢Δ͜ͱɻ

Slide 15

Slide 15 text

࣍ͷࣜΛߟ͑Δɻ a=2Ͱb=3͔ͩΒɺc=2+3=5Ͱ͋Δɻ ͯ͞গ͕࣌ؒ͠ܦ͔ͬͯΒa=6ͱ୅ೖͯ͠΋
 ΋ͪΖΜc͸มΘΒͣ5ͷ··Ͱ͋Δɻ ͜͜ͰϦΞΫςΟϒϓϩάϥϛϯάͷཱ৔ʹཱͬͯ ߟ͑Δͱɺa=6ʹม͑ͨͱ͖c͸9ʹͳΔɻ ྫ a = 2 b = 3 c = a + b

Slide 16

Slide 16 text

͢ͳΘͪϦΞΫςΟϒϓϩάϥϛϯάͷཱ৔Ͱ͸ a,b,cΛ࣌ؒͱͱ΋ʹมԽ͠͏Δ஋=ετϦʔϜͱ ଊ͑Δɻઌ΄ͲͷࣜΛ΋͏গ͠આ໌తʹॻ͘ͱ ྫ a = ࣌ؒͱͱ΋ʹมԽ͠͏Δ஋Ͱॳظ஋2ɺগ͔ͯ͠͠Β6ʹมԽ b = ࣌ؒͱͱ΋ʹมԽ͠͏Δ஋Ͱॳظ஋3 c = ࣌ؒͱͱ΋ʹมԽ͠͏Δaͱbͷ࿨ a b c ԣ͸࣌ؒ࣠ ࿨ 2 5 3 6 9

Slide 17

Slide 17 text

΋͏Ұ౓ॻ͘ͱɺϦΞΫςΟϒϓϩάϥϛϯάͱ͸ ԼهͷΑ͏ͳετϦʔϜΛத৺ਓ෺ͱͯ͠ ϓϩάϥϛϯά͢Δख๏ͷ͜ͱɻ ࣮ࡍʹ͸ɺͦͷετϦʔϜʹର͠ * ෳ਺ͷετϦʔϜͷmerge,zip,combineLatest * ετϦʔϜͷfilter, map * ετϦʔϜΛsubscribe͢Δ ͳͲͷૢ࡞Λͯ͠ϓϩάϥϛϯά͍ͯ͘͠

Slide 18

Slide 18 text

Perl6Ͱ͸ετϦʔϜ=Supply • Perl6Ͱ͸Supplyܕ͕ετϦʔϜʹରԠ͢Δ • ྫ • γάφϧ͸Supplyͱͯ͠ఏڙ͞ΕΔ • ֎෦ίϚϯυͷstdout/err͕Supplyͱͯ͠ఏڙ͞ΕΔ my $signal-supply = signal(SIGINT); say $signal-supply ~~ Supply; # True my $proc = Proc::Async.new("dstat"); say $proc.stdout ~~ Supply; # True

Slide 19

Slide 19 text

Supplyৄࡉ - ࡞Γํ # ϑΝΠϧγεςϜͷมߋ௨஌Supply my $fs-supply = IO::Notification.watch-path(%*ENV); # 10ඵ͝ͱʹeventΛemit͢ΔSupply my $interval-supply = Supply.interval(10); # supplyϒϩοΫͰࣗ෼Ͱ࡞Δ͜ͱ΋Մೳ my $supply = supply { emit "value1"; sleep 1; emit "value2"; };

Slide 20

Slide 20 text

Supplyৄࡉ - ૢ࡞ • ઌ΄ͲετϦʔϜͷૢ࡞ͱͯ͠filter, mapΛڍ͛ ͨɻPerl6ͩͱgrep, mapͰͰ͖Δɻ # dotfileΛൈ͍ͨSupply my $not-dotfiles = IO::Notification.watch-path(%*ENV).grep: -> $e { $e.path.IO.basename !~~ /^'.'/; }; # 10ඵ͝ͱʹ࣌ࠁΛemit͢ΔSupply my $time-supply = Supply.interval(10).map({DateTime.now});

Slide 21

Slide 21 text

Supplyৄࡉ - ૢ࡞ • ઌ΄ͲετϦʔϜΛsubscribe͢Δͱड़΂ͨɻ Perl6Ͱ͸tapɻtapͰɺSupplyʹ஋͕emit͞Ε ͨͱ͖ͷಈ࡞Λొ࿥Ͱ͖Δɻ my $signal = signal(SIGTERM); $signal.tap: -> $v { note "catch $v" };

Slide 22

Slide 22 text

Supplyৄࡉ - ૢ࡞ • ઌ΄Ͳෳ਺ͷετϦʔϜͷૢ࡞ͱͯ͠merge, zip,combineLatestΛڍ͛ͨɻPerl6ͩͱmerge, zip,zip-latestͰ͖Δɻ Supply.merge($supply1, $supply2); Supply.zip($supply1, $supply2); Supply.zip-latest($supply1, $supply2);

Slide 23

Slide 23 text

࣮͢͜͠ફతͳྫ • tail -f͸ϑΝΠϧʹ௥ه͞ΕΔͱ஋(จࣈྻ)͕ emit͞ΕΔͨΊετϦʔϜ=Supplyͱͯ͠ଊ͑ ΒΕΔ • ࡞ͬͨ
 https://github.com/skaji/perl6-tail • ͜ͷperl6-tailΛ࢖ͬͯΈΔ

Slide 24

Slide 24 text

use IO::TailFile; my $tail = IO::TailFile.watch("access.log", :chomp); access.logΛtail

Slide 25

Slide 25 text

ࣾ಺͔ΒͷΞΫηεΛআ͖ 1෼͝ͱʹrequest/secΛग़͢ -> ΋ͬͱ͍͍ॻ͖ํ͕͋Δ͸ͣ use IO::TailFile; my $count = 0; my $promise = Promise.new; my $tail = IO::TailFile.watch("access.log", :chomp) .grep(-> $line { $line !~~ / '192.168' / }) .map(-> $line { 1 }); $tail.tap: -> $i { $count += $i }, done => { $promise.keep(Nil) }; my $interval = Supply.interval(60); $interval.tap: -> $v { say "rps " ~ ($count / 60); $count = 0 }; await $promise;

Slide 26

Slide 26 text

Perl-ish

Slide 27

Slide 27 text

use v6; use IO::TailFile; my $tail = IO::TailFile.watch("access.log"); # infinite list! my @line = $tail.list.lazy; for @line -> $line { # ... } # react, whenever block! react { whenever $tail -> $line { # ... }; whenever Supply.ineterval(10) { # ... }; };

Slide 28

Slide 28 text

݁࿦ • ϦΞΫςΟϒϓϩάϥϛϯάͱ͸ετϦʔϜΛ த৺ͱͯ͠ϓϩάϥϛϯά͢Δख๏ • Perl6Ͱ͸ ετϦʔϜ = Supply • Supplyͷϝιου͸ͦΖ͓ͬͯΓ
 Perl6ͰϦΞΫςΟϒϓϩάϥϛϯά͍͚Δ!
 (ଟ෼)