對函數語言程式設計的誤解

aqee發表於2012-09-21

  最近,我偶然看到了這樣一篇文章:實用的純函數語言程式設計,裡面談到了函數語言程式設計的優勢。然而,作者的某些對函數語言程式設計的思想認識卻讓我詫異:

“長期的處在指令式程式設計的環境世界裡會讓我們養成一種特定的順序式的思考方式 … 而另一邊,在純函式的世界裡,我們被強迫去思考的是如何變換資料。”

  作者辯論說,按照程式碼序列來思考程式執行的思考方式是指令式程式設計語言固有的特徵。文章中給出的第一個“命令式”的例子是一個簡單的Java迴圈:

 int sum(int[] list) {
	  int result = 0;
	  for (int i : list)
	    result += i;
	  return result;
	}

  問題在於,我可以用純函式程式語言寫出相同形式的這個例子。當然,這程式碼跟Haskell語言程式碼不是很相似,但你要知道,Haskell並不是唯一的純函式程式語言。例如,下面的這段程式碼:

int sum([int] list):
	    result = 0
	    for i in list:
	        result = result + i
	    return result

  這是一個最嚴格意義上的純函式(針對相同的輸入永遠都產生相同的輸出,沒有邊際效應,而且具有親系透徹性(referentially transparent)的。)這個函式是純函式,這是因為複合資料結構(例如list,set,map等)具有值語義(value semantics),它們的行為跟基本資料結構(例如int)一樣,而不是類似Java裡的那種對資料的引用。

  函式式風格

  我認為作者在文章裡把函式式語言和函式式風格(以函式為主要表達形式和計算方式)混淆了。沒錯,函式式風格更傾向於使用遞迴而不是迴圈。但這並不阻礙著函式式語言裡使用迴圈結構。

  關鍵還在於,很多命令式語言裡支援函數語言程式設計風格。換句話說,它不是函數語言程式設計語言的專利(儘管它們更適合)。我們應該清楚的區分這兩個概念,從而避免對函數語言程式設計語言和指令式程式設計語言之間的不同產生混淆。

  問題是有些人並不喜歡函式式風格。例如,我更喜歡使用迴圈(比如上面的sum()例子裡),因為這樣更加清晰,好理解。但是,對於有些東西(例如遍歷一個列表),我認為用遞迴更好。這是我的風格。。問題是,人們通常會認為,那些具有指令式程式設計習慣的人應該完全的轉換成函數語言程式設計語言風格。但事實上不需要這樣。一些主流的函數語言程式設計語言故意給指令式程式設計製造障礙。如果事情能變的簡單點,人們會慢慢的轉變他們的程式設計習慣,而不需要形式上的強迫…

  你對此有想法嗎?

  英文連結:A Misconception of Functional Programming?

相關文章