"What Does Your Code Smell Like?"で学ぶPerl6

46
"What Does Your Code Smell Like?" で学ぶPerl6 by risou at yokohama.pm #9

description

2012/10/19 at Yokohama.pm #9

Transcript of "What Does Your Code Smell Like?"で学ぶPerl6

Page 1: "What Does Your Code Smell Like?"で学ぶPerl6

"What Does Your Code Smell Like?"で学ぶPerl6

by risouat yokohama.pm #9

Page 2: "What Does Your Code Smell Like?"で学ぶPerl6

はじめに

• 今回は Perl6 のお話をします• Perl6 に興味のない方は、15分の休憩と思ってゆっくりしてください。

Page 3: "What Does Your Code Smell Like?"で学ぶPerl6

YAPCお疲れ様でした

•面白くてタメになるトークがたくさん

•懇親会の美味しい料理

• LTthonのすごい盛り上がり

• etc...

Page 4: "What Does Your Code Smell Like?"で学ぶPerl6

ところで

Page 5: "What Does Your Code Smell Like?"で学ぶPerl6

Larry のトーク聴きましたか?

Page 6: "What Does Your Code Smell Like?"で学ぶPerl6
Page 7: "What Does Your Code Smell Like?"で学ぶPerl6

What Does Your Code Smell Like?

• strand sort を行うプログラム

• Perl5 のコードを Perl6 のコードへ

Page 8: "What Does Your Code Smell Like?"で学ぶPerl6

use 5.10.0; # for given/whensub merge { my ($x, $y) = @_; my @out; while (@$x and @$y) { given ($x->[-1] <=> $y->[-1]) { when( 1) { unshift @out, pop @$x } when(-1) { unshift @out, pop @$y } default { splice @out, 0, 0, pop(@$x), pop(@$y) } } } return @$x, @$y, @out}

