SlideShare ist ein Scribd-Unternehmen logo
1 von 30
e-Zuka Teck Night Vol.1




Ruby                      の
クロージャと
ファイバーを
かっこよく使ってみよう

e-Zuka Teck Night, Rubyist九州   近畿大学
            山崎重一郎
e-Zuka Teck Night Vol.1




            Rubyには
          関数型言語の
         顔があるんです

 1.9になってますます関数型言語的な感じ
 closureやFiberはそんな感じが強い
 今日はRubyをオブジェクト指向言語じゃなくて関
  数型言語みたいに扱います!
e-Zuka Teck Night Vol.1




関数定義
λを使って関数を定義すると




    ->x{ … }
e-Zuka Teck Night Vol.1




無名関数の使い方

> ->x{x+1}   #Procオブジェクト

> ->x{x+1}[3] #関数適用
4
e-Zuka Teck Night Vol.1




Rubyの文法をちょっと
 繰り返し構造を持つオブジェクトの例
イテレータ
 (1..5)    #範囲ブジェクト
 オブジェクト自体の繰り返し構造にそって繰り返しを制御
 [1,2,3,4,5] #配列

> (1..5).map{|x| x*100} #イテレータmap
[100, 200, 300, 400, 500]

> (1..5).reduce{|s,x|s+=x} #イテレータreduce
15
e-Zuka Teck Night Vol.1




関数に名前をつける
Procを代入する

 階乗関数の例

 fact =->n{n==0?1:(1..n).reduce(:*)}
e-Zuka Teck Night Vol.1




関数とクロージャ
関数の独立変数と係数は何が違うのか?


  f(x) = a*x
 アルファベットの前の方が係数で終わりの方が変数?
e-Zuka Teck Night Vol.1




λとレキシカル変数
ラムダは「これが変数だ」という束縛を表示する




  f = ->x{a*x}

束縛されていない変数   aは、「レキシカル変数」
e-Zuka Teck Night Vol.1




レキシカル変数の例

> a=1
> ->x{a=a*x}}[10]
10
>a
10
e-Zuka Teck Night Vol.1




レキシコン:辞書の語彙
レキシカル変数とは、辞書の項目の意味

文字列 →      束縛されている値

eval するとその環境の辞書におけるレキシカル変数の
 値がわかる

> age = 54
> eval('age')
54
e-Zuka Teck Night Vol.1



関数の関数の定義
λを二つ使うと(関数の関数)




->x{->y{...}}
e-Zuka Teck Night Vol.1




レキシカル変数と
クロージャ
 係数   a を関数の関数の束縛変数として定義する場合


  f= ->a{->x{a*x}}
e-Zuka Teck Night Vol.1

関数の関数でクロージャを
つくる
組合せ関数 2引数(nとr)
combi=->n{->r{fact[n]/(fact[r]*fact[n-r])}}
> combi[8][4]
70

> c8=combi[8] # nが8のクロージャをつくる
> (0..8).map{|x| c8[x]} #いろんなrでの結果
[1, 8, 28, 56, 70, 56, 28, 8, 1]
e-Zuka Teck Night Vol.1




関数に辞書(環境)が含ま
れている(クロージャ)
> eval('n',c8.binding)
>8
> n=1000
> eval('n',c8.binding)
>8
e-Zuka Teck Night Vol.1




レキシカルスコープ
変数の辞書に一旦定義されると
その後は、ずっと内側の世界でも同じ辞書を使う
内側の世界の辞書は外からは隠蔽されている
     a=1


     a=10 代入      a=10

     a→10         a→未定義
     a→10         a→未定義
e-Zuka Teck Night Vol.1




関数のメモ化は、xが未定義の時だけobj
                                x||=obj
クロージャでキャッシュが作れる
             を代入するという意味
組み合わせ関数のメモ化

c=->m{->n{m[n]||={};->r{m[n][r]||=combi[n][r]}}}
> cm=c[{}] #空のハッシュオブジェクトで初期化
> cm[80000][79990]
 2957280616639006757538254376469462127992000
> eval('m',cm.binding)

{80000=>{79990=>2957280616639006757538254376
469462127992000}}
e-Zuka Teck Night Vol.1




Fiber                  #子スレッド(ファイバー)
                       f=Fiber.new{|x|
                           puts '最初'
                           Fiber.yield
軽量スレッドと継続                 puts x
• Fiber.new{|x|...}        y=Fiber.yield
  ファイバーの生成                 puts y
  =子スレッド(軽量)             }
                   #親スレッド
