81
Clojure の のののののののののの のののののの Ruby のののののののの のののの esm LT 2016/10/07

Esm lt threading_macro

  • Upload
    -

  • View
    572

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話についてesm LT 2016/10/07

Page 2: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

自己紹介▸ 久納 工▸ 2006 年入社▸ IT サービス事業部

Page 3: Esm lt threading_macro

Clojure▸ Clojure ( 発音は /'klouʒər/[2], クロージャー ) はプログラミング言語であり、 LISP 系の言語の方言の一つである。関数型プログラミングのプログラミングスタイルでのインタラクティブな開発を支援し、マルチスレッドプログラムの開発を容易化する汎用言語である。 Clojure 言語のプログラムは Java 仮想マシンと Microsoft .NET 共通言語ランタイムで動作する。 Clojure 言語は「データとしてのプログラムコード」 ( 英語 : 「 code as data 」 ) という思想で設計されており、洗練されたマクロ機構を持つ。

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

Wikipedia より

Page 4: Esm lt threading_macro

Clojure▸ Clojure ( 発音は /'klouʒər/[2], クロージャー ) はプログラミング言語であり、 LISP 系の言語の方言の一つである。関数型プログラミングのプログラミングスタイルでのインタラクティブな開発を支援し、マルチスレッドプログラムの開発を容易化する汎用言語である。 Clojure 言語のプログラムは Java 仮想マシンと Microsoft .NET 共通言語ランタイムで動作する。 Clojure 言語は「データとしてのプログラムコード」 ( 英語 : 「 code as data 」 ) という思想で設計されており、洗練されたマクロ機構を持つ。

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

Wikipedia より

Page 5: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

スレッディングマクロとはClojure の S 式だと(reduce + 100 (map #(* %1 2) (filter even? [1 2 3 4])))

Page 6: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

スレッディングマクロとはClojure の S 式だと(reduce + 100 (map #(* %1 2) (filter even? [1 2 3 4]))) こう実行されて

Page 7: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

スレッディングマクロとはClojure の S 式だと(reduce + 100 (map #(* %1 2) (filter even? [1 2 3 4])));;=> 112

こうなる

Page 8: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

スレッディングマクロとはスレッディングマクロだと(->> [1 2 3 4] (filter even?) (map #(* %1 2)) (reduce + 100))

Page 9: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

スレッディングマクロとはスレッディングマクロだと(->> [1 2 3 4] (filter even?) (map #(* %1 2)) (reduce + 100))

こう実行されて

Page 10: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

スレッディングマクロとはスレッディングマクロだと(->> [1 2 3 4] (filter even?) (map #(* %1 2)) (reduce + 100));;=> 112

こうなる

Page 11: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

スレッディングマクロの利点スレッディングマクロ(->> [1 2 3 4] (filter even?) (map #(* %1 2)) (reduce + 100))

S 式のみ(reduce + 100 (map #(* %1 2) (filter even? [1 2 3 4])))

Page 12: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

スレッディングマクロの利点スレッディングマクロ(->> [1 2 3 4] (filter even?) (map #(* %1 2)) (reduce + 100))

S 式のみ(reduce + 100 (map #(* %1 2) (filter even? [1 2 3 4])))

スレッディングマクロを使うと評価の時系列順に上から読むことが出来る

Page 13: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

他にもあるスレッディングマクロの利点Clojure の S 式だと(reduce + 100 (map #(* %1 2) (filter even? [1 2 3 4])))

Page 14: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

他にもあるスレッディングマクロの利点Clojure の S 式だと(reduce + 100..(map #(* %1 2)....(filter even?......[1 2 3 4])))

インデントはこうなる

Page 15: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

他にもあるスレッディングマクロの利点スレッディングマクロだと(->> [1 2 3 4] (filter even?) (map #(* %1 2)) (reduce + 100))

Page 16: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

他にもあるスレッディングマクロの利点スレッディングマクロだと(->>..[1 2 3 4]..(filter even?)..(map #(* %1 2))..(reduce + 100))

インデントはこうなる

Page 17: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

他にもあるスレッディングマクロの利点スレッディングマクロ(->> [1 2 3 4] (filter even?) (map #(* %1 2)) (reduce + 100))

S 式のみ(reduce + 100 (map #(* %1 2) (filter even? [1 2 3 4])))

Page 18: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

他にもあるスレッディングマクロの利点スレッディングマクロ(->>..[1 2 3 4]..(filter even?)..(map #(* %1 2))..(reduce + 100))

S 式のみ(reduce + 100..(map #(* %1 2)....(filter even?......[1 2 3 4])))

コードのインデントが深くならない

Page 19: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

スレッディングマクロの利点

他にも有るけど割愛

Page 20: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話についてesm LT 2016/10/07

Page 21: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話についてesm LT 2016/10/07

Page 22: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

第二部

esm LT 2016/10/07

Page 23: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

Ruby のラムダ式で S 式相当の処理を書くと…

Page 24: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

Ruby のラムダ式で S 式相当の処理を書くと…-> (collection) { collection.reduce(100, :+) }. call(-> (collection) { collection.map {|e| e * 2 } }. call(-> (collection) { collection.select(&:even?) }. call([1, 2, 3, 4])))

Page 25: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

Ruby のラムダ式で S 式相当の処理を書くと…-> (collection) { collection.reduce(100, :+) }. call(-> (collection) { collection.map {|e| e * 2 } }. call(-> (collection) { collection.select(&:even?) }. call([1, 2, 3, 4])))

これをスレッディングマクロっぽく書けるようにする

Page 26: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

基本のアイディア[ -> (collection) { collection.select(&:even?) }, -> (collection) { collection.map {|e| e * 2 } }, -> (collection) { collection.reduce(100, :+) }].reduce([1, 2, 3, 4]) { |acc, proc| proc.call(acc)}

Page 27: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

基本のアイディア[ -> (collection) { collection.select(&:even?) }, -> (collection) { collection.map {|e| e * 2 } }, -> (collection) { collection.reduce(100, :+) }].reduce([1, 2, 3, 4]) { |acc, proc| proc.call(acc)}

Proc の配列に対して

Page 28: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

基本のアイディア[ -> (collection) { collection.select(&:even?) }, -> (collection) { collection.map {|e| e * 2 } }, -> (collection) { collection.reduce(100, :+) }].reduce([1, 2, 3, 4]) { |acc, proc| proc.call(acc)}

Proc の配列に対して

reduce して、処理結果に順々に適用する

Page 29: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

基本のアイディア[ -> (collection) { collection.select(&:even?) }, -> (collection) { collection.map {|e| e * 2 } }, -> (collection) { collection.reduce(100, :+) }].reduce([1, 2, 3, 4]) { |acc, proc| proc.call(acc)}=> 112

Proc の配列に対して

reduce して、処理結果に順々に適用する

Page 30: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

とりあえずここまで実装してみるdef thread_last(*procs) procs[1..-1].reduce(procs.first) {|acc, proc| proc.call acc }end

Page 31: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

とりあえずここまで実装してみるdef thread_last(*procs) procs[1..-1].reduce(procs.first) {|acc, proc| proc.call acc }end

thread_last( [1,2,3,4], -> (collection) { collection.select(&:even?) }, -> (collection) { collection.map {|e| e * 2 } }, -> (collection) { collection.reduce(100, :+) })

Page 32: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

とりあえずここまで実装してみるdef thread_last(*procs) procs[1..-1].reduce(procs.first) {|acc, proc| proc.call acc }end

thread_last( [1,2,3,4], -> (collection) { collection.select(&:even?) }, -> (collection) { collection.map {|e| e * 2 } }, -> (collection) { collection.reduce(100, :+) })

=> 112

Page 33: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

とりあえずここまで実装してみるdef thread_last(*procs) procs[1..-1].reduce(procs.first) {|acc, proc| proc.call acc }end

thread_last( [1,2,3,4], -> (collection) { collection.select(&:even?) }, -> (collection) { collection.map {|e| e * 2 } }, -> (collection) { collection.reduce(100, :+) })

=> 112 出来た!

Page 34: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

基本のアイディア[ -> (collection) { collection.select(&:even?) }, -> (collection) { collection.map {|e| e * 2 } }, -> (collection) { collection.reduce(100, :+) }].reduce([1, 2, 3, 4]) { |acc, proc| proc.call(acc)}

Page 35: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

こんなときはどうする?[ -> (collection) { collection.select(&:even?) }, -> (n, collection) { collection.map {|e| e * n } }, -> (collection) { collection.reduce(100, :+) }].reduce([1, 2, 3, 4]) { |acc, proc| proc.call(acc)}

Page 36: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

こんなときはどうする?[ -> (collection) { collection.select(&:even?) }, -> (n, collection) { collection.map {|e| e * n } }, -> (collection) { collection.reduce(100, :+) }].reduce([1, 2, 3, 4]) { |acc, proc| proc.call(acc)} n を指定したい

Page 37: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

こんなときはどうする?[ -> (collection) { collection.select(&:even?) }, -> (n, collection) { collection.map {|e| e * n } }, -> (collection) { collection.reduce(100, :+) }].reduce([1, 2, 3, 4]) { |acc, proc| proc.call(acc)}ArgumentError: wrong number of arguments (given 1, expected 2)

Page 38: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

こんなときはどうする?[ -> (collection) { collection.select(&:even?) }, -> (n, collection) { collection.map {|e| e * n } }, -> (collection) { collection.reduce(100, :+) }].reduce([1, 2, 3, 4]) { |acc, proc| proc.call(acc)}ArgumentError: wrong number of arguments (given 1, expected 2)

一つの引数にだけProc を適用している

Page 39: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

こんなときは[ -> (collection) { collection.select(&:even?) }, -> (n, collection) { collection.map {|e| e * n } }, -> (collection) { collection.reduce(100, :+) }].reduce([1, 2, 3, 4]) { |acc, proc| proc.call(acc)}

Page 40: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

こんなときはこうする![ -> (collection) { collection.select(&:even?) }, -> (n, collection) { collection.map {|e| e * n } }.curry[2], -> (collection) { collection.reduce(100, :+) }].reduce([1, 2, 3, 4]) { |acc, proc| proc.call(acc)}

Page 41: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

こんなときはこうする![ -> (collection) { collection.select(&:even?) }, -> (n, collection) { collection.map {|e| e * n } }.curry[2], -> (collection) { collection.reduce(100, :+) }].reduce([1, 2, 3, 4]) { |acc, proc| proc.call(acc)}=> 112

Page 42: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

こんなときはこうする![ -> (collection) { collection.select(&:even?) }, -> (n, collection) { collection.map {|e| e * n } }.curry[2], -> (collection) { collection.reduce(100, :+) }].reduce([1, 2, 3, 4]) { |acc, proc| proc.call(acc)}

curry とは?

Page 43: Esm lt threading_macro

60sec で分かる ( と良いなと思う )カリー化と部分適用

Page 44: Esm lt threading_macro

60sec で分かる ( と良いなと思う ) カリー化と部分適用

カリー化とは関数がただ一つの引数だけをとるようにすること。この状態の関数をカリー化されていると呼ぶ。

2引数の関数はカリー化することで、引数の数が一つである関数と、その関数を返す引数の数が一つの関数に分けられる。

Page 45: Esm lt threading_macro

60sec で分かる ( と良いなと思う ) カリー化と部分適用

カリー化とはRuby で書くと…->(x, y) { x + y }.call(2, 3)=> 5

Page 46: Esm lt threading_macro

60sec で分かる ( と良いなと思う ) カリー化と部分適用

カリー化とはRuby で書くと…->(x, y) { x + y }.call(2, 3)=> 5

->(x) { -> (y) { x + y } }.call(2).call(3)=> 5

カリー化 ( 手動 )

Page 47: Esm lt threading_macro

60sec で分かる ( と良いなと思う ) カリー化と部分適用

カリー化とはRuby で書くと…->(x, y) { x + y }.call(2, 3)=> 5

->(x, y) { x + y }.curry[2][3]=> 5

カリー化

Page 48: Esm lt threading_macro

60sec で分かる ( と良いなと思う ) カリー化と部分適用

カリー化とはRuby で書くと…->(x, y) { x + y }.call(2, 3)

->(x, y) { x + y }.curry[2][3]

``-> (y) { 2 + y }`` 相当の Proc が返ってくる

カリー化

Page 49: Esm lt threading_macro

60sec で分かる ( と良いなと思う ) カリー化と部分適用

カリー化とは任意の数の引数の Proc をカリー化出来る

->(x, y, z) { x + y + z }.curry[2][3][4]=> 9->(x, y, z, xx, yy, zz) { x + y + z + xx + yy + zz }.curry[2][3][4][5][6][7]=> 27

Page 50: Esm lt threading_macro

60sec で分かる ( と良いなと思う ) カリー化と部分適用

カリー化とは途中で変数に取ることも出来る

partialized_proc = ->(x, y) { x + y }.curry[2]=> #<Proc:0x007feaa2f4c6f0 (lambda)>

partialized_proc[3]=> 5

Page 51: Esm lt threading_macro

60sec で分かる ( と良いなと思う ) カリー化と部分適用

カリー化とは途中で変数に取ることも出来る

partialized_proc = ->(x, y) { x + y }.curry[2]=> #<Proc:0x007feaa2f4c6f0 (lambda)>

partialized_proc[3]=> 5全ての引数が渡されると処理結果が返ってくる

Page 52: Esm lt threading_macro

60sec で分かる ( と良いなと思う ) カリー化と部分適用

部分適用とは部分適用とは、関数に対して全ての引数を一度に渡さず、一部の引数だけ渡すことができる仕組み。

Page 53: Esm lt threading_macro

60sec で分かる ( と良いなと思う ) カリー化と部分適用

部分適用とはpartialized_proc = ->(x, y) { x + y }.curry[2]=> #<Proc:0x007feaa2f4c6f0 (lambda)>partialized_proc[3]=> 5

Page 54: Esm lt threading_macro

60sec で分かる ( と良いなと思う ) カリー化と部分適用

部分適用とはpartialized_proc = ->(x, y) { x + y }.curry[2]=> #<Proc:0x007feaa2f4c6f0 (lambda)>partialized_proc[3]=> 5これが部分適用された状態の Proc

Page 55: Esm lt threading_macro

60sec で分かる ( と良いなと思う )カリー化と部分適用

Page 56: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

⚠ 注意事項

Page 57: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

⚠ 注意事項Clojure ではスレッディングマクロの実現にTransducers という機構を使用しています。

Page 58: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

⚠ 注意事項Clojure ではスレッディングマクロの実現にTransducers という機構を使用しています。

が、ここでは Transducers については触れません。

Page 59: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

この書き方を[ -> (collection) { collection.select(&:even?) }, -> (n, collection) { collection.map {|e| e * n } }.curry[2], -> (collection) { collection.reduce(100, :+) }].reduce([1, 2, 3, 4]) { |acc, proc| proc.call(acc)}

Page 60: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

thread_last に適用すると…thread_last( [1,2,3,4], -> (collection) { collection.select(&:even?) }, -> (n, collection) { collection.map {|e| e * n }.curry[2] }, -> (collection) { collection.reduce(100, :+) })

Page 61: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

thread_last に適用すると…thread_last( [1,2,3,4], -> (collection) { collection.select(&:even?) }, -> (n, collection) { collection.map {|e| e * n }.curry[2] }, -> (collection) { collection.reduce(100, :+) })=> 112

Page 62: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

thread_last に適用すると…thread_last( [1,2,3,4], -> (collection) { collection.select(&:even?) }, -> (n, collection) { collection.map {|e| e * n }.curry[2] }, -> (collection) { collection.reduce(100, :+) })=> 112 利用者が curry しないといけない

Page 63: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

いちいち curry したくない……

Page 64: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

いちいち curry したくない……class Proc def |(arg) self.curry[arg] endend

Page 65: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

いちいち curry したくない……class Proc def |(arg) self.curry[arg] endend

Proc に | メソッドを生やす

Page 66: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

いちいち curry したくない……class Proc def |(arg) self.curry[arg] endend

thread_last( [1,2,3,4], -> (collection) { collection.select(&:even?) }, -> (n, collection) { collection.map {|e| e * n } } | 2, -> (collection) { collection.reduce(100, :+) })

Proc に | メソッドを生やす

Page 67: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

いちいち curry したくない……class Proc def |(arg) self.curry[arg] endend

thread_last( [1,2,3,4], -> (collection) { collection.select(&:even?) }, -> (n, collection) { collection.map {|e| e * n } } | 2, -> (collection) { collection.reduce(100, :+) })

=> 112

Proc に | メソッドを生やす

Page 68: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

thread_last(->>) が出来た!

Page 69: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

thread_last(->>) が出来た!

Page 70: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

色々なスレッディングマクロ‣ ->‣ ->>‣ as->‣ some->‣ some->>‣ cond->‣ cond->>

Page 71: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

色々なスレッディングマクロ‣ ->‣ ->>‣ as->‣ some->‣ some->>‣ cond->‣ cond->>

まだまだ戦いは続く……

Page 72: Esm lt threading_macro

▸ 一番最初の値に Proc が来ることもある。ので、最初が Proc ならば実行する。もちろん引数の数が不定なのでcall ではなく curry で。

▸ Proc に生やした | メソッドで即時 curry していたけど、 thread_first(->) のときは実行する寸前までカリー化したくないので、実行時まで配列で持っているようにした。▸ thread_as(as->) するときは引数の挿入場所を選べる。シンボルで表現したいが Proc の結果がシンボルになることも有るので、表現しきれない。ので Proc に新たなメソッド & を生やした。かつ、挿入位置を表す型を用意した。▸ map とか reduce とかするラムダ式を一々書きたくない……ので、引数で受け取った Collection をレシーバーとして map を実行するメソッド _map(proc) が include したクラスの self に生えるようにした。 reduce,

select に関しても同様。▸ ↑ で作ったメソッドで、 Proc を渡したいときと Block を渡したいときがある。

▸ Clojure の ->> と同じようなメソッドのエイリアスを設けたいが、 - 始まりのメソッドは書けない。マルチバイトはいけるので、色々考えた結果これが一番近いと思う。 `` ー✈✈ ``

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

戦いの記録 ( ダイジェスト版 )

Page 73: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

色々やった結果-> (collection) { collection.reduce(100, :+) }. call(-> (collection) { collection.map {|e| e * 2 } }. call(-> (collection) { collection.select(&:even?) }. call([1, 2, 3, 4])))

Page 74: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

色々やった結果-> (collection) { collection.reduce(100, :+) }. call(-> (collection) { collection.map {|e| e * 2 } }. call(-> (collection) { collection.select(&:even?) }. call([1, 2, 3, 4])))

thread_last( [1, 2, 3, 4], _select(&:even?), _map(-> (e) { e * 2 }), _reduce(100, &:+))

Page 75: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

色々やった結果-> (collection) { collection.reduce(100, :+) }. call(-> (collection) { collection.map {|e| e * 2 } }. call(-> (collection) { collection.select(&:even?) }. call([1, 2, 3, 4])))

thread_last( [1, 2, 3, 4], _select(&:even?), _map(-> (e) { e * 2 }), _reduce(100, &:+)) ここまで短く簡潔に書ける!!!

Page 76: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

なお……

thread_last( [1, 2, 3, 4], _select(&:even?), _map(-> (e) { e * 2 }), _reduce(100, &:+))

Page 77: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

なお……

thread_last( [1, 2, 3, 4], _select(&:even?), _map(-> (e) { e * 2 }), _reduce(100, &:+))

このコードをラムダ式を使わずに普通に書くと……

Page 78: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

なお……[1, 2, 3, 4]. select(&:even?). map {|e| e * 2}. reduce(100, :+)

thread_last( [1, 2, 3, 4], _select(&:even?), _map(-> (e) { e * 2 }), _reduce(100, &:+))

このコードをラムダ式を使わずに普通に書くと……

Page 79: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

結論。

Page 80: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

結論。

素の Ruby すごい

Page 81: Esm lt threading_macro

Clojure のスレッディングマクロっぽいものを Ruby で実装してみた話について

第二部

esm LT 2016/10/07