SlideShare ist ein Scribd-Unternehmen logo
1 von 92
Downloaden Sie, um offline zu lesen
那些 Functional
                  Programming 教我的事
                       ihower@gmail.com
                           2012/4/15
                           OSDC.TW




Sunday, April 15, 12
About Me

                       • 張文鈿 a.k.a. ihower
                       • Twitter: @ihower
                       • Ruby 熟手、Scala 初心者
                       • Ruby on Rails 源碼貢獻者
                       • 熱情豆行動樂活科技

Sunday, April 15, 12
Agenda


                       • 1. 為什麼想學FP?
                       • 2. FP有什麼特色?


Sunday, April 15, 12
Part1:

                   為什麼想學 Functional
                     Programming


Sunday, April 15, 12
Moore’s Law Ending
                         單核時脈無法再提昇了,多核架構是現在進行式




Sunday, April 15, 12
Single-Threading can’t
                               scale!




                                            4 Cores
Sunday, April 15, 12
Horizontal scaling
                       Q: 你的程式 Concurrency Ready 嗎?




Sunday, April 15, 12
Multithreading Program
                           Demo


          Example from: What All Rubyist Should Know About Threads (Jim Weirich, RubyConf 2008)
Sunday, April 15, 12
Thread-safe (1)


                       • 每個存取到的共享變數,都要
                        Synchronize




Sunday, April 15, 12
Thread safe (2)


                       • 操作必須注意 Atomic



Sunday, April 15, 12
Thread safe (3)


                       • 要有個策略可以避免 Deadlock



Sunday, April 15, 12
Thread safe (4)


                       • 每個你用到的 Library 都必須滿足上述規
                        則 (1)~(3)