• Fiver.yield(obj)
                   > f.resume 3
  親のコンテクストに行く
                   最初
                   > f.resume
• resume(obj) メソッド 3
  子供のコンテクストに行く > f.resume 7
  (停止中の処理を継続)      7
                   > f.resume
                   FiberError: dead fiber called
e-Zuka Teck Night Vol.1




Fiberによる
親子コミュニケーション
ファイバー(子スレッド)の生成
f=Fiber.new{|x| loop{x=Fiber.yield(x+1)}}

親スレッドからファイバー(子スレッド)にメッセージを出すと
ファイバーがそれに応える

> f.resume 100
101
> f.resume 2
3
e-Zuka Teck Night Vol.1


Fiberによるジェネレータ
無限集合などをあつかうプログラム

自然数ジェネレータ
num=->a{loop{a+=1}}
> num[0] #... 無限ループ〜
無限集合を素直に生成しているんだけどね

ファイバーにした自然数ジェネレータ
num=Fiber.new{|a| loop{Fiber.yield a+=1}}
> num.resume 0
1
> num.resume
2
e-Zuka Teck Night Vol.1


Fiberによるジェネレータ
フィボナッチ数列バージョン!
fib=->{a,b=0,1;loop{a,b=b,a+b}}
>fib[]
... 無限ループ〜
ファイバーにする
f=Fiber.new{a,b=0,1;loop{Fiber.yield a;a,b=b,a+b}}

> 5.times {puts f.resume}
0
1
1
2
3
e-Zuka Teck Night Vol.1



Generate and Test
素数生成の例
> num=->a{Fiber.new{loop{Fiber.yield a+=1}}}
> numg=num[1]             #2以上の自然数のジェネレータ


prime=->pl{->{
    begin
     n=numg.resume #自然数ジェネレータ
    end until pl.all?{|x|n%x!=0} #テスト
    pl.push n}}

> pr=prime[[]]
> pr[]
[2]
> pr[]
e-Zuka Teck Night Vol.1



    Fiber による
    ジェネレータ
素数バージョン(しつこい!)
prime =->n{p=[];loop{p.push n if p.all?{|x|n%x!=0};n+=1}}

>prime[2]

ファイバー版

fprime=Fiber.new{|n|p=[];
      loop{Fiber.yield p.push(n).last if p.all?{|x|n%x!=0};n+=1}}

> fprime.resume 2
2
> fprime.resume
3
e-Zuka Teck Night Vol.1


ノンプリエンプティブな
マルチタスク
OSに頼らない(負荷が軽い)
ファイバーにした自然数ジェネレータ

num1=Fiber.new{|a| loop{Fiber.yield a+=1}}
num2=Fiber.new{|a| loop{Fiber.yield a+=1}}

> num1.resume 0
1
> num2.resume 0
1
> num1.resume
2
> num2.resume
2
e-Zuka Teck Night Vol.1



コルーチンとしての
Fiber
初期のMacintosh OS
 多数のコルーチンの集合体でできていた
                            Macintosh 128K
 (超軽量スレッド)
                               8MHz
                               128Kb

                    操作による
                    イベント


          実際のメモリ
                   ビットマップ
                   への表示など
e-Zuka Teck Night Vol.1




Fiberでコルーチン
Webサーバの超軽量化
イベント処理をコルーチンPoolに事前に生成しておく
メモリ節約、レスポンスの高速化
                    Pjaxなどの
                    細粒度イベント
                               ブラウザ
                  操作による
                  イベント
                  POSTとか



  Fiber対応Webサーバ
                  ブラウザへの
    Goliathとか     表示変更
e-Zuka Teck Night Vol.1


      FiberとThreadの比較
 出典:Ruby Fibers Vs Ruby Threads
  http://oldmoe.blogspot.com/2008/08/ruby-fibers-vs-ruby-threads.html
e-Zuka Teck Night Vol.1

Fiberでリアルタイム処理
3軸加速度センサーのバッファ入力の例
#バッファ管理クロージャ
bf=->a{->d{a.push(d).shift; a}}

#ファイバー生成関数
bff=->a{b=bf[a]; Fiber.new{|d|loop{d=Fiber.yield b[d]}}}

fx=bff[Array.new(10,0.0)] #x軸方向
fy=bff[Array.new(10,0.0)] #y軸方向
fz=bff[Array.new(10,0.0)] #z軸方向
loop do
  data=sp.readline.split(',').map {|x| x.to_f}
  fx.resume(data[0])
  fy.resume(data[1])
  fz.resume(data[2])
