iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 30
3
Software Development

認識scala系列 第 30

Scala day 30 (Functional Programming)

Functional Programming

今天是鐵人賽的最後一天,就來聊聊第一天說到的 scala 可以 Functional Programming 吧.Functional Programming 其實之前就已存在了,但為什麼最近又開始紅了起來了呢?
我覺得是因為大數據、machine learning、AI 等...技術越來越受到重視,而這些需要大量運算的環境下,無法只靠單執行緒處理運算.所以才會使用多執行緒、分散式運算、平行處理等來增加處理資料的速度.但使用這些技術解決運算速度問題的同時,也衍生出其他的問題.而 Functional Programming 是很適合用來解決這些問題,所以也越來越受到重視.

接著先介紹兩個蠻重要的觀念是Concurrency(並行)以及Parallelism(平行).

Concurrency

多個任務在一個 CPU(core) 上面執行,在時間內交互執行,會以為是同時處理多個工作.(multitasking on a single-core machine).

Parallelism

多個任務在多個 CPU(cores) 上面同時執行,同時處理多個工作.(tasks run at the same time on a multicore processor).

那面對 Concurrency 以及 Parallelism 的環境時.Imperative programming(C、C++、Java、Pythin) 在處理這些問題上就會顯得非常複雜.像 java 要寫 multi-thread 的程式時就要很小心,而且要避免一些問題,例如:deadlock.有很多共用變數或方法的地方又要加上 synchronize.所以光是處理這些問題就很令人頭痛,那會變成那麼複雜有一個很大的原因就是因為 Imperative programming 用到的變數幾乎都是 mutable 的.mutable 的變數代表它的值可以被改變、而且也可以被重新定義.那在 Concurrency 或 Parallelism 執行上,你無法確定 state 的狀況是什麼.這時候 immutable 及 pure function 的好處出來了,你不用擔心變數或function 在哪邊被重新定義了,因為 immutable 不可以被改變.所以 scala 的 collection 有 mutable 及 immutable.

Functional Programming 要點

開發程式時,幾乎都使用 pure functions,程式裡只使用 immutable values (scala 的 val).

Pure functions

  • pure function 的結果,只依賴於輸入的參數及內部算法
  • pure function 不會有 side effects(副作用),它不會讀取外部的東西,及寫入外部東西
  • 根據上面兩個性質來看,pure function 傳入的參數(假設是 x),不管呼叫幾次結果都會是一樣的(y)

Example

Imperative 的寫法(use var & for) :

def sum(nums: List[Int]): Int = {
  var sum = 0
  for (i <- nums) {
    sum += i }
  sum
}

val lst = List(1,2,3)
sum(lst) // Int = 6

Functional 的寫法(use match & recursion) :

def sums(xs: List[Int]): Int = xs match {
  case Nil => 0
  case x :: tail => x + sums(tail)
}
sums(lst) // Int = 6

Imperative 的寫法(use mutable collection & for) :

def double(ints: List[Int]): List[Int] = {
  val buffer = new scala.collection.mutable.ListBuffer[Int]()
  for (i <- ints) {
    buffer += i * 2
  }
  buffer.toList
}
val oldNumbers = List(1,2,3)
val newNumbers = double(oldNumbers) // List(2, 4, 6)

Functional 的寫法(use Higher Order Function(map)) :

val oldNumbers = List(1,2,3)
val newNumbers = oldNumbers.map(_ * 2) // List(2, 4, 6)

總結


  • Functional Programming 也是另一門很深奧的學問,尤其 OOP 寫久了之後,可能一時會轉不過來,這邊只是稍微跟大家提一下而已,有興趣的話大家再研究一下吧.
  • 在這 30 天介紹了許多 scala 的特色,也在最後一天也跟大家稍微介紹了一下FP.但其實還有許許多多的學問需要研究.我覺得會java的人,很值得也學習一下 scala 這個語言,可以激發出更多不一樣的想法不管是 OOP 或是 FP.鐵人賽結束了,希望這些文章能讓大家有一點點收穫,繼續前進 scala 的世界吧~加油!

上一篇
Scala day 29 (some collection method)
系列文
認識scala30

1 則留言

1
stana
iT邦新手 5 級 ‧ 2018-01-02 14:40:12

恭禧鐵人首度練成 XD

我要留言

立即登入留言