Sunday, April 15, 12
另⼀一個問題...


                       • Synchronized 太多了,都是 blocking
                        threads,程式同時間只有⼀一個 thread 在
                        跑 :(




Sunday, April 15, 12
Multi-threading
                       Programing is Hard



Sunday, April 15, 12
Hard to program
                        只好讓團隊中最聰明的人去寫




Sunday, April 15, 12
Hard to test
                       測試無法窮舉各種情況,上線後不定時爆炸




Sunday, April 15, 12
會這麼難的根本原因:

                       Mutable shared state



Sunday, April 15, 12
如果有⼀一種程式語言



                       沒有 Mutable 變數




Sunday, April 15, 12
沒有 Mutable 變數,
                       那就不需要擔心 Synchronize
                            問題啦!!



Sunday, April 15, 12
Functional Programing
                           早在還沒有多核CPU的50年前




Sunday, April 15, 12
(Wikipedia)
     In computer science, functional
     programming is a programming paradigm
     that treats computation as the evaluation
     of mathematical functions and avoids state
     and mutable data. It emphasizes the
     application of functions, in contrast to the
     imperative programming style, which
     emphasizes changes in state.


Sunday, April 15, 12
(Wikipedia)
     In computer science, functional
     programming is a programming paradigm
     that treats computation as the evaluation
     of mathematical functions and avoids state
     and mutable data. It emphasizes the
     application of functions, in contrast to the
     imperative programming style, which
     emphasizes changes in state.


Sunday, April 15, 12
Functional Language
                           提供了開發
                       Concurrency program
                           的良好基礎

Sunday, April 15, 12
目前有哪些主流
                       Functional Language?


Sunday, April 15, 12
Erlang

                       • Ericsson Functional Language
                       • No mutable variable and side effects
                       • For distributed, reliable, soft real-time
                         highly concurrent systems.
                       • Use the Actor model of concurrency

Sunday, April 15, 12
Erlang 業界案例
                       • Facebook chat
                       • Github
                       • RabbitMQ
                       • NoSQL
                        • CouchDB, Riak, Membase

Sunday, April 15, 12
Clojure

                  • Lisp-like functional language
                  • JVM
                  • Use STM   (Software transactional memory)   for concurrency
                   • 記憶體層級的 ACI                  (Atomicity, Consistent, Isolation)




Sunday, April 15, 12
• Hybrid: Object-orient and functional
                       • JVM
                       • Use Akka (Actor and STM) for concurrency


Sunday, April 15, 12
Scala 業界案例

                       • Twitter
                       • LinkedIn



Sunday, April 15, 12
F#

                       • Microsoft’s functional language
                       • .NET
                       • OCaml-like



Sunday, April 15, 12
Haskell


                       • Pure Functional language 研究領域上的統⼀一
                        標準實作

                       • 紀念數學家 Haskell Curry


Sunday, April 15, 12
小結

                       • 多核時代,需要能 Concurrency 的程式
                       • 用程序性的OO語言寫 Concurrency 很難
                       • Functional Programing 讓 Concurrency
                         Programming 變簡單




Sunday, April 15, 12
Part2:

                       FP 的幾個特色



Sunday, April 15, 12
• 1. Avoiding Mutable State
                       • 2. Recursion
                       • 3. Higher-Order Functions
                       • 4. Function Composition
                       • 5. Lazy Evaluation
                       • 6. Pattern Matching

Sunday, April 15, 12
1. 避免 Mutable State



Sunday, April 15, 12
在FP語言中,變數指
                   派之後就是 immutable
                       ** Erlang R15B **
                       X = 1234.

                       X = 5678.
                       ** exception error: no match of
                       right hand side value 5678




Sunday, April 15, 12
在 Scala 中,使用 val
                            宣告變數
              val a = 1234

              a = 5678
              <console>:8: error: reassignment to val

              var b = 1234
              b = 5678
              5678


Sunday, April 15, 12
Persistent data
                             structure
                 • Immutable 的 Map, Hash, Set 等等
                 • 跟資料庫無關,而是因為其內部實作特性
                  • Produce new values by sharing structure
                       with existing values




Sunday, April 15, 12
Why need Immutable
                         data structure?

                       • No side-effects 的效能衝擊!!
                        • Copying overhead


Sunday, April 15, 12
Linked List
                       相加兩個List,會共享已有的資料




Sunday, April 15, 12
Tree   (內部實作)

                       建立新的Tree時,共享資料




Sunday, April 15, 12
Scala’s collection
            •          預設提供 Immutable 資料結構

                   •    List
                   •    Map
                   •    Vector
                   •    Set
            •          Mutable 的資料結構需要額外 import
                   •    scala.collection.mutable.LinkedList
                   •    scala.collection.mutable.Map
                   •    scala.collection.mutable.ArrayBuffer
                   •    scala.collection.mutable.Set


Sunday, April 15, 12
2. Recursion
                       遞迴只應天上有,凡人應當用迴圈?




Sunday, April 15, 12
Non-recursion
                               需要 result 變數

                       def factorial(n)
                         result = 1 # result 是變數
                         for i in 2..n
                           result = i * result
                         end

                         return result
                       end



Sunday, April 15, 12
Recursion
                         用 recursion 可以不需要中間變數



                       def factorial(n)
                         if (n==1)
                           return 1
                         else
                           return n * factorial(n-1)
                         end
                       end




Sunday, April 15, 12
Recursion?
                             但是 call stack 爆炸了?




                       > factorial(10000)
                       # SystemStackError: stack
                       level too deep




Sunday, April 15, 12
Tail-call optimization
                             FP程式語言會負責轉成 loop (例:Scala)




                       @tailrec def factorial(acc: Int, n: Int): Int = {
                         if (n <= 1) acc
                         else factorial(n * acc, n - 1)
                       }




Sunday, April 15, 12
3. Higher-Order
                       function 的應用



Sunday, April 15, 12
Function is first-class
                            value      ( JavaScript 例)




                         var sayHello = function(){
                            alert("Hello World!");
                         };

                         sayHello();




Sunday, April 15, 12
Higher-order function


                       • 可以把 function 做參數傳遞到 function 裡
                       • function 可以當做 function 回傳的結果


Sunday, April 15, 12
JavaScript     (ECMA5)   forEach
                        [2,3,5,6].forEach(
                           function(item){
                             console.log(item);
                           }
                        );

                        //   2
                        //   3
                        //   5
                        //   6


Sunday, April 15, 12
Callback method
                               ( Java 需要用 Anonymous inner class)



                       final Button button = new
                       Button(this);
                       button.setOnClickListener(
                        new View.OnClickListener() {
                            public void onClick(View v) {
                                "Hello, World!"
                        }}
                       );



Sunday, April 15, 12
JDK 8 開始支援
                              lambda
                       final Button button = new
                       Button(this);
                       button.setOnClickListener(
                          (View v) -> { "Hello" }
                       );




Sunday, April 15, 12
Combinator Functions

                       • 操作 Collection 的基本三招
                        • filter 去除某些元素,回傳新的容器
                        • map 轉變每個元素,回傳新的容器
                        • fold 迭代計算每個元素,回傳結果

Sunday, April 15, 12
範例:找出 Tickets 價格小於1000中,最高的價格


                        val tickets = List("a","b", "c")

                        def getPrice(ticket : String) = {
                            Map( "a" -> 1100, "b" -> 900, "c" -> 800 ).
                               get(ticket).getOrElse(0)
                        }

                        def Less1000(price: Int) = price < 1000

                        def pickHighPriced(price1: Int, price2: Int) =
                        {
                            if (price1 > price2) price1 else price2
                        }




Sunday, April 15, 12
傳統命令式流程
                       import scala.collection.mutable.ArrayBuffer
                       //抓出所有價格
                       val prices = new ArrayBuffer[Int]
                       for(ticket <- tickets) {
                           prices += getPrice(ticket)
                       }
                       //去除大於1000的
                       for(price <- prices){
                         if (!Less1000(price)) prices -= price
                       }
                       //跑迴圈找出最大值
                       var highestPrice = 0
                       for(price <- prices) {
                         highestPrice = pickHighPriced(highestPrice,
                       price)
                       }

                       highestPrice

Sunday, April 15, 12
Functional Style

                  val highestPrice =
                         tickets.map{ x => getPrice(x) }
                                .filter{ x => Less1000(x) }
         [“a”, “b”,”c”]         .reduce{ (x,y) => pickHighPriced(x,y) }




Sunday, April 15, 12
Functional Style
                                                              [1100, 900,800]
                       val highestPrice =
                              tickets.map{ x => getPrice(x) }
                                     .filter{ x => Less1000(x) }
                                     .reduce{ (x,y) => pickHighPriced(x,y) }




Sunday, April 15, 12
Functional Style

                       val highestPrice =                          [900,800]
                              tickets.map{ x => getPrice(x) }
                                     .filter{ x => Less1000(x) }
                                     .reduce{ (x,y) => pickHighPriced(x,y) }




Sunday, April 15, 12
Functional Style

                       val highestPrice =
                              tickets.map{ x => getPrice(x) }                  900
                                     .filter{ x => Less1000(x) }
                                     .reduce{ (x,y) => pickHighPriced(x,y) }




Sunday, April 15, 12
Scala 可以用 _ 簡化

                       val highestPrice = tickets.map{ getPrice(_) }
                                                 .filter{ Less1000(_) }
                                                 .reduce{
                       pickHighPriced(_,_) }




Sunday, April 15, 12
繼續簡化

            val higtestPrice =
            tickets.map.getPrice.filter.Less1000.reduce.pickHighPriced




Sunday, April 15, 12
Scala 可以用空隔做
                            method call
          val higtestPrice =
             tickets map getPrice filter Less1000 reduce pickHighPriced




Sunday, April 15, 12
State transformation
                       不需要 Mutate 變數就可以處理 Collection




Sunday, April 15, 12
4. Function Composition
                       拆解和組合函式




Sunday, April 15, 12
Partial Functions
                       固定某些參數,回傳新的 Function




Sunday, April 15, 12
Haskell
                       add x y = x + y
                       add 2 3
                       # 5

                       addTwo = add 2
                       addTwo 3
                       # 5




Sunday, April 15, 12
Scala
                                   用⼀一個 _ wildcard


                       def add(x:Int, y:Int) = x + y

                       val addTwo = add(2, _:Int)

                       addTwo(3)
                       //5




Sunday, April 15, 12
Currying
                              named after Haskell Curry



                       • 將⼀一個有 N 個參數的 function 轉換成
                        N 個只有⼀一個參數的 function 的過程




Sunday, April 15, 12
Haskell
                           每個 function 都是 Curried,其實都只有⼀一個參數



                       max 4 5

                       # 其實是
                       (max 4) 5

                       # max函式的宣告是
                       max :: Ord a => a -> (a -> a)
                       max 4 :: (Ord a, Num a) => a -> a



Sunday, April 15, 12
Haskell
                           每個 function 都是 Curried,其實都只有⼀一個參數



                       max 4 5
                                       (max 4) 先得到⼀一個
                       # 其實是         Partial Function,然後再
                                               帶入5
                       (max 4) 5

                       # max函式的宣告是
                       max :: Ord a => a -> (a -> a)
                       max 4 :: (Ord a, Num a) => a -> a



Sunday, April 15, 12
Scala
                       可以將函式定義成 Curried 形式

                       def sum(a: Int, b: Int) = a + b
                       sum(2, 3) // 5

                       def curriedSum(a: Int)(b: Int) = a * b
                       curriedSum(2)(3) // 5
                                                     curriedSum(2)
                                                  先得到⼀一個 Partial
                                                Function,然後再帶入3




Sunday, April 15, 12
Compose
                       把兩個⼀一個參數的 Function 合併起來
                         可以串聯多個組合成新的函數


                         f(g(x)) = (f。g)(x)




Sunday, April 15, 12
Haskell
                         中間的串列省掉了
                       reverse( sort [2,5,1,10,5] )

                       # -- the '.' operator is used to
                       compose functions
                       reverseSort = reverse . sort
                       reverseSort [2,5,1,10,5]




Sunday, April 15, 12
JavaScript
                            也可以自定 compose 方法




                       function compose(f, g) {
                         return function(x) {
                           return f(g(x));
                         }
                       }




Sunday, April 15, 12
5. Lazy evaluation

                 • 直到真的需要才執行
                  • 增加效率,減少沒有用到的計算
                  • 可以簡潔地表達無窮 list


Sunday, April 15, 12
Haskell is lazy
                        functional language
                       cycle [1,2,3]
                       # [1,2,3, 1,2,3, 1,2,3, 1,2,3, 1,2,3, 1,2,3,
                       1,2,3,....

                       take 10 (cycle [1,2,3])
                       # [1,2,3,1,2,3,1,2,3,1]"




Sunday, April 15, 12
Scala’s lazy val
                                useful for lazy initialization



                       val a = { println("evaluating A"); "A" }
                       // evaluating A
                       // a: java.lang.String = A



                       lazy val b = { println("evaluating B"); "B" }
                       // b: java.lang.String = <lazy>




Sunday, April 15, 12
Scala Stream (lazy list)
                            Scala 預設的 List 不是 Lazy



             def from(n: Int): Stream[Int] = Stream.cons( n, from(n+1) )
             lazy val odds = from(0).filter(_ % 2 == 1)

             odds.take(10).print
             // 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, empty




Sunday, April 15, 12
Ruby Enumerable::Lazy
                 容器不是 Lazy 的話,無窮元素就不能套 Combinator
                             functions 了

                  require 'prime'

                  Prime.to_a # 這樣是無窮數列...

                  Prime.take(10).to_a
                  # [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]

                  Prime.lazy.select{ |x| x % 4 == 3 }.take(10).to_a
                  # => [3, 7, 11, 19, 23, 31, 43, 47, 59, 67]




Sunday, April 15, 12
6. Pattern Matching

                       • 模式比對
                        • 比對兩個 expression 是否可以相同
                       • 用途
                        • 控制結構
                        • 指派變數

Sunday, April 15, 12
Erlang
                                  用來比對然後指派變數
               X.
               "1: variable 'X' is unbound"

               X = 2.

               {X, Y} = {1, 2}.
               "exception error: no match of right hand side value {1,2}"

               {X, Y} = {2, 3}.
               {2,3}

               Y.
               "此時 Y 是 3"




Sunday, April 15, 12
Erlang
                          來試試 List



                       [H|T] = [1,2,3,4,5].

                       H. "1"
                       T. "[2,3,4,5]"




Sunday, April 15, 12
Erlang (cont.)
                              來試試 List



                        [A,B,C|T] = [1,2,3,4,5].
                        A. "1"
                        B. "2"
                        C. "3"
                        T. "[4,5]"




Sunday, April 15, 12
Scala
                                       用 match 比對



                       import scala.util.Random

                       val randomInt = new Random().nextInt(10)

                       randomInt match {
                         case 7 => println("lucky seven")
                         case otherNumber => println("get " + otherNumber)
                       }




Sunday, April 15, 12
Scala
                                          可以比對 Type


                       val items = List(1, "foo", 3.5)

                       for (item <- items) {
                         item match {
                           case i: Int => println("got an Integer: " + i)
                           case s: String => println("got a String: " + s)
                           case f: Double => println("got a Double: " + f)
                           case other => println("got others: " + other)
                         }
                       }




Sunday, April 15, 12
Scala
                            可以加上 Guard 條件

      val t1 = ("A", "B")
      val t2 = ("C", "D")
      val t3 = ("E", "F")

      for( tuple <- List(t1, t2, t3) ) {
        tuple match {
          case (one, two) if one == "C" => println("得到開頭是C的tuple")
          case (one, two) => println("blah")
        }
      }

      // blah
      // Got tuple starting with C
      // blah


Sunday, April 15, 12
總結



Sunday, April 15, 12
Functional Style

               • 強調 immutability,避免 Function 的 Side-effects
               • 雖然還是無法完全避免 side-effects (例如IO),
                       但是 FP Style 降低了 Mutable State,增加程式
                       碼正確性和 Concurrency 能力。




Sunday, April 15, 12
要怎麼開始FP?
            •          Functional Programing 不同程度地混搭在各種程式語言之
                       中:
                  •      Java 也可以寫 FP Style
                  •      Scripting 語言(Ruby/Python/JavaScript) 也提供了很多 好
                         用的 FP 技巧
            •          但要學到 Avoid Mutable State 和 No-side Effects Function
                       的精髓,還是得試試 Functional 程式語言
                  •      建議多看看不同的 FP 語言,Lisp, Haskell, Scala, F# 概念
                         相通但語法差蠻多的


Sunday, April 15, 12
入門推薦書籍




Sunday, April 15, 12
Thanks.
                       • 感謝 @godfat (Haskell強者) 、大貓和
                        @idryman (Lisp 強者) 的指教

                       • 如果你有在寫FP,歡迎來找我聊聊、交
                        換名片,也許有機會來辦⼀一個 FP user
                        group 聚會 :-)