end
e-Zuka Teck Night Vol.1




Fiberによる
リアルタイム処理
3つじゃあまりありがたくない
1000個のセンサーの入力をサーバでリアルタイム処理


群衆や流体のシミュレーションにも
JavaScritptやprocessingの方がいいかもしれないけど
e-Zuka Teck Night Vol.1




コールバックスパゲティ
を改善する
JavaScriptでブラウザの制御を書くと
 コルーチン登録タイミングの空振り
 コールバックルーチンがコールバックルーチンを呼ぶ


javaScript 1.7で Fiber (yield, next) が仕様に追加され
 た(いまのところ実装されているのはfirefoxだけ)

 将来的には、マウスでぐりぐりやるようなプログラムはFiber
 で書くようになるでしょう。
e-Zuka Teck Night Vol.1




まとめ
細粒度イベント駆動型Web (Pjaxなど)
センサー/機械制御系/ロボット
シミュレーション
ジェネレータを使う知的システム
マウスでごりごり型
ファイバーをうまく使うとそういうタイプのプログラ
ムをすっきり書ける!

Weitere ähnliche Inhalte

Was ist angesagt?

NIPS2013読み会: Scalable kernels for graphs with continuous attributes
NIPS2013読み会: Scalable kernels for graphs with continuous attributesNIPS2013読み会: Scalable kernels for graphs with continuous attributes
NIPS2013読み会: Scalable kernels for graphs with continuous attributesYasuo Tabei
 
Project Loom + Project Panama
Project Loom + Project PanamaProject Loom + Project Panama
Project Loom + Project PanamaYuichi Sakuraba
 
Cython intro prelerease
Cython intro prelereaseCython intro prelerease
Cython intro prelereaseShiqiao Du
 
劣モジュラ関数とNetwork flow
劣モジュラ関数とNetwork flow劣モジュラ関数とNetwork flow
劣モジュラ関数とNetwork flowYuri Xyca
 
並列対決 Elixir × Go × C# x Scala , Node.js
並列対決 Elixir × Go × C# x Scala , Node.js並列対決 Elixir × Go × C# x Scala , Node.js
並列対決 Elixir × Go × C# x Scala , Node.jsYoshiiro Ueno
 
Away3D 4.1 パーティクル入門
Away3D 4.1 パーティクル入門Away3D 4.1 パーティクル入門
Away3D 4.1 パーティクル入門Yasunobu Ikeda
 
Corona HandsOn#2
Corona HandsOn#2Corona HandsOn#2
Corona HandsOn#2Tetsuo Ono
 
PyOpenCLによるGPGPU入門 Tokyo.SciPy#4 編
PyOpenCLによるGPGPU入門 Tokyo.SciPy#4 編PyOpenCLによるGPGPU入門 Tokyo.SciPy#4 編
PyOpenCLによるGPGPU入門 Tokyo.SciPy#4 編Yosuke Onoue
 
準同型暗号の実装とMontgomery, Karatsuba, FFT の性能
準同型暗号の実装とMontgomery, Karatsuba, FFT の性能準同型暗号の実装とMontgomery, Karatsuba, FFT の性能
準同型暗号の実装とMontgomery, Karatsuba, FFT の性能MITSUNARI Shigeo
 
きつねさんでもわかるLlvm読書会 第2回
きつねさんでもわかるLlvm読書会 第2回きつねさんでもわかるLlvm読書会 第2回
きつねさんでもわかるLlvm読書会 第2回Tomoya Kawanishi
 
Introduction qc
Introduction qcIntroduction qc
Introduction qckoutarmiur
 

Was ist angesagt? (13)

NIPS2013読み会: Scalable kernels for graphs with continuous attributes
NIPS2013読み会: Scalable kernels for graphs with continuous attributesNIPS2013読み会: Scalable kernels for graphs with continuous attributes
NIPS2013読み会: Scalable kernels for graphs with continuous attributes
 
Project Loom + Project Panama
Project Loom + Project PanamaProject Loom + Project Panama
Project Loom + Project Panama
 
PFI Christmas seminar 2009
PFI Christmas seminar 2009PFI Christmas seminar 2009
PFI Christmas seminar 2009
 
Cython intro prelerease
Cython intro prelereaseCython intro prelerease
Cython intro prelerease
 