sub strand { my $x = shift; my @out = shift @$x // return; if (@$x) { for (-@$x .. -1) { if ($x->[$_] >= $out[-1]) { push @out, splice @$x, $_, 1 } } } return @out}

sub strand_sort { my @x = @_; my @out; while (my @strand = strand(\@x)) { @out = merge(\@out, \@strand) } @out}

my @a = map (int rand(100), 1 .. 10);say "Before @a";@a = strand_sort(@a);say "After @a";

Page 9: "What Does Your Code Smell Like?"で学ぶPerl6

sub infix:<M> (@x is rw, @y is rw) { gather { while @x and @y { given @x[0] cmp @y[0] { when Increase { take @x.shift } when Decrease { take @y.shift } when Same { take @x.shift, @y.shift } } } take @x, @y }}

sub strand (@x is rw) { my $prev = -Inf; my $i = 0; gather while $i < @x { if @x[$i] before $prev { $i++; } else { take $prev = @x.splice($i, 1)[0]; } }}

sub strand_sort (@x is copy) { my @out; @out M= strand(@x) while @x; @out}

my @a = (^100).roll(10);say "Before @a[]";@a = strand_sort(@a);say "After @a[]";

@a = <The quick brown fox jumps over the lazy dog>;say "Before @a[]";@a = strand_sort(@a);say "After @a[]";

Page 10: "What Does Your Code Smell Like?"で学ぶPerl6

今回のお話

• “What Does Your Code Smell Like?”を元に Perl6 を紹介します

•(時間の都合で)全部は紹介しません

Page 11: "What Does Your Code Smell Like?"で学ぶPerl6

文法の違い

Page 12: "What Does Your Code Smell Like?"で学ぶPerl6

merge関数

sub merge { my ($x, $y) = @_; my @out; while (@$x and @$y) { given ($x->[-1] <=> $y->[-1]) { when( 1) { unshift @out, pop @$x } when(-1) { unshift @out, pop @$y } default { splice @out, 0, 0, pop(@$x), pop(@$y) } } } return @$x, @$y, @out}

Page 13: "What Does Your Code Smell Like?"で学ぶPerl6

シンタックスハイライトを変更

sub merge { my ($x, $y) = @_; my @out; while (@$x and @$y) { given ($x->[-1] <=> $y->[-1]) { when( 1) { unshift @out, pop @$x } when(-1) { unshift @out, pop @$y } default { splice @out, 0, 0, pop(@$x), pop(@$y) } } } return @$x, @$y, @out}

Page 14: "What Does Your Code Smell Like?"で学ぶPerl6

引数の受取り方が変わる

sub merge ($x, $y) {# my ($x, $y) = @_; my @out; while (@$x and @$y) { given ($x->[-1] <=> $y->[-1]) { when( 1) { unshift @out, pop @$x } when(-1) { unshift @out, pop @$y } default { splice @out, 0, 0, pop(@$x), pop(@$y) } } } return @$x, @$y, @out}

Page 15: "What Does Your Code Smell Like?"で学ぶPerl6

不要な括弧を除去

sub merge ($x, $y) {# my ($x, $y) = @_; my @out; while @$x and @$y { given $x->[-1] <=> $y->[-1] { when 1 { unshift @out, pop @$x } when -1 { unshift @out, pop @$y } default { splice @out, 0, 0, pop(@$x), pop(@$y) } } } return @$x, @$y, @out}

Page 16: "What Does Your Code Smell Like?"で学ぶPerl6

全ての変数がリファンレス

sub merge (@x, @y) {# my ($x, $y) = @_; my @out; while @x and @y { given $x[-1] <=> $y[-1] { when 1 { unshift @out, pop @x } when -1 { unshift @out, pop @y } default { splice @out, 0, 0, pop(@x), pop(@y) } } } return @x, @y, @out}

Page 17: "What Does Your Code Smell Like?"で学ぶPerl6

strand関数

sub strand { my $x = shift; my @out = shift @$x // return; if (@$x) { for (-@$x .. -1) { if ($x->[$_] >= $out[-1]) { push @out, splice @$x, $_, 1 } } } return @out}

Page 18: "What Does Your Code Smell Like?"で学ぶPerl6

シンタックスハイライトを変更

sub strand { my $x = shift; my @out = shift @$x // return; if (@$x) { for (-@$x .. -1) { if ($x->[$_] >= $out[-1]) { push @out, splice @$x, $_, 1 } } } return @out}

Page 19: "What Does Your Code Smell Like?"で学ぶPerl6

既に説明した変更を適用

sub strand (@x) { my @out = shift @x // return; if @x { for -@x .. -1 { if (@x[$_] >= @out[-1]) { push @out, splice @x, $_, 1 } } } return @out}

Page 20: "What Does Your Code Smell Like?"で学ぶPerl6

配列の添字にマイナスは使えない

sub strand (@x) { my @out = shift @x // return; if @x { for -@x .. -1 { if (@x[*+$_] >= @out[*-1]) { push @out, splice @x, *+$_, 1 } } } return @out}

Page 21: "What Does Your Code Smell Like?"で学ぶPerl6

範囲指定時の ^

sub strand (@x) { my @out = shift @x // return; if @x { for 0 ..^ @x { if (@x[$_] >= @out[*-1]) { push @out, splice @x, $_, 1 } } } return @out}

Page 22: "What Does Your Code Smell Like?"で学ぶPerl6

変更点まとめ

• 引数の受取り方が変わった• if, while 等の条件指定時に括弧が不要• 全ての変数がリファレンスに• 配列の添字に負数は使えない→代わりに whatever(*) を使う

• 範囲指定の .. に ^ をつけると、その値を除外( 0 ^..^ 3 => 1, 2 )

Page 23: "What Does Your Code Smell Like?"で学ぶPerl6

見慣れないキーワード

Page 24: "What Does Your Code Smell Like?"で学ぶPerl6

見慣れないものたち

sub infix:<M> (@x is rw, @y is rw) { gather { while @x and @y { given @x[0] cmp @y[0] { when Increase { take @x.shift } when Decrease { take @y.shift } when Same { take @x.shift, @y.shift } } } take @x, @y }}

Page 25: "What Does Your Code Smell Like?"で学ぶPerl6

infix:<M>

Page 26: "What Does Your Code Smell Like?"で学ぶPerl6

infix:<***>

•いわゆる中置演算子の定義

•引数を2つとる

Page 27: "What Does Your Code Smell Like?"で学ぶPerl6

sub infix:<exp> ($x, $y) { $x ** $y;}

say 3 exp 4; # 81

(例) べき乗の関数

Page 28: "What Does Your Code Smell Like?"で学ぶPerl6

sub infix:<M> (@x is rw, @y is rw) { gather { while @x and @y { given @x[0] cmp @y[0] { when Increase { take @x.shift } when Decrease { take @y.shift } when Same { take @x.shift, @y.shift } } } take @x, @y }}

こう定義して……

Page 29: "What Does Your Code Smell Like?"で学ぶPerl6

sub strand_sort (@x is copy) { my @out; @out = @out M strand(@x) while @x; @out;}

こう使う

Page 30: "What Does Your Code Smell Like?"で学ぶPerl6

sub strand_sort (@x is copy) { my @out; @out M= strand(@x) while @x; @out;}

こう書くこともできる

Page 31: "What Does Your Code Smell Like?"で学ぶPerl6

is rw

Page 32: "What Does Your Code Smell Like?"で学ぶPerl6

is ***

• Perl6 では引数は読み取り専用

•引数の値を変更したい場合は is rw

•引数のコピーが欲しい場合は is copy

Page 33: "What Does Your Code Smell Like?"で学ぶPerl6

sub writable ($x is rw) { $x += 1; say "x = $x";}

my $orig = 10;say "orig = $orig";writable($orig);say "orig = $orig";

# orig = 10# x = 11# orig = 11

is rw を使うと

Page 34: "What Does Your Code Smell Like?"で学ぶPerl6

sub copy_value ($x is copy) { $x += 1; say "x = $x";}

my $orig = 10;say "orig = $orig";copy_value($orig);say "orig = $orig";

# orig = 10# x = 11# orig = 10

is copy を使うと

Page 35: "What Does Your Code Smell Like?"で学ぶPerl6

sub read_only ($x) { $x += 1; say "x = $x";}

my $orig = 10;say "orig = $orig";read_only($orig);say "orig = $orig";

# orig = 10# Cannot assign to a readonly variable or a value# in block at src/gen/CORE.setting:11981# in sub read_only at is.pl:2# in block at is.pl:8

何も指定しなかった場合

Page 36: "What Does Your Code Smell Like?"で学ぶPerl6

gather ... take

Page 37: "What Does Your Code Smell Like?"で学ぶPerl6

gather ... take

• gather は遅延評価リストを返す

•評価時に gather ブロック内を走査

• take された要素を見つけて返す

Page 38: "What Does Your Code Smell Like?"で学ぶPerl6

my @list = gather { for 0 .. Inf { take $_ ** $_; }}

say @list[0..3]; # 1 1 4 27

簡単な例

Page 39: "What Does Your Code Smell Like?"で学ぶPerl6

sub infix:<M> (@x is rw, @y is rw) { gather { while @x and @y { given @x[0] cmp @y[0] { when Increase { take @x.shift } when Decrease { take @y.shift } when Same { take @x.shift, @y.shift } } } take @x, @y }}

merge関数での使い方

Page 40: "What Does Your Code Smell Like?"で学ぶPerl6

まとめ

• 文法にちょっとした変更がたくさん• 演算子を定義できる• is *** で引数へのアクセスレベルを指定• 遅延評価ができる

Page 41: "What Does Your Code Smell Like?"で学ぶPerl6

ところで

Page 42: "What Does Your Code Smell Like?"で学ぶPerl6

Perl5 と Perl6 の関係

• 異なる言語• Perl6 は Perl5 をベースに設計されている• Perl6 の特徴の一部は Perl5 に移植されている

Page 43: "What Does Your Code Smell Like?"で学ぶPerl6

Perl6::Gather

Page 44: "What Does Your Code Smell Like?"で学ぶPerl6
Page 45: "What Does Your Code Smell Like?"で学ぶPerl6

use strict;use warnings;

use Perl6::Gather;

my @list = gather { for (0..100) { take $_ ** $_; }};

for (0..3) { print $list[$_], ' ';}print "\n";

# 1 1 4 27

Page 46: "What Does Your Code Smell Like?"で学ぶPerl6