Sunday, April 15, 12

Más contenido relacionado

Was ist angesagt?

軟體開發之路甘苦談(Gelis)
軟體開發之路甘苦談(Gelis)軟體開發之路甘苦談(Gelis)
軟體開發之路甘苦談(Gelis)Gelis Wu
 
Linuxのsemaphoreとmutexを見る 
Linuxのsemaphoreとmutexを見る Linuxのsemaphoreとmutexを見る 
Linuxのsemaphoreとmutexを見る wata2ki
 
我的 DevOps 故事
我的 DevOps 故事我的 DevOps 故事
我的 DevOps 故事Poy Chang
 
eStargzイメージとlazy pullingによる高速なコンテナ起動
eStargzイメージとlazy pullingによる高速なコンテナ起動eStargzイメージとlazy pullingによる高速なコンテナ起動
eStargzイメージとlazy pullingによる高速なコンテナ起動Kohei Tokunaga
 
GraalVMの多言語実行機能が凄そうだったので試しにApache Sparkに組み込んで動かしてみたけどちょっとまだ早かったかもしれない(Open So...
GraalVMの多言語実行機能が凄そうだったので試しにApache Sparkに組み込んで動かしてみたけどちょっとまだ早かったかもしれない(Open So...GraalVMの多言語実行機能が凄そうだったので試しにApache Sparkに組み込んで動かしてみたけどちょっとまだ早かったかもしれない(Open So...
GraalVMの多言語実行機能が凄そうだったので試しにApache Sparkに組み込んで動かしてみたけどちょっとまだ早かったかもしれない(Open So...NTT DATA Technology & Innovation
 
Webアプリを並行開発する際のマイグレーション戦略
Webアプリを並行開発する際のマイグレーション戦略Webアプリを並行開発する際のマイグレーション戦略
Webアプリを並行開発する際のマイグレーション戦略Takayuki Shimizukawa
 
分散システムについて語らせてくれ
分散システムについて語らせてくれ分散システムについて語らせてくれ
分散システムについて語らせてくれKumazaki Hiroki
 
トランザクションの設計と進化
トランザクションの設計と進化トランザクションの設計と進化
トランザクションの設計と進化Kumazaki Hiroki
 
インフラエンジニアの綺麗で優しい手順書の書き方
インフラエンジニアの綺麗で優しい手順書の書き方インフラエンジニアの綺麗で優しい手順書の書き方
インフラエンジニアの綺麗で優しい手順書の書き方Shohei Koyama
 
BuildKitによる高速でセキュアなイメージビルド
BuildKitによる高速でセキュアなイメージビルドBuildKitによる高速でセキュアなイメージビルド
BuildKitによる高速でセキュアなイメージビルドAkihiro Suda
 
Linux KVMではじめるカンタン仮想化入門
Linux KVMではじめるカンタン仮想化入門Linux KVMではじめるカンタン仮想化入門
Linux KVMではじめるカンタン仮想化入門VirtualTech Japan Inc.
 
BHyVeってなんや
BHyVeってなんやBHyVeってなんや
BHyVeってなんやTakuya ASADA
 
型安全性入門
型安全性入門型安全性入門
型安全性入門Akinori Abe
 
【第26回Elasticsearch勉強会】Logstashとともに振り返る、やっちまった事例ごった煮
【第26回Elasticsearch勉強会】Logstashとともに振り返る、やっちまった事例ごった煮【第26回Elasticsearch勉強会】Logstashとともに振り返る、やっちまった事例ごった煮
【第26回Elasticsearch勉強会】Logstashとともに振り返る、やっちまった事例ごった煮Hibino Hisashi
 
シェル芸初心者によるシェル芸入門
シェル芸初心者によるシェル芸入門シェル芸初心者によるシェル芸入門
シェル芸初心者によるシェル芸入門icchy
 
ソーシャルゲームのためのデータベース設計
ソーシャルゲームのためのデータベース設計ソーシャルゲームのためのデータベース設計
ソーシャルゲームのためのデータベース設計Yoshinori Matsunobu
 
twMVC#18 | 專案分層架構
twMVC#18 | 專案分層架構twMVC#18 | 專案分層架構
twMVC#18 | 專案分層架構twMVC
 
GoによるWebアプリ開発のキホン
GoによるWebアプリ開発のキホンGoによるWebアプリ開発のキホン
GoによるWebアプリ開発のキホンAkihiko Horiuchi
 
なかったらINSERTしたいし、あるならロック取りたいやん?
なかったらINSERTしたいし、あるならロック取りたいやん?なかったらINSERTしたいし、あるならロック取りたいやん?
なかったらINSERTしたいし、あるならロック取りたいやん?ichirin2501
 

Was ist angesagt? (20)

軟體開發之路甘苦談(Gelis)
軟體開發之路甘苦談(Gelis)軟體開發之路甘苦談(Gelis)
軟體開發之路甘苦談(Gelis)
 
Linuxのsemaphoreとmutexを見る 
Linuxのsemaphoreとmutexを見る Linuxのsemaphoreとmutexを見る 
Linuxのsemaphoreとmutexを見る 
 
我的 DevOps 故事
我的 DevOps 故事我的 DevOps 故事
我的 DevOps 故事
 
eStargzイメージとlazy pullingによる高速なコンテナ起動
eStargzイメージとlazy pullingによる高速なコンテナ起動eStargzイメージとlazy pullingによる高速なコンテナ起動
eStargzイメージとlazy pullingによる高速なコンテナ起動
 
GraalVMの多言語実行機能が凄そうだったので試しにApache Sparkに組み込んで動かしてみたけどちょっとまだ早かったかもしれない(Open So...
GraalVMの多言語実行機能が凄そうだったので試しにApache Sparkに組み込んで動かしてみたけどちょっとまだ早かったかもしれない(Open So...GraalVMの多言語実行機能が凄そうだったので試しにApache Sparkに組み込んで動かしてみたけどちょっとまだ早かったかもしれない(Open So...
GraalVMの多言語実行機能が凄そうだったので試しにApache Sparkに組み込んで動かしてみたけどちょっとまだ早かったかもしれない(Open So...
 
Webアプリを並行開発する際のマイグレーション戦略
Webアプリを並行開発する際のマイグレーション戦略Webアプリを並行開発する際のマイグレーション戦略
Webアプリを並行開発する際のマイグレーション戦略
 
分散システムについて語らせてくれ
分散システムについて語らせてくれ分散システムについて語らせてくれ
分散システムについて語らせてくれ
 
トランザクションの設計と進化
トランザクションの設計と進化トランザクションの設計と進化
トランザクションの設計と進化
 
インフラエンジニアの綺麗で優しい手順書の書き方
インフラエンジニアの綺麗で優しい手順書の書き方インフラエンジニアの綺麗で優しい手順書の書き方
インフラエンジニアの綺麗で優しい手順書の書き方
 
ServiceとRepository
ServiceとRepositoryServiceとRepository
ServiceとRepository
 
BuildKitによる高速でセキュアなイメージビルド
BuildKitによる高速でセキュアなイメージビルドBuildKitによる高速でセキュアなイメージビルド
BuildKitによる高速でセキュアなイメージビルド
 
Linux KVMではじめるカンタン仮想化入門
Linux KVMではじめるカンタン仮想化入門Linux KVMではじめるカンタン仮想化入門
Linux KVMではじめるカンタン仮想化入門
 
BHyVeってなんや
BHyVeってなんやBHyVeってなんや
BHyVeってなんや
 
型安全性入門
型安全性入門型安全性入門
型安全性入門
 
【第26回Elasticsearch勉強会】Logstashとともに振り返る、やっちまった事例ごった煮
【第26回Elasticsearch勉強会】Logstashとともに振り返る、やっちまった事例ごった煮【第26回Elasticsearch勉強会】Logstashとともに振り返る、やっちまった事例ごった煮
【第26回Elasticsearch勉強会】Logstashとともに振り返る、やっちまった事例ごった煮
 
シェル芸初心者によるシェル芸入門
シェル芸初心者によるシェル芸入門シェル芸初心者によるシェル芸入門
シェル芸初心者によるシェル芸入門
 
ソーシャルゲームのためのデータベース設計
ソーシャルゲームのためのデータベース設計ソーシャルゲームのためのデータベース設計
ソーシャルゲームのためのデータベース設計
 
twMVC#18 | 專案分層架構
twMVC#18 | 專案分層架構twMVC#18 | 專案分層架構
twMVC#18 | 專案分層架構
 
GoによるWebアプリ開発のキホン
GoによるWebアプリ開発のキホンGoによるWebアプリ開発のキホン
GoによるWebアプリ開発のキホン
 
なかったらINSERTしたいし、あるならロック取りたいやん?
なかったらINSERTしたいし、あるならロック取りたいやん?なかったらINSERTしたいし、あるならロック取りたいやん?
なかったらINSERTしたいし、あるならロック取りたいやん?
 

Ähnlich wie 那些 Functional Programming 教我的事

[JVMLS 12] Kotlin / Java Interop
[JVMLS 12] Kotlin / Java Interop[JVMLS 12] Kotlin / Java Interop
[JVMLS 12] Kotlin / Java InteropAndrey Breslav
 
Node.js Patterns and Opinions
Node.js Patterns and OpinionsNode.js Patterns and Opinions
Node.js Patterns and OpinionsIsaacSchlueter
 
Intro to Laravel PHP Framework
Intro to Laravel PHP FrameworkIntro to Laravel PHP Framework
Intro to Laravel PHP FrameworkBill Condo
 
Enterprise javascriptsession1
Enterprise javascriptsession1Enterprise javascriptsession1
Enterprise javascriptsession1Troy Miles
 
Cassandra Day 2014: Interactive Analytics with Cassandra and Spark
Cassandra Day 2014: Interactive Analytics with Cassandra and SparkCassandra Day 2014: Interactive Analytics with Cassandra and Spark
Cassandra Day 2014: Interactive Analytics with Cassandra and SparkEvan Chan
 
Future Programming Languages
Future Programming LanguagesFuture Programming Languages
Future Programming LanguagesAlcides Fonseca
 
Ruby on Rails (RoR) as a back-end processor for Apex
Ruby on Rails (RoR) as a back-end processor for Apex Ruby on Rails (RoR) as a back-end processor for Apex
Ruby on Rails (RoR) as a back-end processor for Apex Espen Brækken
 
Journey to 1000 tests a day
Journey to 1000 tests a dayJourney to 1000 tests a day
Journey to 1000 tests a dayBruce McLeod
 
static ABAP code analyzers
static ABAP code analyzersstatic ABAP code analyzers
static ABAP code analyzersMarkus Theilen
 
Cloud Foundry the Open PaaS - OpenTour Austin Keynote
Cloud Foundry the Open PaaS - OpenTour Austin KeynoteCloud Foundry the Open PaaS - OpenTour Austin Keynote
Cloud Foundry the Open PaaS - OpenTour Austin KeynotePatrick Chanezon
 
Software Libraries And Numbers
Software Libraries And NumbersSoftware Libraries And Numbers
Software Libraries And NumbersRobert Reiz
 
Scala adoption by enterprises
Scala adoption by enterprisesScala adoption by enterprises
Scala adoption by enterprisesMike Slinn
 
Polyglot and functional (Devoxx Nov/2011)
Polyglot and functional (Devoxx Nov/2011)Polyglot and functional (Devoxx Nov/2011)
Polyglot and functional (Devoxx Nov/2011)Martijn Verburg
 
Pinterest arch summit august 2012 - scaling pinterest
Pinterest arch summit   august 2012 - scaling pinterestPinterest arch summit   august 2012 - scaling pinterest
Pinterest arch summit august 2012 - scaling pinterestdrewz lin
 
LiveRebel + Pragmatic Continuous Delivery (Arcusys)
LiveRebel + Pragmatic Continuous Delivery (Arcusys)LiveRebel + Pragmatic Continuous Delivery (Arcusys)
LiveRebel + Pragmatic Continuous Delivery (Arcusys)Neeme Praks
 
GitHub Notable OSS Project
GitHub  Notable OSS ProjectGitHub  Notable OSS Project
GitHub Notable OSS Projectroumia
 
Experience Converting from Ruby to Scala
Experience Converting from Ruby to ScalaExperience Converting from Ruby to Scala
Experience Converting from Ruby to ScalaJohn Nestor
 

Ähnlich wie 那些 Functional Programming 教我的事 (20)

[JVMLS 12] Kotlin / Java Interop
[JVMLS 12] Kotlin / Java Interop[JVMLS 12] Kotlin / Java Interop
[JVMLS 12] Kotlin / Java Interop
 
Node.js Patterns and Opinions
Node.js Patterns and OpinionsNode.js Patterns and Opinions
Node.js Patterns and Opinions
 
Intro to Laravel PHP Framework
Intro to Laravel PHP FrameworkIntro to Laravel PHP Framework
Intro to Laravel PHP Framework
 
Stardog talk-dc-march-17
Stardog talk-dc-march-17Stardog talk-dc-march-17
Stardog talk-dc-march-17
 
Scala
ScalaScala
Scala
 
Enterprise javascriptsession1
Enterprise javascriptsession1Enterprise javascriptsession1
Enterprise javascriptsession1
 
Cassandra Day 2014: Interactive Analytics with Cassandra and Spark
Cassandra Day 2014: Interactive Analytics with Cassandra and SparkCassandra Day 2014: Interactive Analytics with Cassandra and Spark
Cassandra Day 2014: Interactive Analytics with Cassandra and Spark
 
Future Programming Languages
Future Programming LanguagesFuture Programming Languages
Future Programming Languages
 
Ruby on Rails (RoR) as a back-end processor for Apex
Ruby on Rails (RoR) as a back-end processor for Apex Ruby on Rails (RoR) as a back-end processor for Apex
Ruby on Rails (RoR) as a back-end processor for Apex
 
Journey to 1000 tests a day
Journey to 1000 tests a dayJourney to 1000 tests a day
Journey to 1000 tests a day
 
static ABAP code analyzers
static ABAP code analyzersstatic ABAP code analyzers
static ABAP code analyzers
 
eZ Publish nextgen
eZ Publish nextgeneZ Publish nextgen
eZ Publish nextgen
 
Cloud Foundry the Open PaaS - OpenTour Austin Keynote
Cloud Foundry the Open PaaS - OpenTour Austin KeynoteCloud Foundry the Open PaaS - OpenTour Austin Keynote
Cloud Foundry the Open PaaS - OpenTour Austin Keynote
 
Software Libraries And Numbers
Software Libraries And NumbersSoftware Libraries And Numbers
Software Libraries And Numbers
 
Scala adoption by enterprises
Scala adoption by enterprisesScala adoption by enterprises
Scala adoption by enterprises
 
Polyglot and functional (Devoxx Nov/2011)
Polyglot and functional (Devoxx Nov/2011)Polyglot and functional (Devoxx Nov/2011)
Polyglot and functional (Devoxx Nov/2011)
 
Pinterest arch summit august 2012 - scaling pinterest
Pinterest arch summit   august 2012 - scaling pinterestPinterest arch summit   august 2012 - scaling pinterest
Pinterest arch summit august 2012 - scaling pinterest
 
LiveRebel + Pragmatic Continuous Delivery (Arcusys)
LiveRebel + Pragmatic Continuous Delivery (Arcusys)LiveRebel + Pragmatic Continuous Delivery (Arcusys)
LiveRebel + Pragmatic Continuous Delivery (Arcusys)
 
GitHub Notable OSS Project
GitHub  Notable OSS ProjectGitHub  Notable OSS Project
GitHub Notable OSS Project
 
Experience Converting from Ruby to Scala
Experience Converting from Ruby to ScalaExperience Converting from Ruby to Scala
Experience Converting from Ruby to Scala
 

Mehr von Wen-Tien Chang

⼤語⾔模型 LLM 應⽤開發入⾨
⼤語⾔模型 LLM 應⽤開發入⾨⼤語⾔模型 LLM 應⽤開發入⾨
⼤語⾔模型 LLM 應⽤開發入⾨Wen-Tien Chang
 
Ruby Rails 老司機帶飛
Ruby Rails 老司機帶飛Ruby Rails 老司機帶飛
Ruby Rails 老司機帶飛Wen-Tien Chang
 
A brief introduction to Machine Learning
A brief introduction to Machine LearningA brief introduction to Machine Learning
A brief introduction to Machine LearningWen-Tien Chang
 
淺談 Startup 公司的軟體開發流程 v2
淺談 Startup 公司的軟體開發流程 v2淺談 Startup 公司的軟體開發流程 v2
淺談 Startup 公司的軟體開發流程 v2Wen-Tien Chang
 
RSpec on Rails Tutorial
RSpec on Rails TutorialRSpec on Rails Tutorial
RSpec on Rails TutorialWen-Tien Chang
 
ALPHAhackathon: How to collaborate
ALPHAhackathon: How to collaborateALPHAhackathon: How to collaborate
ALPHAhackathon: How to collaborateWen-Tien Chang
 
Git 版本控制系統 -- 從微觀到宏觀
Git 版本控制系統 -- 從微觀到宏觀Git 版本控制系統 -- 從微觀到宏觀
Git 版本控制系統 -- 從微觀到宏觀Wen-Tien Chang
 
Exception Handling: Designing Robust Software in Ruby (with presentation note)
Exception Handling: Designing Robust Software in Ruby (with presentation note)Exception Handling: Designing Robust Software in Ruby (with presentation note)
Exception Handling: Designing Robust Software in Ruby (with presentation note)Wen-Tien Chang
 
Exception Handling: Designing Robust Software in Ruby
Exception Handling: Designing Robust Software in RubyException Handling: Designing Robust Software in Ruby
Exception Handling: Designing Robust Software in RubyWen-Tien Chang
 
從 Classes 到 Objects: 那些 OOP 教我的事
從 Classes 到 Objects: 那些 OOP 教我的事從 Classes 到 Objects: 那些 OOP 教我的事
從 Classes 到 Objects: 那些 OOP 教我的事Wen-Tien Chang
 
Yet another introduction to Git - from the bottom up
Yet another introduction to Git - from the bottom upYet another introduction to Git - from the bottom up
Yet another introduction to Git - from the bottom upWen-Tien Chang
 
A brief introduction to Vagrant – 原來 VirtualBox 可以這樣玩
A brief introduction to Vagrant – 原來 VirtualBox 可以這樣玩A brief introduction to Vagrant – 原來 VirtualBox 可以這樣玩
A brief introduction to Vagrant – 原來 VirtualBox 可以這樣玩Wen-Tien Chang
 
Ruby 程式語言綜覽簡介
Ruby 程式語言綜覽簡介Ruby 程式語言綜覽簡介
Ruby 程式語言綜覽簡介Wen-Tien Chang
 
A brief introduction to SPDY - 邁向 HTTP/2.0
A brief introduction to SPDY - 邁向 HTTP/2.0A brief introduction to SPDY - 邁向 HTTP/2.0
A brief introduction to SPDY - 邁向 HTTP/2.0Wen-Tien Chang
 
RubyConf Taiwan 2012 Opening & Closing
RubyConf Taiwan 2012 Opening & ClosingRubyConf Taiwan 2012 Opening & Closing
RubyConf Taiwan 2012 Opening & ClosingWen-Tien Chang
 
從 Scrum 到 Kanban: 為什麼 Scrum 不適合 Lean Startup
從 Scrum 到 Kanban: 為什麼 Scrum 不適合 Lean Startup從 Scrum 到 Kanban: 為什麼 Scrum 不適合 Lean Startup
從 Scrum 到 Kanban: 為什麼 Scrum 不適合 Lean StartupWen-Tien Chang
 
RubyConf Taiwan 2011 Opening & Closing
RubyConf Taiwan 2011 Opening & ClosingRubyConf Taiwan 2011 Opening & Closing
RubyConf Taiwan 2011 Opening & ClosingWen-Tien Chang
 
BDD style Unit Testing
BDD style Unit TestingBDD style Unit Testing
BDD style Unit TestingWen-Tien Chang
 

Mehr von Wen-Tien Chang (20)

⼤語⾔模型 LLM 應⽤開發入⾨
⼤語⾔模型 LLM 應⽤開發入⾨⼤語⾔模型 LLM 應⽤開發入⾨
⼤語⾔模型 LLM 應⽤開發入⾨
 
Ruby Rails 老司機帶飛
Ruby Rails 老司機帶飛Ruby Rails 老司機帶飛
Ruby Rails 老司機帶飛
 
A brief introduction to Machine Learning
A brief introduction to Machine LearningA brief introduction to Machine Learning
A brief introduction to Machine Learning
 
淺談 Startup 公司的軟體開發流程 v2
淺談 Startup 公司的軟體開發流程 v2淺談 Startup 公司的軟體開發流程 v2
淺談 Startup 公司的軟體開發流程 v2
 
RSpec on Rails Tutorial
RSpec on Rails TutorialRSpec on Rails Tutorial
RSpec on Rails Tutorial
 
RSpec & TDD Tutorial
RSpec & TDD TutorialRSpec & TDD Tutorial
RSpec & TDD Tutorial
 
ALPHAhackathon: How to collaborate
ALPHAhackathon: How to collaborateALPHAhackathon: How to collaborate
ALPHAhackathon: How to collaborate
 
Git 版本控制系統 -- 從微觀到宏觀
Git 版本控制系統 -- 從微觀到宏觀Git 版本控制系統 -- 從微觀到宏觀
Git 版本控制系統 -- 從微觀到宏觀
 
Exception Handling: Designing Robust Software in Ruby (with presentation note)
Exception Handling: Designing Robust Software in Ruby (with presentation note)Exception Handling: Designing Robust Software in Ruby (with presentation note)
Exception Handling: Designing Robust Software in Ruby (with presentation note)
 
Exception Handling: Designing Robust Software in Ruby
Exception Handling: Designing Robust Software in RubyException Handling: Designing Robust Software in Ruby
Exception Handling: Designing Robust Software in Ruby
 
從 Classes 到 Objects: 那些 OOP 教我的事
從 Classes 到 Objects: 那些 OOP 教我的事從 Classes 到 Objects: 那些 OOP 教我的事
從 Classes 到 Objects: 那些 OOP 教我的事
 
Yet another introduction to Git - from the bottom up
Yet another introduction to Git - from the bottom upYet another introduction to Git - from the bottom up
Yet another introduction to Git - from the bottom up
 
A brief introduction to Vagrant – 原來 VirtualBox 可以這樣玩
A brief introduction to Vagrant – 原來 VirtualBox 可以這樣玩A brief introduction to Vagrant – 原來 VirtualBox 可以這樣玩
A brief introduction to Vagrant – 原來 VirtualBox 可以這樣玩
 
Ruby 程式語言綜覽簡介
Ruby 程式語言綜覽簡介Ruby 程式語言綜覽簡介
Ruby 程式語言綜覽簡介
 
A brief introduction to SPDY - 邁向 HTTP/2.0
A brief introduction to SPDY - 邁向 HTTP/2.0A brief introduction to SPDY - 邁向 HTTP/2.0
A brief introduction to SPDY - 邁向 HTTP/2.0
 
RubyConf Taiwan 2012 Opening & Closing
RubyConf Taiwan 2012 Opening & ClosingRubyConf Taiwan 2012 Opening & Closing
RubyConf Taiwan 2012 Opening & Closing
 
從 Scrum 到 Kanban: 為什麼 Scrum 不適合 Lean Startup
從 Scrum 到 Kanban: 為什麼 Scrum 不適合 Lean Startup從 Scrum 到 Kanban: 為什麼 Scrum 不適合 Lean Startup
從 Scrum 到 Kanban: 為什麼 Scrum 不適合 Lean Startup
 
Git Tutorial 教學
Git Tutorial 教學Git Tutorial 教學
Git Tutorial 教學
 
RubyConf Taiwan 2011 Opening & Closing
RubyConf Taiwan 2011 Opening & ClosingRubyConf Taiwan 2011 Opening & Closing
RubyConf Taiwan 2011 Opening & Closing
 
BDD style Unit Testing
BDD style Unit TestingBDD style Unit Testing
BDD style Unit Testing
 

那些 Functional Programming 教我的事

  • 1. 那些 Functional Programming 教我的事 ihower@gmail.com 2012/4/15 OSDC.TW Sunday, April 15, 12
  • 2. About Me • 張文鈿 a.k.a. ihower • Twitter: @ihower • Ruby 熟手、Scala 初心者 • Ruby on Rails 源碼貢獻者 • 熱情豆行動樂活科技 Sunday, April 15, 12
  • 3. Agenda • 1. 為什麼想學FP? • 2. FP有什麼特色? Sunday, April 15, 12
  • 4. Part1: 為什麼想學 Functional Programming Sunday, April 15, 12
  • 5. Moore’s Law Ending 單核時脈無法再提昇了,多核架構是現在進行式 Sunday, April 15, 12
  • 6. Single-Threading can’t scale! 4 Cores Sunday, April 15, 12
  • 7. Horizontal scaling Q: 你的程式 Concurrency Ready 嗎? Sunday, April 15, 12
  • 8. Multithreading Program Demo Example from: What All Rubyist Should Know About Threads (Jim Weirich, RubyConf 2008) Sunday, April 15, 12
  • 9. Thread-safe (1) • 每個存取到的共享變數,都要 Synchronize Sunday, April 15, 12
  • 10. Thread safe (2) • 操作必須注意 Atomic Sunday, April 15, 12
  • 11. Thread safe (3) • 要有個策略可以避免 Deadlock Sunday, April 15, 12
  • 12. Thread safe (4) • 每個你用到的 Library 都必須滿足上述規 則 (1)~(3) Sunday, April 15, 12
  • 13. 另⼀一個問題... • Synchronized 太多了,都是 blocking threads,程式同時間只有⼀一個 thread 在 跑 :( Sunday, April 15, 12
  • 14. Multi-threading Programing is Hard Sunday, April 15, 12
  • 15. Hard to program 只好讓團隊中最聰明的人去寫 Sunday, April 15, 12
  • 16. Hard to test 測試無法窮舉各種情況,上線後不定時爆炸 Sunday, April 15, 12
  • 17. 會這麼難的根本原因: Mutable shared state Sunday, April 15, 12
  • 18. 如果有⼀一種程式語言 沒有 Mutable 變數 Sunday, April 15, 12
  • 19. 沒有 Mutable 變數, 那就不需要擔心 Synchronize 問題啦!! Sunday, April 15, 12
  • 20. Functional Programing 早在還沒有多核CPU的50年前 Sunday, April 15, 12
  • 21. (Wikipedia) In computer science, functional programming is a programming paradigm that treats computation as the evaluation of mathematical functions and avoids state and mutable data. It emphasizes the application of functions, in contrast to the imperative programming style, which emphasizes changes in state. Sunday, April 15, 12
  • 22. (Wikipedia) In computer science, functional programming is a programming paradigm that treats computation as the evaluation of mathematical functions and avoids state and mutable data. It emphasizes the application of functions, in contrast to the imperative programming style, which emphasizes changes in state. Sunday, April 15, 12
  • 23. Functional Language 提供了開發 Concurrency program 的良好基礎 Sunday, April 15, 12
  • 24. 目前有哪些主流 Functional Language? Sunday, April 15, 12
  • 25. Erlang • Ericsson Functional Language • No mutable variable and side effects • For distributed, reliable, soft real-time highly concurrent systems. • Use the Actor model of concurrency Sunday, April 15, 12
  • 26. Erlang 業界案例 • Facebook chat • Github • RabbitMQ • NoSQL • CouchDB, Riak, Membase Sunday, April 15, 12
  • 27. Clojure • Lisp-like functional language • JVM • Use STM (Software transactional memory) for concurrency • 記憶體層級的 ACI (Atomicity, Consistent, Isolation) Sunday, April 15, 12
  • 28. • Hybrid: Object-orient and functional • JVM • Use Akka (Actor and STM) for concurrency Sunday, April 15, 12
  • 29. Scala 業界案例 • Twitter • LinkedIn Sunday, April 15, 12
  • 30. F# • Microsoft’s functional language • .NET • OCaml-like Sunday, April 15, 12
  • 31. Haskell • Pure Functional language 研究領域上的統⼀一 標準實作 • 紀念數學家 Haskell Curry Sunday, April 15, 12
  • 32. 小結 • 多核時代,需要能 Concurrency 的程式 • 用程序性的OO語言寫 Concurrency 很難 • Functional Programing 讓 Concurrency Programming 變簡單 Sunday, April 15, 12
  • 33. Part2: FP 的幾個特色 Sunday, April 15, 12
  • 34. • 1. Avoiding Mutable State • 2. Recursion • 3. Higher-Order Functions • 4. Function Composition • 5. Lazy Evaluation • 6. Pattern Matching Sunday, April 15, 12
  • 35. 1. 避免 Mutable State Sunday, April 15, 12
  • 36. 在FP語言中,變數指 派之後就是 immutable ** Erlang R15B ** X = 1234. X = 5678. ** exception error: no match of right hand side value 5678 Sunday, April 15, 12
  • 37. 在 Scala 中,使用 val 宣告變數 val a = 1234 a = 5678 <console>:8: error: reassignment to val var b = 1234 b = 5678 5678 Sunday, April 15, 12
  • 38. Persistent data structure • Immutable 的 Map, Hash, Set 等等 • 跟資料庫無關,而是因為其內部實作特性 • Produce new values by sharing structure with existing values Sunday, April 15, 12
  • 39. Why need Immutable data structure? • No side-effects 的效能衝擊!! • Copying overhead Sunday, April 15, 12
  • 40. Linked List 相加兩個List,會共享已有的資料 Sunday, April 15, 12
  • 41. Tree (內部實作) 建立新的Tree時,共享資料 Sunday, April 15, 12
  • 42. Scala’s collection • 預設提供 Immutable 資料結構 • List • Map • Vector • Set • Mutable 的資料結構需要額外 import • scala.collection.mutable.LinkedList • scala.collection.mutable.Map • scala.collection.mutable.ArrayBuffer • scala.collection.mutable.Set Sunday, April 15, 12
  • 43. 2. Recursion 遞迴只應天上有,凡人應當用迴圈? Sunday, April 15, 12
  • 44. Non-recursion 需要 result 變數 def factorial(n) result = 1 # result 是變數 for i in 2..n result = i * result end return result end Sunday, April 15, 12
  • 45. Recursion 用 recursion 可以不需要中間變數 def factorial(n) if (n==1) return 1 else return n * factorial(n-1) end end Sunday, April 15, 12
  • 46. Recursion? 但是 call stack 爆炸了? > factorial(10000) # SystemStackError: stack level too deep Sunday, April 15, 12
  • 47. Tail-call optimization FP程式語言會負責轉成 loop (例:Scala) @tailrec def factorial(acc: Int, n: Int): Int = { if (n <= 1) acc else factorial(n * acc, n - 1) } Sunday, April 15, 12
  • 48. 3. Higher-Order function 的應用 Sunday, April 15, 12
  • 49. Function is first-class value ( JavaScript 例) var sayHello = function(){ alert("Hello World!"); }; sayHello(); Sunday, April 15, 12
  • 50. Higher-order function • 可以把 function 做參數傳遞到 function 裡 • function 可以當做 function 回傳的結果 Sunday, April 15, 12
  • 51. JavaScript (ECMA5) forEach [2,3,5,6].forEach( function(item){ console.log(item); } ); // 2 // 3 // 5 // 6 Sunday, April 15, 12
  • 52. Callback method ( Java 需要用 Anonymous inner class) final Button button = new Button(this); button.setOnClickListener( new View.OnClickListener() { public void onClick(View v) { "Hello, World!" }} ); Sunday, April 15, 12
  • 53. JDK 8 開始支援 lambda final Button button = new Button(this); button.setOnClickListener( (View v) -> { "Hello" } ); Sunday, April 15, 12
  • 54. Combinator Functions • 操作 Collection 的基本三招 • filter 去除某些元素,回傳新的容器 • map 轉變每個元素,回傳新的容器 • fold 迭代計算每個元素,回傳結果 Sunday, April 15, 12
  • 55. 範例:找出 Tickets 價格小於1000中,最高的價格 val tickets = List("a","b", "c") def getPrice(ticket : String) = { Map( "a" -> 1100, "b" -> 900, "c" -> 800 ). get(ticket).getOrElse(0) } def Less1000(price: Int) = price < 1000 def pickHighPriced(price1: Int, price2: Int) = { if (price1 > price2) price1 else price2 } Sunday, April 15, 12
  • 56. 傳統命令式流程 import scala.collection.mutable.ArrayBuffer //抓出所有價格 val prices = new ArrayBuffer[Int] for(ticket <- tickets) { prices += getPrice(ticket) } //去除大於1000的 for(price <- prices){ if (!Less1000(price)) prices -= price } //跑迴圈找出最大值 var highestPrice = 0 for(price <- prices) { highestPrice = pickHighPriced(highestPrice, price) } highestPrice Sunday, April 15, 12
  • 57. Functional Style val highestPrice = tickets.map{ x => getPrice(x) } .filter{ x => Less1000(x) } [“a”, “b”,”c”] .reduce{ (x,y) => pickHighPriced(x,y) } Sunday, April 15, 12
  • 58. Functional Style [1100, 900,800] val highestPrice = tickets.map{ x => getPrice(x) } .filter{ x => Less1000(x) } .reduce{ (x,y) => pickHighPriced(x,y) } Sunday, April 15, 12
  • 59. Functional Style val highestPrice = [900,800] tickets.map{ x => getPrice(x) } .filter{ x => Less1000(x) } .reduce{ (x,y) => pickHighPriced(x,y) } Sunday, April 15, 12
  • 60. Functional Style val highestPrice = tickets.map{ x => getPrice(x) } 900 .filter{ x => Less1000(x) } .reduce{ (x,y) => pickHighPriced(x,y) } Sunday, April 15, 12
  • 61. Scala 可以用 _ 簡化 val highestPrice = tickets.map{ getPrice(_) } .filter{ Less1000(_) } .reduce{ pickHighPriced(_,_) } Sunday, April 15, 12
  • 62. 繼續簡化 val higtestPrice = tickets.map.getPrice.filter.Less1000.reduce.pickHighPriced Sunday, April 15, 12
  • 63. Scala 可以用空隔做 method call val higtestPrice = tickets map getPrice filter Less1000 reduce pickHighPriced Sunday, April 15, 12
  • 64. State transformation 不需要 Mutate 變數就可以處理 Collection Sunday, April 15, 12
  • 65. 4. Function Composition 拆解和組合函式 Sunday, April 15, 12
  • 66. Partial Functions 固定某些參數,回傳新的 Function Sunday, April 15, 12
  • 67. Haskell add x y = x + y add 2 3 # 5 addTwo = add 2 addTwo 3 # 5 Sunday, April 15, 12
  • 68. Scala 用⼀一個 _ wildcard def add(x:Int, y:Int) = x + y val addTwo = add(2, _:Int) addTwo(3) //5 Sunday, April 15, 12
  • 69. Currying named after Haskell Curry • 將⼀一個有 N 個參數的 function 轉換成 N 個只有⼀一個參數的 function 的過程 Sunday, April 15, 12
  • 70. Haskell 每個 function 都是 Curried,其實都只有⼀一個參數 max 4 5 # 其實是 (max 4) 5 # max函式的宣告是 max :: Ord a => a -> (a -> a) max 4 :: (Ord a, Num a) => a -> a Sunday, April 15, 12
  • 71. Haskell 每個 function 都是 Curried,其實都只有⼀一個參數 max 4 5 (max 4) 先得到⼀一個 # 其實是 Partial Function,然後再 帶入5 (max 4) 5 # max函式的宣告是 max :: Ord a => a -> (a -> a) max 4 :: (Ord a, Num a) => a -> a Sunday, April 15, 12
  • 72. Scala 可以將函式定義成 Curried 形式 def sum(a: Int, b: Int) = a + b sum(2, 3) // 5 def curriedSum(a: Int)(b: Int) = a * b curriedSum(2)(3) // 5 curriedSum(2) 先得到⼀一個 Partial Function,然後再帶入3 Sunday, April 15, 12
  • 73. Compose 把兩個⼀一個參數的 Function 合併起來 可以串聯多個組合成新的函數 f(g(x)) = (f。g)(x) Sunday, April 15, 12
  • 74. Haskell 中間的串列省掉了 reverse( sort [2,5,1,10,5] ) # -- the '.' operator is used to compose functions reverseSort = reverse . sort reverseSort [2,5,1,10,5] Sunday, April 15, 12
  • 75. JavaScript 也可以自定 compose 方法 function compose(f, g) { return function(x) { return f(g(x)); } } Sunday, April 15, 12
  • 76. 5. Lazy evaluation • 直到真的需要才執行 • 增加效率,減少沒有用到的計算 • 可以簡潔地表達無窮 list Sunday, April 15, 12
  • 77. Haskell is lazy functional language cycle [1,2,3] # [1,2,3, 1,2,3, 1,2,3, 1,2,3, 1,2,3, 1,2,3, 1,2,3,.... take 10 (cycle [1,2,3]) # [1,2,3,1,2,3,1,2,3,1]" Sunday, April 15, 12
  • 78. Scala’s lazy val useful for lazy initialization val a = { println("evaluating A"); "A" } // evaluating A // a: java.lang.String = A lazy val b = { println("evaluating B"); "B" } // b: java.lang.String = <lazy> Sunday, April 15, 12
  • 79. Scala Stream (lazy list) Scala 預設的 List 不是 Lazy def from(n: Int): Stream[Int] = Stream.cons( n, from(n+1) ) lazy val odds = from(0).filter(_ % 2 == 1) odds.take(10).print // 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, empty Sunday, April 15, 12
  • 80. Ruby Enumerable::Lazy 容器不是 Lazy 的話,無窮元素就不能套 Combinator functions 了 require 'prime' Prime.to_a # 這樣是無窮數列... Prime.take(10).to_a # [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] Prime.lazy.select{ |x| x % 4 == 3 }.take(10).to_a # => [3, 7, 11, 19, 23, 31, 43, 47, 59, 67] Sunday, April 15, 12
  • 81. 6. Pattern Matching • 模式比對 • 比對兩個 expression 是否可以相同 • 用途 • 控制結構 • 指派變數 Sunday, April 15, 12
  • 82. Erlang 用來比對然後指派變數 X. "1: variable 'X' is unbound" X = 2. {X, Y} = {1, 2}. "exception error: no match of right hand side value {1,2}" {X, Y} = {2, 3}. {2,3} Y. "此時 Y 是 3" Sunday, April 15, 12
  • 83. Erlang 來試試 List [H|T] = [1,2,3,4,5]. H. "1" T. "[2,3,4,5]" Sunday, April 15, 12
  • 84. Erlang (cont.) 來試試 List [A,B,C|T] = [1,2,3,4,5]. A. "1" B. "2" C. "3" T. "[4,5]" Sunday, April 15, 12
  • 85. Scala 用 match 比對 import scala.util.Random val randomInt = new Random().nextInt(10) randomInt match { case 7 => println("lucky seven") case otherNumber => println("get " + otherNumber) } Sunday, April 15, 12
  • 86. Scala 可以比對 Type val items = List(1, "foo", 3.5) for (item <- items) { item match { case i: Int => println("got an Integer: " + i) case s: String => println("got a String: " + s) case f: Double => println("got a Double: " + f) case other => println("got others: " + other) } } Sunday, April 15, 12
  • 87. Scala 可以加上 Guard 條件 val t1 = ("A", "B") val t2 = ("C", "D") val t3 = ("E", "F") for( tuple <- List(t1, t2, t3) ) { tuple match { case (one, two) if one == "C" => println("得到開頭是C的tuple") case (one, two) => println("blah") } } // blah // Got tuple starting with C // blah Sunday, April 15, 12
  • 89. Functional Style • 強調 immutability,避免 Function 的 Side-effects • 雖然還是無法完全避免 side-effects (例如IO), 但是 FP Style 降低了 Mutable State,增加程式 碼正確性和 Concurrency 能力。 Sunday, April 15, 12
  • 90. 要怎麼開始FP? • Functional Programing 不同程度地混搭在各種程式語言之 中: • Java 也可以寫 FP Style • Scripting 語言(Ruby/Python/JavaScript) 也提供了很多 好 用的 FP 技巧 • 但要學到 Avoid Mutable State 和 No-side Effects Function 的精髓,還是得試試 Functional 程式語言 • 建議多看看不同的 FP 語言,Lisp, Haskell, Scala, F# 概念 相通但語法差蠻多的 Sunday, April 15, 12
  • 92. Thanks. • 感謝 @godfat (Haskell強者) 、大貓和 @idryman (Lisp 強者) 的指教 • 如果你有在寫FP,歡迎來找我聊聊、交 換名片,也許有機會來辦⼀一個 FP user group 聚會 :-) Sunday, April 15, 12