劣モジュラ関数とNetwork flow
劣モジュラ関数とNetwork flow劣モジュラ関数とNetwork flow
劣モジュラ関数とNetwork flow
 
並列対決 Elixir × Go × C# x Scala , Node.js
並列対決 Elixir × Go × C# x Scala , Node.js並列対決 Elixir × Go × C# x Scala , Node.js
並列対決 Elixir × Go × C# x Scala , Node.js
 
Away3D 4.1 パーティクル入門
Away3D 4.1 パーティクル入門Away3D 4.1 パーティクル入門
Away3D 4.1 パーティクル入門
 
Corona HandsOn#2
Corona HandsOn#2Corona HandsOn#2
Corona HandsOn#2
 
PyOpenCLによるGPGPU入門 Tokyo.SciPy#4 編
PyOpenCLによるGPGPU入門 Tokyo.SciPy#4 編PyOpenCLによるGPGPU入門 Tokyo.SciPy#4 編
PyOpenCLによるGPGPU入門 Tokyo.SciPy#4 編
 
準同型暗号の実装とMontgomery, Karatsuba, FFT の性能
準同型暗号の実装とMontgomery, Karatsuba, FFT の性能準同型暗号の実装とMontgomery, Karatsuba, FFT の性能
準同型暗号の実装とMontgomery, Karatsuba, FFT の性能
 
きつねさんでもわかるLlvm読書会 第2回
きつねさんでもわかるLlvm読書会 第2回きつねさんでもわかるLlvm読書会 第2回
きつねさんでもわかるLlvm読書会 第2回
 
Introduction qc
Introduction qcIntroduction qc
Introduction qc
 
FHE in Action
FHE in ActionFHE in Action
FHE in Action
 

Ähnlich wie Ruby1.9のfiberのかっこよくつかおう

フィボナッチ数列の作り方
フィボナッチ数列の作り方フィボナッチ数列の作り方
フィボナッチ数列の作り方Tomoya Kawanishi
 
深層学習 Day1レポート
深層学習 Day1レポート深層学習 Day1レポート
深層学習 Day1レポートtaishimotoda
 
Rで学ぶデータマイニングI 第8章〜第13章
Rで学ぶデータマイニングI 第8章〜第13章Rで学ぶデータマイニングI 第8章〜第13章
Rで学ぶデータマイニングI 第8章〜第13章Prunus 1350
 
Ekmett勉強会発表資料
Ekmett勉強会発表資料Ekmett勉強会発表資料
Ekmett勉強会発表資料時響 逢坂
 
yieldとreturnの話
yieldとreturnの話yieldとreturnの話
yieldとreturnの話bleis tift
 
Web講座 第8回
Web講座 第8回Web講座 第8回
Web講座 第8回nanametown
 
関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)啓 小笠原
 
PRML Chapter 5 (5.0-5.4)
PRML Chapter 5 (5.0-5.4)PRML Chapter 5 (5.0-5.4)
PRML Chapter 5 (5.0-5.4)Shogo Nakamura
 
Ekmett勉強会発表資料
Ekmett勉強会発表資料Ekmett勉強会発表資料
Ekmett勉強会発表資料時響 逢坂
 
Siphone coffeemaker okayama-js-1
Siphone coffeemaker okayama-js-1Siphone coffeemaker okayama-js-1
Siphone coffeemaker okayama-js-1NISHIMOTO Keisuke
 
Knn発表資料(R)
Knn発表資料(R)Knn発表資料(R)
Knn発表資料(R)Sora Kubota
 
Perlと出会い、Perlを作る
Perlと出会い、Perlを作るPerlと出会い、Perlを作る
Perlと出会い、Perlを作るgoccy
 

Ähnlich wie Ruby1.9のfiberのかっこよくつかおう (16)

フィボナッチ数列の作り方
フィボナッチ数列の作り方フィボナッチ数列の作り方
フィボナッチ数列の作り方
 
深層学習 Day1レポート
深層学習 Day1レポート深層学習 Day1レポート
深層学習 Day1レポート
 
たのしい関数型
たのしい関数型たのしい関数型
たのしい関数型
 
Rで学ぶデータマイニングI 第8章〜第13章
Rで学ぶデータマイニングI 第8章〜第13章Rで学ぶデータマイニングI 第8章〜第13章
Rで学ぶデータマイニングI 第8章〜第13章
 
Ekmett勉強会発表資料
Ekmett勉強会発表資料Ekmett勉強会発表資料
Ekmett勉強会発表資料
 
