Slide 1

Slide 1 text

Clojureͷ εϨοσΟϯάϚΫϩ ͬΆ͍΋ͷΛRubyͰ࣮૷ͯ͠Έͨ࿩ ʹ͍ͭͯ esm LT 2016/10/07

Slide 2

Slide 2 text

ClojureͷεϨοσΟϯάϚΫϩͬΆ͍΋ͷΛRubyͰ࣮૷ͯ͠Έͨ࿩ʹ͍ͭͯ ࣗݾ঺հ ▸ ٱೲ ޻ ▸ 2006೥ೖࣾ ▸ ITαʔϏεࣄۀ෦

Slide 3

Slide 3 text

Clojure ▸ Clojure (ൃԻ͸/'klouʒər/[2], Ϋϩʔδϟʔ)͸ϓϩάϥϛϯάݴ ޠͰ͋ΓɺLISPܥͷݴޠͷํݴͷҰͭͰ͋Δɻؔ਺ܕϓϩάϥ ϛϯάͷϓϩάϥϛϯάελΠϧͰͷΠϯλϥΫςΟϒͳ։ൃ Λࢧԉ͠ɺϚϧνεϨουϓϩάϥϜͷ։ൃΛ༰қԽ͢Δ൚༻ ݴޠͰ͋ΔɻClojureݴޠͷϓϩάϥϜ͸JavaԾ૝Ϛγϯͱ Microsoft .NET ڞ௨ݴޠϥϯλΠϜͰಈ࡞͢ΔɻClojureݴޠ͸ ʮσʔλͱͯ͠ͷϓϩάϥϜίʔυʯ (ӳޠ:ʮcode as dataʯ) ͱ͍͏ࢥ૝Ͱઃܭ͞Ε͓ͯΓɺચ࿅͞ΕͨϚΫϩػߏΛ࣋ͭɻ ClojureͷεϨοσΟϯάϚΫϩͬΆ͍΋ͷΛRubyͰ࣮૷ͯ͠Έͨ࿩ʹ͍ͭͯ WikipediaΑΓ

Slide 4

Slide 4 text

Clojure ▸ Clojure (ൃԻ͸/'klouʒər/[2], Ϋϩʔδϟʔ)͸ϓϩάϥϛϯάݴ ޠͰ͋ΓɺLISPܥͷݴޠͷํݴͷҰͭͰ͋Δɻؔ਺ܕϓϩάϥ ϛϯάͷϓϩάϥϛϯάελΠϧͰͷΠϯλϥΫςΟϒͳ։ൃ Λࢧԉ͠ɺϚϧνεϨουϓϩάϥϜͷ։ൃΛ༰қԽ͢Δ൚༻ ݴޠͰ͋ΔɻClojureݴޠͷϓϩάϥϜ͸JavaԾ૝Ϛγϯͱ Microsoft .NET ڞ௨ݴޠϥϯλΠϜͰಈ࡞͢ΔɻClojureݴޠ͸ ʮσʔλͱͯ͠ͷϓϩάϥϜίʔυʯ (ӳޠ:ʮcode as dataʯ) ͱ͍͏ࢥ૝Ͱઃܭ͞Ε͓ͯΓɺચ࿅͞ΕͨϚΫϩػߏΛ࣋ͭɻ ClojureͷεϨοσΟϯάϚΫϩͬΆ͍΋ͷΛRubyͰ࣮૷ͯ͠Έͨ࿩ʹ͍ͭͯ WikipediaΑΓ

Slide 5

Slide 5 text

ClojureͷεϨοσΟϯάϚΫϩͬΆ͍΋ͷΛRubyͰ࣮૷ͯ͠Έͨ࿩ʹ͍ͭͯ εϨοσΟϯάϚΫϩͱ͸ ClojureͷSࣜͩͱ (reduce + 100 (map #(* %1 2) (filter even? [1 2 3 4])))

Slide 6

Slide 6 text

ClojureͷεϨοσΟϯάϚΫϩͬΆ͍΋ͷΛRubyͰ࣮૷ͯ͠Έͨ࿩ʹ͍ͭͯ εϨοσΟϯάϚΫϩͱ͸ ClojureͷSࣜͩͱ (reduce + 100 (map #(* %1 2) (filter even? [1 2 3 4]))) こう実行されて

Slide 7

Slide 7 text

ClojureͷεϨοσΟϯάϚΫϩͬΆ͍΋ͷΛRubyͰ࣮૷ͯ͠Έͨ࿩ʹ͍ͭͯ εϨοσΟϯάϚΫϩͱ͸ ClojureͷSࣜͩͱ (reduce + 100 (map #(* %1 2) (filter even? [1 2 3 4]))) ;;=> 112 こうなる

Slide 8

Slide 8 text

ClojureͷεϨοσΟϯάϚΫϩͬΆ͍΋ͷΛRubyͰ࣮૷ͯ͠Έͨ࿩ʹ͍ͭͯ εϨοσΟϯάϚΫϩͱ͸ εϨοσΟϯάϚΫϩͩͱ (->> [1 2 3 4] (filter even?) (map #(* %1 2)) (reduce + 100))

Slide 9

Slide 9 text

ClojureͷεϨοσΟϯάϚΫϩͬΆ͍΋ͷΛRubyͰ࣮૷ͯ͠Έͨ࿩ʹ͍ͭͯ εϨοσΟϯάϚΫϩͱ͸ εϨοσΟϯάϚΫϩͩͱ (->> [1 2 3 4] (filter even?) (map #(* %1 2)) (reduce + 100)) こう実行されて

Slide 10

Slide 10 text

ClojureͷεϨοσΟϯάϚΫϩͬΆ͍΋ͷΛRubyͰ࣮૷ͯ͠Έͨ࿩ʹ͍ͭͯ εϨοσΟϯάϚΫϩͱ͸ εϨοσΟϯάϚΫϩͩͱ (->> [1 2 3 4] (filter even?) (map #(* %1 2)) (reduce + 100)) ;;=> 112 こうなる

Slide 11

Slide 11 text

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])))

Slide 12

Slide 12 text

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]))) スレッディングマクロを使うと 評価の時系列順に上から読むことが出来る

Slide 13

Slide 13 text

ClojureͷεϨοσΟϯάϚΫϩͬΆ͍΋ͷΛRubyͰ࣮૷ͯ͠Έͨ࿩ʹ͍ͭͯ ଞʹ΋͋ΔεϨοσΟϯάϚΫϩͷར఺ ClojureͷSࣜͩͱ (reduce + 100 (map #(* %1 2) (filter even? [1 2 3 4])))

Slide 14

Slide 14 text

ClojureͷεϨοσΟϯάϚΫϩͬΆ͍΋ͷΛRubyͰ࣮૷ͯ͠Έͨ࿩ʹ͍ͭͯ ଞʹ΋͋ΔεϨοσΟϯάϚΫϩͷར఺ ClojureͷSࣜͩͱ (reduce + 100 ..(map #(* %1 2) ....(filter even? ......[1 2 3 4]))) インデントはこうなる

Slide 15

Slide 15 text

ClojureͷεϨοσΟϯάϚΫϩͬΆ͍΋ͷΛRubyͰ࣮૷ͯ͠Έͨ࿩ʹ͍ͭͯ ଞʹ΋͋ΔεϨοσΟϯάϚΫϩͷར఺ εϨοσΟϯάϚΫϩͩͱ (->> [1 2 3 4] (filter even?) (map #(* %1 2)) (reduce + 100))

Slide 16

Slide 16 text

ClojureͷεϨοσΟϯάϚΫϩͬΆ͍΋ͷΛRubyͰ࣮૷ͯ͠Έͨ࿩ʹ͍ͭͯ ଞʹ΋͋ΔεϨοσΟϯάϚΫϩͷར఺ εϨοσΟϯάϚΫϩͩͱ (->> ..[1 2 3 4] ..(filter even?) ..(map #(* %1 2)) ..(reduce + 100)) インデントはこうなる

Slide 17

Slide 17 text

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])))

Slide 18

Slide 18 text

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]))) コードのインデントが深くならない

Slide 19

Slide 19 text

ClojureͷεϨοσΟϯάϚΫϩͬΆ͍΋ͷΛRubyͰ࣮૷ͯ͠Έͨ࿩ʹ͍ͭͯ εϨοσΟϯάϚΫϩͷར఺ 他にも有るけど割愛

Slide 20

Slide 20 text

Clojureͷ εϨοσΟϯάϚΫϩ ͬΆ͍΋ͷΛRubyͰ࣮૷ͯ͠Έͨ࿩ ʹ͍ͭͯ esm LT 2016/10/07

Slide 21

Slide 21 text

Clojureͷ εϨοσΟϯάϚΫϩ ͬΆ͍΋ͷΛRubyͰ࣮૷ͯ͠Έͨ࿩ ʹ͍ͭͯ END esm LT 2016/10/07

Slide 22

Slide 22 text

Clojureͷ εϨοσΟϯάϚΫϩ ͬΆ͍΋ͷΛRubyͰ࣮૷ͯ͠Έͨ࿩ ʹ͍ͭͯ ୈೋ෦ esm LT 2016/10/07

Slide 23

Slide 23 text

ClojureͷεϨοσΟϯάϚΫϩͬΆ͍΋ͷΛRubyͰ࣮૷ͯ͠Έͨ࿩ʹ͍ͭͯ RubyͷϥϜμࣜͰSࣜ૬౰ͷॲཧΛॻ͘ͱ…

Slide 24

Slide 24 text

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])))

Slide 25

Slide 25 text

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]))) これをスレッディングマクロっぽく 書けるようにする

