Scala函數編程讀書筆記(一)

前幾天在Manning網買了本《Functional Programming in Scala》電子書,正好趁春節長假好好學習一下。

這不是一本關於Scala編程的書,而是介紹函數編程(Functional Programming,簡稱FP)概念和原理的書,用Scala作爲示例,其原理可以用於任何一種函數編程語言,例如F#、Erlang、clojure等。而一些其他語言如Python、Ruby、Javascript等,對函數編程的支持都很強,一些函數編程原理也可以同樣適用於這些語言。

第一章 什麼是函數編程

"函數編程"是一種"編程範式"(programming paradigm),也就是如何編寫程序的方法論。它基於這樣一個簡單的限制條件:只用“純函數”編寫程序,換句話說,就是隻用沒有“副作用”的函數編程。

通常情況下,以下一些操作都會帶來副作用:

  • 修改變量
  • 修改數據結構
  • 設置對象的屬性
  • 捕獲異常
  • 控制檯輸入或者輸出
  • 讀寫一個文件
  • 往顯示屏上輸出

假設一個程序不能做以上任何事情,我們難以想象,這個程序還能有什麼用處。如果不能修改變量,那麼如何寫循環語句呢?函數編程就是告訴我們如何寫出不帶副作用的程序。事實證明,增加這種限制是有很多好處的,我們編寫的程序更加模塊化,純函數的程序更容易測試,重用,並行化。爲了獲得這些好處,我們必須轉變編程方式。

一個函數有一個類型A的輸入和B類型的輸出(在Scala中表示爲A => B),對於每個指定的類型A的值a,都有唯一一個對應的B類型的值b。

例如,intToString就是一個Int => String的函數,對於每個指定的Int類型的數,都輸出一個String類型的值。除此之外,它不做任何事情。換句話說,就是沒有可以察覺到的其他任何計算返回值以外的操作,我們稱這個函數爲“純函數”。其他的一些純函數比如“+”,對於任何給定的兩個整數,每次執行都會返回相同的一個整數。Java或者scala中String類型的length也是如此,其他還有很多這樣的純函數。

純函數可以用表達式取代另外一個表達式中的值,例如,x=3+5,那麼y=x+1 和 y=(3+5)+1 是完全等價的。非純函數就不是這樣了,下面用兩個例子說明它們之間的區別。

    scala> val x = "Hello, World"
    x: java.lang.String = Hello, World
    scala> val r1 = x.reverse
    r1: String = dlroW ,olleH
    scala> val r2 = x.reverse
    r2: String = dlroW ,olleH

    scala> val r1 = "Hello, World".reverse
    r1: String = dlroW ,olleH
    val r2 = "Hello, World".reverse
    r2: String = dlroW ,olleH

在這個例子中,reverse是一個純函數。reverse不會有副作用。

    scala> val x = new StringBuilder("Hello")
    x: java.lang.StringBuilder = Hello
    scala> val y = x.append(", World")
    y: java.lang.StringBuilder = Hello, World
    scala> val r1 = y.toString
    r1: java.lang.String = Hello, World
    scala> val r2 = y.toString
    r2: java.lang.String = Hello, World

    scala> val x = new StringBuilder("Hello")
    x: java.lang.StringBuilder = Hello
    scala> val r1 = x.append(", World").toString
    r1: java.lang.String = Hello, World
    scala> val r2 = x.append(", World").toString
    r2: java.lang.String = Hello, World, World

而在這裏例子中,append除了返回以外,還改變了x的值,帶來了副作用,因此它不是一個純函數。

增加了這樣限制的函數編程,給我們帶來了很大程度的模塊化。模塊化程序是可以理解的和可以重複使用的組件,它獨立於整體。這樣,整體的含義僅僅依賴於它的組件和它們之間組合的規則的含義。模塊可以看成是一個黑盒子,使得邏輯計算具有可重用性。後面的章節都是討論如何進行函數編程。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章