yieldとreturnの話
yieldとreturnの話yieldとreturnの話
yieldとreturnの話
 
ATN No.2 Scala事始め
ATN No.2 Scala事始めATN No.2 Scala事始め
ATN No.2 Scala事始め
 
Fiberの使いどころ
Fiberの使いどころFiberの使いどころ
Fiberの使いどころ
 
Web講座 第8回
Web講座 第8回Web講座 第8回
Web講座 第8回
 
関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)
 
PRML Chapter 5 (5.0-5.4)
PRML Chapter 5 (5.0-5.4)PRML Chapter 5 (5.0-5.4)
PRML Chapter 5 (5.0-5.4)
 
Ekmett勉強会発表資料
Ekmett勉強会発表資料Ekmett勉強会発表資料
Ekmett勉強会発表資料
 
PRML5
PRML5PRML5
PRML5
 
Siphone coffeemaker okayama-js-1
Siphone coffeemaker okayama-js-1Siphone coffeemaker okayama-js-1
Siphone coffeemaker okayama-js-1
 
Knn発表資料(R)
Knn発表資料(R)Knn発表資料(R)
Knn発表資料(R)
 
Perlと出会い、Perlを作る
Perlと出会い、Perlを作るPerlと出会い、Perlを作る
Perlと出会い、Perlを作る
 

Mehr von Kindai University

Blockchain and Virtual Currency - Technical issues -
Blockchain and Virtual Currency- Technical issues -Blockchain and Virtual Currency- Technical issues -
Blockchain and Virtual Currency - Technical issues -Kindai University
 
ブロックチェーンエコノミーのコンセンサスとガバナンス
ブロックチェーンエコノミーのコンセンサスとガバナンスブロックチェーンエコノミーのコンセンサスとガバナンス
ブロックチェーンエコノミーのコンセンサスとガバナンスKindai University
 
福岡ブロックチェーン・エコノミー勉強会セミナー
福岡ブロックチェーン・エコノミー勉強会セミナー福岡ブロックチェーン・エコノミー勉強会セミナー
福岡ブロックチェーン・エコノミー勉強会セミナーKindai University
 
福岡ブロックチェーン・エコノミー勉強会公開版
福岡ブロックチェーン・エコノミー勉強会公開版福岡ブロックチェーン・エコノミー勉強会公開版
福岡ブロックチェーン・エコノミー勉強会公開版Kindai University
 
ブロックチェーンによるデータガバナンスと社会基盤の再構築
ブロックチェーンによるデータガバナンスと社会基盤の再構築ブロックチェーンによるデータガバナンスと社会基盤の再構築
ブロックチェーンによるデータガバナンスと社会基盤の再構築Kindai University
 
やっぱりブロックチェインより仮想通貨
やっぱりブロックチェインより仮想通貨やっぱりブロックチェインより仮想通貨
やっぱりブロックチェインより仮想通貨Kindai University
 
FinTechと金融サービスの将来像
FinTechと金融サービスの将来像FinTechと金融サービスの将来像
FinTechと金融サービスの将来像Kindai University
 
仮想通貨のブロックチェイン技術によるFinTech
仮想通貨のブロックチェイン技術によるFinTech仮想通貨のブロックチェイン技術によるFinTech
仮想通貨のブロックチェイン技術によるFinTechKindai University
 
ビットコイン福岡勉強会法的課題
ビットコイン福岡勉強会法的課題ビットコイン福岡勉強会法的課題
ビットコイン福岡勉強会法的課題Kindai University
 
ブロックチェインとOpen asset protocol
ブロックチェインとOpen asset protocolブロックチェインとOpen asset protocol
ブロックチェインとOpen asset protocolKindai University
 
電気マネーでエネルギー問題解決
電気マネーでエネルギー問題解決電気マネーでエネルギー問題解決
電気マネーでエネルギー問題解決Kindai University
 
電子情報通信学会グローバル社会とビットコイン(山崎)
電子情報通信学会グローバル社会とビットコイン(山崎)電子情報通信学会グローバル社会とビットコイン(山崎)
電子情報通信学会グローバル社会とビットコイン(山崎)Kindai University
 
薬院サルー仮想通貨プロジェクト
薬院サルー仮想通貨プロジェクト薬院サルー仮想通貨プロジェクト
薬院サルー仮想通貨プロジェクトKindai University
 

Mehr von Kindai University (20)