Slide 26

Slide 26 text

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)
 }

Slide 27

Slide 27 text

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の配列に対して

Slide 28

Slide 28 text

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して、処理結果に順々に適用する

Slide 29

Slide 29 text

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して、処理結果に順々に適用する

Slide 30

Slide 30 text

ClojureͷεϨοσΟϯάϚΫϩͬΆ͍΋ͷΛRubyͰ࣮૷ͯ͠Έͨ࿩ʹ͍ͭͯ ͱΓ͋͑ͣ͜͜·Ͱ࣮૷ͯ͠ΈΔ def thread_last(*procs)
 procs[1..-1].reduce(procs.first) {|acc, proc|
 proc.call acc
 }
 end

Slide 31

Slide 31 text

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, :+) }
 )

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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 出来た!

Slide 34

Slide 34 text

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)
 }

Slide 35

Slide 35 text

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)
 }

Slide 36

Slide 36 text

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を指定したい

Slide 37

Slide 37 text

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)

Slide 38

Slide 38 text

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を適用している

Slide 39

Slide 39 text

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)
 }

Slide 40

Slide 40 text

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)
 }

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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とは?

Slide 43

Slide 43 text

60sec Ͱ෼͔Δ(ͱྑ͍ͳͱࢥ͏) ΧϦʔԽͱ෦෼ద༻

