2008-10-18 20 views
20

我可以枚舉函數式編程的許多特性,但是當我的朋友問我時可以爲我定義函數式編程嗎?我不能。函數式編程的定義點

+0

可以使用C#,C++,Python,Perl等多種語言的函數式編程。但也有功能語言(LISP,ML等)。我想從你的問題中,我們需要關注各個地方的功能特性,而不僅僅是函數式語言...... – Cervo 2008-10-18 15:13:06

+0

它與馮諾依曼和教會的蘭姆達 – vrdhn 2012-03-03 16:07:56

回答

20

我會說純函數式編程的定義是,所有的計算都是在no副作用函數中完成的。也就是說,函數需要輸入和返回值,但不要改變任何隱藏狀態。在這個範例中,函數更接近地模擬他們的數學表兄弟。

當我開始玩Erlang,一種一次寫入堆棧的語言的時候,這個東西已經被釘住了。然而,應該澄清的是,編程範例和編程語言之間存在差異。通常被稱爲功能的語言提供了許多可以鼓勵或強化功能範例的功能(例如,具有一次寫入堆棧的Erlang,高階函數,閉包等)。然而,功能性編程範例可以用於許多語言(具有不同程度的痛苦)。

+0

我會補充說,你可以在許多常見的編程語言中做到這一點,而不是烏爾朗/其他功能語言。但簡而言之,這就是定義。 – Cervo 2008-10-18 15:14:55

+1

不正確。你指的是_pure_FP。有些FP沒有副作用。你[將FP與程序的分類結合起來,用IP與DP](http://stackoverflow.com/questions/602444/what-is-functional-claclarative-and-imperative-programming/8357604#8357604)。 – 2011-12-08 01:09:08

-1

這就像使用矢量而不是位圖繪製圖片 - 告訴畫家如何更改圖片,而不是在每一步中圖片的樣子。

它是應用功能而不是改變狀態。

8

wikipedia

在計算機科學中,功能性編程是一種編程範例,把作爲計算的數學函數評估,並且避免了狀態和可變數據。它強調功能的應用,與強調狀態變化的命令式編程風格形成鮮明對比。

使用功能的做法提供了以下好處:

  • 併發編程是函數式語言更容易。
  • FP中的函數永遠不會導致副作用 - 這使得單元測試更容易。
  • 生產環境中的熱代碼部署要容易得多。
  • 功能語言可以在數學上推理。懶惰評估提供了性能優化的潛力。
  • 更具表現力的 - 閉包,模式匹配,高級類型系統等,讓程序員更容易「說出他們的意思」。
  • 簡潔 - 對於某些類別的程序,功能性解決方案明顯更簡潔。

有一篇文章詳細介紹了更多細節here

3

我必須補充一點,函數式編程往往也會抽象出程序和控制域的控制結構 - 例如,你不再對某些事物列表做'for循環',而是用'映射'它一些功能來產生輸出。

我認爲函數式編程是一種精神狀態以及上面給出的定義。

-1

我認爲John Stauffer主要有這個定義。我還想補充一點,你需要能夠傳遞函數。基本上你需要高階函數,這意味着你可以輕鬆地傳遞函數(儘管傳遞塊足夠好)。

例如一個非常流行的函數調用是map。它基本上相當於

list is some list of items 
OutList is some empty list 
foreach item in list 
    OutList.append(function(item)) 
return OutList 

這樣代碼被表示爲map(函數,列表)。革命性的概念是功能是一種功能。 Javascript是高級函數語言的一個很好的例子。基本上,函數可以像變量一樣處理,並傳入函數或從函數返回。 C++和C具有可以類似使用的函數指針。 .NET委託也可以類似地使用。

那麼你能想到的各種很酷的抽象的...

你有一個功能AddItemsInList,MultiplyItemsInList等..?
每個函數接受(列表)並返回一個結果

您可以創建(注意,很多語言不允許你通過周圍+的功能,但它似乎要表達的概念,最清晰的方式)... 。

AggregateItemsInList(List, combinefunction, StepFunction) 

遞增函數索引上工作...最好是讓他們使用像下一個和下一個incTwo未來如果存在列表操作列表上的工作....

function incNormal(x) { 
    return x + 1 
} 

function incTwo(x) { 
    return x + 2 
} 

AggregateItemsInList(List, +, incNormal) 

旺旺去做每隔一個項目?

AggegateItemsInList(List, +, incTwo) 

要繁殖嗎?

AggregateItemsInList(List, *, incNormal) 

想要將考試分數加在一起嗎?

function AddScores (studenta, studentb) { 
    return studenta.score + studentb.score 
} 

AggregateItemsInList(ListOfStudents, AddScores, incOne) 

高階函數是一個非常強大的抽象。而不必爲數字,字符串,學生等編寫自定義方法。您有一個聚合方法循環遍歷任何列表,並且您只需爲每個數據類型創建添加操作。

12

到目前爲止,很多定義都強調純度,但有許多語言被認爲是功能性的,完全不是純粹的(例如,ML,Scheme)。我認爲,做一個語言的「功能性」的關鍵屬性是:

  1. 高階函數。函數是一個與整數和布爾值無關的內置數據類型。匿名功能很容易創建和習慣用法(例如,lambda)。
  2. 一切都是表達。在命令式語言中,區分變化狀態並影響控制流的語句和產生值的表達式。在功能語言(甚至不純的功能語言)中,表達評估是執行的基本單位。

給定這兩個屬性,你自然會得到我們認爲的功能(例如,用褶皺和地圖表示計算)的行爲。消除可變狀態是使事情變得更加有效的一種方式。

7

能夠枚舉這些特徵比試圖定義這個術語本身更有用,因爲人們會在各種環境中使用術語「功能性編程」,並在整個連續體中具有許多意義的陰影,而單個特徵具有個別更清晰的定義,這是更普遍的認同。

下面是想到的功能。大多數人使用術語「函數式編程」來指代那些特徵的一些子集(最常見/最重要的是「純度」和「高階函數」)。

FP特徵:

  • 純度(又名不變性,避開副作用,引用透明
  • 高階函數(例如傳遞函數作爲參數,作爲結果返回,定義匿名函數作爲lambda表達式)
  • 懶惰(又名。 非嚴格評價,最有用的/可用時與純度耦合)
  • 代數數據類型模式匹配
  • 瓶蓋
  • 討好/局部應用
  • 參數多態性(又名泛型
  • 遞歸(如純度的結果)
  • 編程與表達,而不是報表(又更爲突出,從純度)
  • ...

越從上述特徵你正在使用的列表,更有可能有人會標註你正在做的「功能編程」(以及前兩個功能 - 純度和高階功能 - 可能對你的「FP分數」來說是最值得的額外獎勵) 。

1

有兩個單獨的定義:

  • 年長的定義(第一類函數)由康威克里斯已經給出。

  • John Stauffer給出了更新的定義(避免像變異這樣的副作用)。這更一般地稱爲純粹的函數式編程。

這是一個很混亂的來源......