Blockchain and Virtual Currency - Technical issues -
Blockchain and Virtual Currency- Technical issues -Blockchain and Virtual Currency- Technical issues -
Blockchain and Virtual Currency - Technical issues -
 
Gbec finance and blockchain
Gbec finance and blockchainGbec finance and blockchain
Gbec finance and blockchain
 
Blockchian definition
Blockchian definitionBlockchian definition
Blockchian definition
 
Blockchain economy
Blockchain economyBlockchain economy
Blockchain economy
 
ブロックチェーンエコノミーのコンセンサスとガバナンス
ブロックチェーンエコノミーのコンセンサスとガバナンスブロックチェーンエコノミーのコンセンサスとガバナンス
ブロックチェーンエコノミーのコンセンサスとガバナンス
 
福岡ブロックチェーン・エコノミー勉強会セミナー
福岡ブロックチェーン・エコノミー勉強会セミナー福岡ブロックチェーン・エコノミー勉強会セミナー
福岡ブロックチェーン・エコノミー勉強会セミナー
 
福岡ブロックチェーン・エコノミー勉強会公開版
福岡ブロックチェーン・エコノミー勉強会公開版福岡ブロックチェーン・エコノミー勉強会公開版
福岡ブロックチェーン・エコノミー勉強会公開版
 
ブロックチェーンによるデータガバナンスと社会基盤の再構築
ブロックチェーンによるデータガバナンスと社会基盤の再構築ブロックチェーンによるデータガバナンスと社会基盤の再構築
ブロックチェーンによるデータガバナンスと社会基盤の再構築
 
やっぱりブロックチェインより仮想通貨
やっぱりブロックチェインより仮想通貨やっぱりブロックチェインより仮想通貨
やっぱりブロックチェインより仮想通貨
 
FinTechと金融サービスの将来像
FinTechと金融サービスの将来像FinTechと金融サービスの将来像
FinTechと金融サービスの将来像
 
Congre chain説明資料
Congre chain説明資料Congre chain説明資料
Congre chain説明資料
 
仮想通貨のブロックチェイン技術によるFinTech
仮想通貨のブロックチェイン技術によるFinTech仮想通貨のブロックチェイン技術によるFinTech
仮想通貨のブロックチェイン技術によるFinTech
 
ビットコイン福岡勉強会法的課題
ビットコイン福岡勉強会法的課題ビットコイン福岡勉強会法的課題
ビットコイン福岡勉強会法的課題
 
ブロックチェインとOpen asset protocol
ブロックチェインとOpen asset protocolブロックチェインとOpen asset protocol
ブロックチェインとOpen asset protocol
 
Open fintech and Kachatter
Open fintech and KachatterOpen fintech and Kachatter
Open fintech and Kachatter
 
電気マネーでエネルギー問題解決
電気マネーでエネルギー問題解決電気マネーでエネルギー問題解決
電気マネーでエネルギー問題解決
 
仮想通貨実験計画
仮想通貨実験計画仮想通貨実験計画
仮想通貨実験計画
 
Bit Nexus
Bit NexusBit Nexus
Bit Nexus
 
電子情報通信学会グローバル社会とビットコイン(山崎)
電子情報通信学会グローバル社会とビットコイン(山崎)電子情報通信学会グローバル社会とビットコイン(山崎)
電子情報通信学会グローバル社会とビットコイン(山崎)
 
薬院サルー仮想通貨プロジェクト
薬院サルー仮想通貨プロジェクト薬院サルー仮想通貨プロジェクト
薬院サルー仮想通貨プロジェクト
 