Slide 44

Slide 44 text

60sec Ͱ෼͔Δ(ͱྑ͍ͳͱࢥ͏)ΧϦʔԽͱ෦෼ద༻ ΧϦʔԽͱ͸ 関数がただ一つの引数だけをとるようにすること。 この状態の関数をカリー化されていると呼ぶ。 2引数の関数はカリー化することで、引数の数が 一つである関数と、その関数を返す引数の数が一 つの関数に分けられる。

Slide 45

Slide 45 text

60sec Ͱ෼͔Δ(ͱྑ͍ͳͱࢥ͏)ΧϦʔԽͱ෦෼ద༻ ΧϦʔԽͱ͸ Ruby で書くと… ->(x, y) { x + y }.call(2, 3) => 5

Slide 46

Slide 46 text

60sec Ͱ෼͔Δ(ͱྑ͍ͳͱࢥ͏)ΧϦʔԽͱ෦෼ద༻ ΧϦʔԽͱ͸ Ruby で書くと… ->(x, y) { x + y }.call(2, 3) => 5 ->(x) { -> (y) { x + y } }.call(2).call(3) => 5 カリー化(手動)

Slide 47

Slide 47 text

60sec Ͱ෼͔Δ(ͱྑ͍ͳͱࢥ͏)ΧϦʔԽͱ෦෼ద༻ ΧϦʔԽͱ͸ Ruby で書くと… ->(x, y) { x + y }.call(2, 3) => 5 ->(x, y) { x + y }.curry[2][3] => 5 カリー化

Slide 48

Slide 48 text

60sec Ͱ෼͔Δ(ͱྑ͍ͳͱࢥ͏)ΧϦʔԽͱ෦෼ద༻ ΧϦʔԽͱ͸ Ruby で書くと… ->(x, y) { x + y }.call(2, 3) ->(x, y) { x + y }.curry[2][3] ``-> (y) { 2 + y }`` 相当のProcが返ってくる カリー化

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

60sec Ͱ෼͔Δ(ͱྑ͍ͳͱࢥ͏)ΧϦʔԽͱ෦෼ద༻ ΧϦʔԽͱ͸ 途中で変数に取ることも出来る partialized_proc = ->(x, y) { x + y }.curry[2] => # partialized_proc[3] => 5

Slide 51

Slide 51 text

