Higher order perl

Post on 31-May-2015

2.885 views 2 download

Tags:

description

Hokkaido.pm #4

Transcript of Higher order perl

高階Perl2/19 Hokkaido.pm #4

@havanaclub

2011年2月19日土曜日

早いもので #4

2011年2月19日土曜日

ところで

2011年2月19日土曜日

プログラマの生涯

2011年2月19日土曜日

プログラマの生涯•OOP期

2011年2月19日土曜日

プログラマの生涯•OOP期•クロージャ期

2011年2月19日土曜日

プログラマの生涯•OOP期•クロージャ期•メタプログラミング期

2011年2月19日土曜日

プログラマの生涯•OOP期•クロージャ期•メタプログラミング期• DSL期

2011年2月19日土曜日

プログラマの生涯•OOP期•クロージャ期•メタプログラミング期• DSL期•もうなんでもいいや……期

2011年2月19日土曜日

プログラマの生涯•OOP期

2011年2月19日土曜日

プログラマの生涯•OOP期•とにかくオブジェクトな感じ

2011年2月19日土曜日

プログラマの生涯•OOP期•とにかくオブジェクトな感じ• Smalltalkにかぶれた

2011年2月19日土曜日

プログラマの生涯•OOP期•とにかくオブジェクトな感じ• Smalltalkにかぶれた• GOF! Kent Beck! ふげふご

2011年2月19日土曜日

プログラマの生涯•OOP期の終焉

2011年2月19日土曜日

プログラマの生涯•OOP期の終焉•謎のクラスファイルの大伽藍

2011年2月19日土曜日

プログラマの生涯•OOP期の終焉•謎のクラスファイルの大伽藍•このファイルなんだっけ……

2011年2月19日土曜日

プログラマの生涯•OOP期の終焉•謎のクラスファイルの大伽藍•このファイルなんだっけ……•抽象化しすぎてなんか必要な手続きがかえって増えたような……

2011年2月19日土曜日

プログラマの生涯•クロージャ期

2011年2月19日土曜日

プログラマの生涯•クロージャ期•とにかくクロージャ

2011年2月19日土曜日

プログラマの生涯•クロージャ期•とにかくクロージャ• Paul Grahumにかぶれた

2011年2月19日土曜日

プログラマの生涯•クロージャ期•とにかくクロージャ• Paul Grahamにかぶれた•関数合成!部分適用!memoize!ふげふご

2011年2月19日土曜日

プログラマの生涯•クロージャ期の終焉

2011年2月19日土曜日

プログラマの生涯•クロージャ期の終焉•デバッグしにくい……

2011年2月19日土曜日

プログラマの生涯•クロージャ期の終焉•デバッグしにくい……•実行時に関数を作るのでスタックトレースに関数の名前が出てこない

2011年2月19日土曜日

プログラマの生涯•クロージャ期の終焉•デバッグしにくい……•実行時に関数を作るのでスタックトレースに関数の名前が出てこない

•まじきびしい

2011年2月19日土曜日

まとめ

2011年2月19日土曜日

There is no silver bullet

2011年2月19日土曜日

高階Perlの話は?

2011年2月19日土曜日

高階Perl• Higher Order Perl• Marks Jason Dominus, 2005• http://hop.perl.plover.com/book/

2011年2月19日土曜日

中身•ぶっちゃけSICPをPerlで書き直しただけ

2011年2月19日土曜日

関数型プログラミングっぽく

2011年2月19日土曜日

関数型プログラミング言語• 関数がfirst-class• first-class = 関数を変数に代入(束縛)したり関数の引数に出来る

• Perl:関数をfirst-classで扱えるので関数型っぽいことも容易

2011年2月19日土曜日

関数の代入?

2011年2月19日土曜日

Perlでのクロージャuse strict;# クロージャを作って変数に束縛my $add = sub { $_[0] + $_[1] };

# 呼び出し$add->(3, 4);# => 7

vsuse strict;

sub add { $_[0] + $_[1]; }

add(2,4);

2011年2月19日土曜日

変数のとじこみuse strict;my $c = 3my $add = sub { $_[0] + $c};

$add->(4);# => 7

変数$cをクロージャ内にとじ込んで後から参照できるようにする

2011年2月19日土曜日

変数の値をクロージャ内で更新すると?

use strict;my $c = 3my $proc = sub { $c++ };

$proc->();# 3$proc->();# 4$proc->();# 5

変数$cの内容が更新されている

2011年2月19日土曜日

普通の関数も変数に入れてみる

use strict;

sub add { $_[0] + $_[1]; }

my $func = ¥&add;$func->(3, 4);# => 7

¥&関数名で関数の参照をとれる

2011年2月19日土曜日

クロージャを作る関数