Ruby1.9のfiberのかっこよくつかおう

  • 1. e-Zuka Teck Night Vol.1 Ruby の クロージャと ファイバーを かっこよく使ってみよう e-Zuka Teck Night, Rubyist九州 近畿大学 山崎重一郎
  • 2. e-Zuka Teck Night Vol.1 Rubyには 関数型言語の 顔があるんです  1.9になってますます関数型言語的な感じ  closureやFiberはそんな感じが強い  今日はRubyをオブジェクト指向言語じゃなくて関 数型言語みたいに扱います!
  • 3. e-Zuka Teck Night Vol.1 関数定義 λを使って関数を定義すると ->x{ … }
  • 4. e-Zuka Teck Night Vol.1 無名関数の使い方 > ->x{x+1} #Procオブジェクト > ->x{x+1}[3] #関数適用 4
  • 5. e-Zuka Teck Night Vol.1 Rubyの文法をちょっと 繰り返し構造を持つオブジェクトの例 イテレータ (1..5) #範囲ブジェクト オブジェクト自体の繰り返し構造にそって繰り返しを制御 [1,2,3,4,5] #配列 > (1..5).map{|x| x*100} #イテレータmap [100, 200, 300, 400, 500] > (1..5).reduce{|s,x|s+=x} #イテレータreduce 15
  • 6. e-Zuka Teck Night Vol.1 関数に名前をつける Procを代入する 階乗関数の例 fact =->n{n==0?1:(1..n).reduce(:*)}
  • 7. e-Zuka Teck Night Vol.1 関数とクロージャ 関数の独立変数と係数は何が違うのか? f(x) = a*x アルファベットの前の方が係数で終わりの方が変数?
  • 8. e-Zuka Teck Night Vol.1 λとレキシカル変数 ラムダは「これが変数だ」という束縛を表示する f = ->x{a*x} 束縛されていない変数 aは、「レキシカル変数」
  • 9. e-Zuka Teck Night Vol.1 レキシカル変数の例 > a=1 > ->x{a=a*x}}[10] 10 >a 10
  • 10. e-Zuka Teck Night Vol.1 レキシコン:辞書の語彙 レキシカル変数とは、辞書の項目の意味 文字列 → 束縛されている値 eval するとその環境の辞書におけるレキシカル変数の 値がわかる > age = 54 > eval('age') 54
  • 11. e-Zuka Teck Night Vol.1 関数の関数の定義 λを二つ使うと(関数の関数) ->x{->y{...}}
  • 12. e-Zuka Teck Night Vol.1 レキシカル変数と クロージャ  係数 a を関数の関数の束縛変数として定義する場合 f= ->a{->x{a*x}}
  • 13. e-Zuka Teck Night Vol.1 関数の関数でクロージャを つくる 組合せ関数 2引数(nとr) combi=->n{->r{fact[n]/(fact[r]*fact[n-r])}} > combi[8][4] 70 > c8=combi[8] # nが8のクロージャをつくる > (0..8).map{|x| c8[x]} #いろんなrでの結果 [1, 8, 28, 56, 70, 56, 28, 8, 1]
  • 14. e-Zuka Teck Night Vol.1 関数に辞書(環境)が含ま れている(クロージャ) > eval('n',c8.binding) >8 > n=1000 > eval('n',c8.binding) >8
  • 15. e-Zuka Teck Night Vol.1 レキシカルスコープ 変数の辞書に一旦定義されると その後は、ずっと内側の世界でも同じ辞書を使う 内側の世界の辞書は外からは隠蔽されている a=1 a=10 代入 a=10 a→10 a→未定義 a→10 a→未定義
  • 16. e-Zuka Teck Night Vol.1 関数のメモ化は、xが未定義の時だけobj x||=obj クロージャでキャッシュが作れる を代入するという意味 組み合わせ関数のメモ化 c=->m{->n{m[n]||={};->r{m[n][r]||=combi[n][r]}}} > cm=c[{}] #空のハッシュオブジェクトで初期化 > cm[80000][79990] 2957280616639006757538254376469462127992000 > eval('m',cm.binding) {80000=>{79990=>2957280616639006757538254376 469462127992000}}
  • 17. e-Zuka Teck Night Vol.1 Fiber #子スレッド(ファイバー) f=Fiber.new{|x| puts '最初' Fiber.yield 軽量スレッドと継続 puts x • Fiber.new{|x|...} y=Fiber.yield ファイバーの生成 puts y =子スレッド(軽量) } #親スレッド • Fiver.yield(obj) > f.resume 3 親のコンテクストに行く 最初 > f.resume • resume(obj) メソッド 3 子供のコンテクストに行く > f.resume 7 (停止中の処理を継続) 7 > f.resume FiberError: dead fiber called
  • 18. e-Zuka Teck Night Vol.1 Fiberによる 親子コミュニケーション ファイバー(子スレッド)の生成 f=Fiber.new{|x| loop{x=Fiber.yield(x+1)}} 親スレッドからファイバー(子スレッド)にメッセージを出すと ファイバーがそれに応える > f.resume 100 101 > f.resume 2 3
  • 19. e-Zuka Teck Night Vol.1 Fiberによるジェネレータ 無限集合などをあつかうプログラム 自然数ジェネレータ num=->a{loop{a+=1}} > num[0] #... 無限ループ〜 無限集合を素直に生成しているんだけどね ファイバーにした自然数ジェネレータ num=Fiber.new{|a| loop{Fiber.yield a+=1}} > num.resume 0 1 > num.resume 2
  • 20. e-Zuka Teck Night Vol.1 Fiberによるジェネレータ フィボナッチ数列バージョン! fib=->{a,b=0,1;loop{a,b=b,a+b}} >fib[] ... 無限ループ〜 ファイバーにする f=Fiber.new{a,b=0,1;loop{Fiber.yield a;a,b=b,a+b}} > 5.times {puts f.resume} 0 1 1 2 3
  • 21. e-Zuka Teck Night Vol.1 Generate and Test 素数生成の例 > num=->a{Fiber.new{loop{Fiber.yield a+=1}}} > numg=num[1] #2以上の自然数のジェネレータ prime=->pl{->{ begin n=numg.resume #自然数ジェネレータ end until pl.all?{|x|n%x!=0} #テスト pl.push n}} > pr=prime[[]] > pr[] [2] > pr[]
  • 22. e-Zuka Teck Night Vol.1 Fiber による ジェネレータ 素数バージョン(しつこい!) prime =->n{p=[];loop{p.push n if p.all?{|x|n%x!=0};n+=1}} >prime[2] ファイバー版 fprime=Fiber.new{|n|p=[]; loop{Fiber.yield p.push(n).last if p.all?{|x|n%x!=0};n+=1}} > fprime.resume 2 2 > fprime.resume 3
  • 23. e-Zuka Teck Night Vol.1 ノンプリエンプティブな マルチタスク OSに頼らない(負荷が軽い) ファイバーにした自然数ジェネレータ num1=Fiber.new{|a| loop{Fiber.yield a+=1}} num2=Fiber.new{|a| loop{Fiber.yield a+=1}} > num1.resume 0 1 > num2.resume 0 1 > num1.resume 2 > num2.resume 2
  • 24. e-Zuka Teck Night Vol.1 コルーチンとしての Fiber 初期のMacintosh OS 多数のコルーチンの集合体でできていた Macintosh 128K (超軽量スレッド) 8MHz 128Kb 操作による イベント 実際のメモリ ビットマップ への表示など
  • 25. e-Zuka Teck Night Vol.1 Fiberでコルーチン Webサーバの超軽量化 イベント処理をコルーチンPoolに事前に生成しておく メモリ節約、レスポンスの高速化 Pjaxなどの 細粒度イベント ブラウザ 操作による イベント POSTとか Fiber対応Webサーバ ブラウザへの Goliathとか 表示変更
  • 26. e-Zuka Teck Night Vol.1 FiberとThreadの比較  出典:Ruby Fibers Vs Ruby Threads http://oldmoe.blogspot.com/2008/08/ruby-fibers-vs-ruby-threads.html
  • 27. e-Zuka Teck Night Vol.1 Fiberでリアルタイム処理 3軸加速度センサーのバッファ入力の例 #バッファ管理クロージャ bf=->a{->d{a.push(d).shift; a}} #ファイバー生成関数 bff=->a{b=bf[a]; Fiber.new{|d|loop{d=Fiber.yield b[d]}}} fx=bff[Array.new(10,0.0)] #x軸方向 fy=bff[Array.new(10,0.0)] #y軸方向 fz=bff[Array.new(10,0.0)] #z軸方向 loop do data=sp.readline.split(',').map {|x| x.to_f} fx.resume(data[0]) fy.resume(data[1]) fz.resume(data[2]) end
  • 28. e-Zuka Teck Night Vol.1 Fiberによる リアルタイム処理 3つじゃあまりありがたくない 1000個のセンサーの入力をサーバでリアルタイム処理 群衆や流体のシミュレーションにも JavaScritptやprocessingの方がいいかもしれないけど
  • 29. e-Zuka Teck Night Vol.1 コールバックスパゲティ を改善する JavaScriptでブラウザの制御を書くと コルーチン登録タイミングの空振り コールバックルーチンがコールバックルーチンを呼ぶ javaScript 1.7で Fiber (yield, next) が仕様に追加され た(いまのところ実装されているのはfirefoxだけ) 将来的には、マウスでぐりぐりやるようなプログラムはFiber で書くようになるでしょう。
  • 30. e-Zuka Teck Night Vol.1 まとめ 細粒度イベント駆動型Web (Pjaxなど) センサー/機械制御系/ロボット シミュレーション ジェネレータを使う知的システム マウスでごりごり型 ファイバーをうまく使うとそういうタイプのプログラ ムをすっきり書ける!