60sec Ͱ෼͔Δ(ͱྑ͍ͳͱࢥ͏)ΧϦʔԽͱ෦෼ద༻ ΧϦʔԽͱ͸ 途中で変数に取ることも出来る partialized_proc = ->(x, y) { x + y }.curry[2] => # partialized_proc[3] => 5 全ての引数が渡されると処理結果が返ってくる

Slide 52

Slide 52 text

60sec Ͱ෼͔Δ(ͱྑ͍ͳͱࢥ͏)ΧϦʔԽͱ෦෼ద༻ ෦෼ద༻ͱ͸ 部分適用とは、関数に対して全ての引数を一度に 渡さず、一部の引数だけ渡すことができる仕組 み。

Slide 53

Slide 53 text

60sec Ͱ෼͔Δ(ͱྑ͍ͳͱࢥ͏)ΧϦʔԽͱ෦෼ద༻ ෦෼ద༻ͱ͸ partialized_proc = ->(x, y) { x + y }.curry[2] => # partialized_proc[3] => 5

Slide 54

Slide 54 text

60sec Ͱ෼͔Δ(ͱྑ͍ͳͱࢥ͏)ΧϦʔԽͱ෦෼ద༻ ෦෼ద༻ͱ͸ partialized_proc = ->(x, y) { x + y }.curry[2] => # partialized_proc[3] => 5 これが部分適用された状態のProc

Slide 55

Slide 55 text

60sec Ͱ෼͔Δ(ͱྑ͍ͳͱࢥ͏) ΧϦʔԽͱ෦෼ద༻ END

Slide 56

Slide 56 text

ClojureͷεϨοσΟϯάϚΫϩͬΆ͍΋ͷΛRubyͰ࣮૷ͯ͠Έͨ࿩ʹ͍ͭͯ ⾠஫ҙࣄ߲

Slide 57

Slide 57 text

ClojureͷεϨοσΟϯάϚΫϩͬΆ͍΋ͷΛRubyͰ࣮૷ͯ͠Έͨ࿩ʹ͍ͭͯ ⾠஫ҙࣄ߲ Clojureではスレッディングマクロの実現に Transducersという機構を使用しています。

Slide 58

Slide 58 text

ClojureͷεϨοσΟϯάϚΫϩͬΆ͍΋ͷΛRubyͰ࣮૷ͯ͠Έͨ࿩ʹ͍ͭͯ ⾠஫ҙࣄ߲ Clojureではスレッディングマクロの実現に Transducersという機構を使用しています。 が、ここではTransducersについては触れません。

Slide 59

Slide 59 text

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)
 }

Slide 60

Slide 60 text

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, :+) }
 )

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

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しないといけない

Slide 63

Slide 63 text

ClojureͷεϨοσΟϯάϚΫϩͬΆ͍΋ͷΛRubyͰ࣮૷ͯ͠Έͨ࿩ʹ͍ͭͯ ͍͍ͪͪcurryͨ͘͠ͳ͍……

Slide 64

Slide 64 text

ClojureͷεϨοσΟϯάϚΫϩͬΆ͍΋ͷΛRubyͰ࣮૷ͯ͠Έͨ࿩ʹ͍ͭͯ ͍͍ͪͪcurryͨ͘͠ͳ͍…… class Proc
 def |(arg)
 self.curry[arg]
 end
 end

Slide 65

Slide 65 text

ClojureͷεϨοσΟϯάϚΫϩͬΆ͍΋ͷΛRubyͰ࣮૷ͯ͠Έͨ࿩ʹ͍ͭͯ ͍͍ͪͪcurryͨ͘͠ͳ͍…… class Proc
 def |(arg)
 self.curry[arg]
 end
 end Procに | メソッドを生やす

Slide 66

Slide 66 text

ClojureͷεϨοσΟϯάϚΫϩͬΆ͍΋ͷΛRubyͰ࣮૷ͯ͠Έͨ࿩ʹ͍ͭͯ ͍͍ͪͪcurryͨ͘͠ͳ͍…… class Proc
 def |(arg)
 self.curry[arg]
 end
 end thread_last(
 [1,2,3,4],
 -> (collection) { collection.select(&:even?) },
 -> (n, collection) { collection.map {|e| e * n } } | 2,
 -> (collection) { collection.reduce(100, :+) }
 ) Procに | メソッドを生やす

Slide 67

Slide 67 text