use strict;# 引数を足し算する関数を返すsub generate { my ($a, $b) = @_; sub { $a + $b };}

generate(3, 4)->();# => 7

2011年2月19日土曜日

クロージャを作る関数(2)use strict;use feature qw(say);

# 引数を足し算する関数を返すsub generate { my ($num) = @_; sub { $num++ };}

my $fun = generate(2);

say $fun->(); # => 2say $fun->(); # => 3

my $fun2 = generate(2);

say $fun2->(); # => 2say $fun2->(); # => 3

2011年2月19日土曜日

どういう役に立つの?

2011年2月19日土曜日

1.コールバック

2011年2月19日土曜日

ファイルの各行を処理

use strict;

sub each_line { my ($file, $proc) = @_; open my $fh “<$file” or return; while(my $line = <$fh>) { $proc->($line); } close($fh);}

each_line(‘aaa.txt’, sub { print $_[0] } );

2011年2月19日土曜日

呼び出し側のsubをなくす

use strict;

sub each_line (&@) { my ($proc, $file) = @_; open my $fh, "<$file" or return; while(my $line = <$fh>) { $proc->($line); } close($fh);}

each_line { print $_[0]; } ('lex.pl') ;

2011年2月19日土曜日

2.関数テーブル

2011年2月19日土曜日

dispatch table(switch代替)

use strict;

my $table = { ‘left’ => sub { print ‘left’ }, ‘right’ => sub { print ‘right’ },};sub dispatch { my ($mode) = @_; my $func = $table->{$mode}; $func && $func->();}dispatch(‘left’);

2011年2月19日土曜日

3.関数のカスタマイズ

2011年2月19日土曜日

ロガーのカスタマイズ

use strict;use Log::Dispatch;

my $logger = Log::Dispatch->new;sub generate_logger { my ($ip) = @_; sub { $logger->info(“$ip : $_[0]“) };}

$custom_logger = generate_logger(‘192.168.1.1’);

$custom_logger->(“msssssg”)# => “192.168.1.1 : msssssssg”

2011年2月19日土曜日

Partial Application(部分適用)

sub patial_add { my ($a) = @_;

sub { add( $a + $_[0] ) };}

sub add { $_[0] + $_[1];}

my $func = patial_add(2);$func->(5);# => 7

2011年2月19日土曜日

4.イテレータ

2011年2月19日土曜日

コンテナの要素を順繰りに取得

use strict;

package Collection;sub new { my $class = shift; bless {data => \@_}, $class; }sub iter { my $self = shift; my $counter = 0; sub { $self->{data}[$counter++] };}

package main;my $iter = Collection->new(1, 2)->iter;say $iter->(); # => 1say $iter->(); # => 2

2011年2月19日土曜日

5.遅延評価

2011年2月19日土曜日

無限リスト

use strict;use feature qw(say);

# 1 .. 無限の整数列を生成my $infinite_list = sub { my $c = 1; sub { $c++; } };

# 整数列の最初から100番目までを表示my $num_list = $infinite_list->();for my $i (0..100) { say $num_list->();}

2011年2月19日土曜日

閑話休題

2011年2月19日土曜日

変数scoping•レキシカルスコープ•my•ダイナミックスコープ• local

2011年2月19日土曜日

レキシカルスコープmy $var = 12;

sub func { say $var;}

sub test { my $var = 19; func();}

test(); # => 12 func(); # => 12

定義時の変数が使われる

2011年2月19日土曜日

ダイナミックスコーlocal $var = 12;

sub func { say $var;}

sub test { local $var = 19; func();}

test(); # => 19func(); # => 12

呼び出しスコープ内で直近の変数が使われる2011年2月19日土曜日

更なる深み

2011年2月19日土曜日

更なる深み•パーサコンビネータ

2011年2月19日土曜日

更なる深み•パーサコンビネータ•インタプリタ作り

2011年2月19日土曜日

更なる深み•パーサコンビネータ•インタプリタ作り•宣言型プログラミング

2011年2月19日土曜日

更なる深み•パーサコンビネータ•インタプリタ作り•宣言型プログラミング•ラムダ計算

2011年2月19日土曜日

更なる深み•パーサコンビネータ•インタプリタ作り•宣言型プログラミング•ラムダ計算

2011年2月19日土曜日

普通にSchemeとかでやった方が……

Scheme!Scheme!

2011年2月19日土曜日

まとめ

2011年2月19日土曜日

クロージャの用量用法を守って使いましょう

2011年2月19日土曜日

参考資料•Higher Order Perl• Structure and Interpretation of Computer Programming

•論理と計算の仕組み• Guy Steele’s Lambda papers(おすすめ)

2011年2月19日土曜日

おまけ

SICP読書会やりたい(hotさんも参加してくれそう)

2011年2月19日土曜日