ClojureͷεϨοσΟϯάϚΫϩͬΆ͍΋ͷΛRubyͰ࣮૷ͯ͠Έͨ࿩ʹ͍ͭͯ ͍͍ͪͪcurryͨ͘͠ͳ͍…… class Proc
 def |(arg)
 self.curry[arg]
 end
 end thread_last(
 [1,2,3,4],
 -> (collection) { collection.select(&:even?) },
 -> (n, collection) { collection.map {|e| e * n } } | 2,
 -> (collection) { collection.reduce(100, :+) }
 ) => 112 Procに | メソッドを生やす

Slide 68

Slide 68 text

ClojureͷεϨοσΟϯάϚΫϩͬΆ͍΋ͷΛRubyͰ࣮૷ͯ͠Έͨ࿩ʹ͍ͭͯ thread_last(->>) が出来た!

Slide 69

Slide 69 text

ClojureͷεϨοσΟϯάϚΫϩͬΆ͍΋ͷΛRubyͰ࣮૷ͯ͠Έͨ࿩ʹ͍ͭͯ thread_last(->>) が出来た!

Slide 70

Slide 70 text

ClojureͷεϨοσΟϯάϚΫϩͬΆ͍΋ͷΛRubyͰ࣮૷ͯ͠Έͨ࿩ʹ͍ͭͯ 色々なスレッディングマクロ ‣ ‣ ‣ BT ‣ TPNF ‣ TPNF ‣ DPOE ‣ DPOE

Slide 71

Slide 71 text

ClojureͷεϨοσΟϯάϚΫϩͬΆ͍΋ͷΛRubyͰ࣮૷ͯ͠Έͨ࿩ʹ͍ͭͯ 色々なスレッディングマクロ ‣ ‣ ‣ BT ‣ TPNF ‣ TPNF ‣ DPOE ‣ DPOE まだまだ戦いは続く……

Slide 72

Slide 72 text

▸ Ұ൪࠷ॳͷ஋ʹ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Ͱ࣮૷ͯ͠Έͨ࿩ʹ͍ͭͯ 戦いの記録(ダイジェスト版)

Slide 73

Slide 73 text

ClojureͷεϨοσΟϯάϚΫϩͬΆ͍΋ͷΛRubyͰ࣮૷ͯ͠Έͨ࿩ʹ͍ͭͯ ৭ʑ΍ͬͨ݁Ռ -> (collection) { collection.reduce(100, :+) }.
 call(-> (collection) { collection.map {|e| e * 2 } }.
 call(-> (collection) { collection.select(&:even?) }.
 call([1, 2, 3, 4]))) 
 
 
 


Slide 74

Slide 74 text

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, &:+)
 )

Slide 75

Slide 75 text

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, &:+)
 ) こ こ まで 短 く簡 潔 に 書 け る! ! !

Slide 76

Slide 76 text

ClojureͷεϨοσΟϯάϚΫϩͬΆ͍΋ͷΛRubyͰ࣮૷ͯ͠Έͨ࿩ʹ͍ͭͯ ͳ͓…… 
 
 
 thread_last(
 [1, 2, 3, 4],
 _select(&:even?),
 _map(-> (e) { e * 2 }),
 _reduce(100, &:+)
 )

Slide 77

Slide 77 text

ClojureͷεϨοσΟϯάϚΫϩͬΆ͍΋ͷΛRubyͰ࣮૷ͯ͠Έͨ࿩ʹ͍ͭͯ ͳ͓…… 
 
 thread_last(
 [1, 2, 3, 4],
 _select(&:even?),
 _map(-> (e) { e * 2 }),
 _reduce(100, &:+)
 ) このコードをラムダ式を使わずに 普通に書くと……

Slide 78

Slide 78 text

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, &:+)
 ) このコードをラムダ式を使わずに 普通に書くと……

Slide 79

Slide 79 text

ClojureͷεϨοσΟϯάϚΫϩͬΆ͍΋ͷΛRubyͰ࣮૷ͯ͠Έͨ࿩ʹ͍ͭͯ ݁࿦ɻ

Slide 80

Slide 80 text

ClojureͷεϨοσΟϯάϚΫϩͬΆ͍΋ͷΛRubyͰ࣮૷ͯ͠Έͨ࿩ʹ͍ͭͯ ݁࿦ɻ 素のRubyすごい

Slide 81

Slide 81 text

Clojureͷ εϨοσΟϯάϚΫϩ ͬΆ͍΋ͷΛRubyͰ࣮૷ͯ͠Έͨ࿩ ʹ͍ͭͯ ୈೋ෦ esm LT 2016/10/07 END