真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

再談編程范式—程序語言背后的思想

編程范式

托馬斯.庫爾提出“科學的革命”的范式論后,Robert Floyd在1979年圖靈獎的頒獎演說中使用了編程范式一詞。編程范式一般包括三個方面,以OOP為例:

創(chuàng)新互聯(lián)專注于企業(yè)成都全網(wǎng)營銷、網(wǎng)站重做改版、淮安網(wǎng)站定制設計、自適應品牌網(wǎng)站建設、H5網(wǎng)站設計、商城開發(fā)、集團公司官網(wǎng)建設、成都外貿(mào)網(wǎng)站制作、高端網(wǎng)站制作、響應式網(wǎng)頁設計等建站業(yè)務,價格優(yōu)惠性價比高,為淮安等各大城市提供網(wǎng)站開發(fā)制作服務。

1,學科的邏輯體系——規(guī)則范式:如 類/對象、繼承、動態(tài)綁定、方法改寫、對象替換等等機制。

2,心理認知因素——心理范式:按照面向對象編程之父Alan Kay的觀點,“計算就是模擬”。OO范式極其重視隱喻(metaphor)的價值,通過擬人化,按照自然的方式模擬自然。

3,自然觀/世界觀——觀念范式:強調程序的組織技術,視程序為松散耦合的對象/類的組合,以繼承機制將類組織成一個層次結構,把程序運行視為相互服務的對象之間的對話。

簡單來說,編程范式是程序員看待程序應該具有的觀點,代表了程序設計者認為程序應該如何被構建和執(zhí)行的看法。

常見的編程范式有:命令式、過程式、說明式、面向對象、函數(shù)式、泛型編程等。

Imperative—命令式||過程式

馮諾依曼 機器語言、匯編語言 BASIC COBOL C Ada FORTRAN?Fortran ,

腳本式?Perl Python PHP,把用其他語言開發(fā)的獨立程序作為部件“粘到一起”

面向對象?Smalltalk C++ Java,將計算建立在獨立的對象的相互作用至上。每個對象有其自身的內(nèi)部狀態(tài),以及管理自身狀態(tài)的可執(zhí)行子程序

Declarative—說明式||聲明式

函數(shù)式? Lisp ML Haskell?,程序被看作是一種從輸入到輸出的函數(shù)

數(shù)據(jù)流? ld Val,語言將計算看成在一些基本的功能結點之間流動的信息流。結點由輸入單詞的到達觸發(fā),能夠并發(fā)操作

邏輯式? Prolog,設法根據(jù)一集邏輯規(guī)則找出滿足某些特定關系的值

基于模板的?XSLT xml html,

需要提醒的是:編程范式是編程語言的一種分類方式,它并不針對某種編程語言。就編程語言而言,一種語言可以適用多種編程范式。

一些編程語言是專門為某種特定范式設計的,例如C語言是過程式編程語言;Smalltalk和Java是較純粹的面向對象編程語言;Haskell是純粹的函數(shù)式編程語言。另外一些編程語言和編程范式的關系并不一一對應,如Python,Scala,Groovy都支持面向對象和一定程度上的函數(shù)式編程。C++是多范式編程語言成功的典范。C++支持和C語言一樣的過程式編程范式,同時也支持面向對象編程范式,STL(Standard Template Library)使C++具有了泛型編程能力。支持多種范式可能是C++直到現(xiàn)在仍然具有強大的生命力的原因之一。

Swift是一門典型的多范式編程語言,即支持面向對象編程范式,也支持函數(shù)式編程范式,同時還支持泛型編程。Swift支持多種編程范式是由其創(chuàng)造目標決定的。Swift創(chuàng)造的初衷就是提供一門實用的工業(yè)語言。不同于Haskell這類出自大學和研究機構的學術性質的編程語言?!痢痢脸鯯wift時就帶著著明確的商業(yè)目的:Mac OS和iOS系統(tǒng)的主要編程語言Objective-C已顯老態(tài),Swift將使得蘋果系統(tǒng)的開發(fā)者擁有一門更現(xiàn)代的編程語言,從而促進蘋果整個生態(tài)圈的良性發(fā)展。

命令式編程:

命令式編程的主要思想是關注計算機執(zhí)行的步驟,即一步一步告訴計算機先做什么再做什么。

從本質上講,它是“馮.諾依曼機”運行機制的抽象,它的編程思想方式源于計算機指令的順序排列。

(也就是說:過程化語言模擬的是計算機機器的系統(tǒng)構造,而并不是基于語言的使用者的個人能力和傾向。這一點我們應該都很清楚,比如我們最早曾經(jīng)使用過的單片機的匯編語言。)

不管你用的是 C, C++ 還是 C#, Java, Javascript, BASIC, Python, Ruby 等等,你都可以以這個方式寫。

程序流程圖是命令式語言進行程序編寫的有效輔助手段。

命令式語言特別適合解決線性(或者說按部就班)的算法問題。它強調“自上而下(自頂向下)”“精益求精”的設計方式。這種方式非常類似我們的工作和生活方式,因為我們的日常活動都是按部就班的順序進行的。?

命令式語言趨向于開發(fā)運行較快且對系統(tǒng)資源利用率較高的程序。命令式語言非常的靈活并強大,同時有許多經(jīng)典應用范例,這使得程序員可以用它來解決多種問題。?

命令式語言的不足之處就是它不適合某些種類問題的解決,例如那些非結構化的具有復雜算法的問題。問題出現(xiàn)在,命令式語言必須對一個算法加以詳盡的說明,并且其中還要包括執(zhí)行這些指令或語句的順序。實際上,給那些非結構化的具有復雜算法的問題給出詳盡的算法是極其困難的。?

廣泛引起爭議和討論的地方是:無條件分支,或goto語句,它是大多數(shù)過程式編程語言的組成部分,反對者聲稱:goto語句可能被無限地濫用;它給程序設計提供了制造混 亂的機會。目前達成的共識是將它保留在大多數(shù)語言中,對于它所具有的危險性,應該通過程序設計的規(guī)定將其最小化。?

命令式對實際事物處理一般可以拆分為以下兩種模式:

  • 流程驅動:類似 一般就是主動輪詢 在干活中還要分心 主動去找活干? 這樣有空余的時間也完全浪費掉了

    采用警覺式者主動去輪詢 ( polling),行為取決于自身的觀察判斷,是流程驅動的,符合常規(guī)的流程驅動式編程 ( Flow-Driven Programming)的模式。

  • 事件驅動:類似? 比如公司有一個oa系統(tǒng) 你干完活的時候只需要看下oa系統(tǒng)有沒分配給你活 沒有可以干自己的事? 不用擔心還有其他事沒干完

    采用托付式者被動等通知 (notification),行為取決于外來的突發(fā)事件,是事件驅動 的,符合事件驅動式編程 ( Event-Driven Programming,簡稱 EDP)的模式。

事件驅動編程

其實,基于事件驅動的程序設計在圖形用戶界面(GUI)出現(xiàn)很久前就已經(jīng)被應用于程序設計中,可是只有當圖形用戶界面廣泛流行時,它才逐漸形演變?yōu)橐环N廣泛使用的程序設計模式。?

在過程式的程序設計中,代碼本身就給出了程序執(zhí)行的順序,盡管執(zhí)行順序可能會受到程序輸入數(shù)據(jù)的影響。

在事件驅動的程序設計中,程序中的許多部分可能在完全不可預料的時刻被執(zhí)行。往往這些程序的執(zhí)行是由用戶與正在執(zhí)行的程序的互動激發(fā)所致。?

  • 事件:就是通知某個特定的事情已經(jīng)發(fā)生(事件發(fā)生具有隨機性)。?

  • 事件與輪詢:輪詢的行為是不斷地觀察和判斷,是一種無休止的行為方式。而事件是靜靜地等待事情的發(fā)生。事實上,在Windows出現(xiàn)之前,采用鼠標輸入字符模式的PC應用程序必須進行串行輪詢,并以這種方式來查詢和響應不同的用戶操做。?

  • 事件處理器:是對事件做出響應時所執(zhí)行的一段程序代碼。事件處理器使得程序能夠對于用戶的行為做出反映。?

事件驅動常常用于用戶與程序的交互,通過圖形用戶接口(鼠標、鍵盤、觸摸板)進行交互式的互動。當然,也可以用于異常的處理和響應用戶自定義的事件等等。

事件的異常處理比用戶交互更復雜。?

事件驅動不僅僅局限在GUI編程應用。但是實現(xiàn)事件驅動我們還需要考慮更多的實際問題,如:事件定義、事件觸發(fā)、事件轉化、事件合并事件排隊、事件分派、事件處理、事件連帶等等。

其實,到目前為止,我們還沒有找到有關純事件驅動編程的語言和類似的開發(fā)環(huán)境。所有關于事件驅動的資料都是基于GUI事件的。?

屬于事件驅動的編程語言有:VB、C#、Java(Java Swing的GUI)等。它們所涉及的事件絕大多數(shù)都是GUI事件。?

此種程化范式要求程序員用按部就班的算法看待每個問題。很顯然,并不是每個問題都適合這種過程化的思維方式。這也就導致了其它程序設計范式出現(xiàn),包括我們現(xiàn)在介紹的面向對象的程序設計范式。?

從編程的發(fā)展史來談面向對象的出現(xiàn)。當軟件還非常簡單的時候,我們只需要面向過程編程:

定義函數(shù)

函數(shù)一 函數(shù)二 函數(shù)三 函數(shù)四

定義數(shù)據(jù)

數(shù)據(jù)一 數(shù)據(jù)二 數(shù)據(jù)三 數(shù)據(jù)四

最后各種函數(shù),數(shù)據(jù)的操作。

當軟件發(fā)展起來后,我們的軟件變得越來越大,代碼量越來越多,復雜度遠超Hello World的時候,我們的編寫就有麻煩了:函數(shù)和數(shù)據(jù)會定義得非常多,面臨兩個問題。首先是命名沖突,英文單詞也就那么幾個,可能寫著寫著取名時就沒合適的短詞用了,為了避免沖突,只能把函數(shù)名取得越來越長。然后是代碼重復,我們可以用函數(shù)里面調用函數(shù)的方法,但是函數(shù)調函數(shù)(比如一個功能多個方法(函數(shù)),幾個功能混用方法)不便于維護。

面向對象程序

面向對象程序設計(Object-oriented programming OOP)是種通過類、方法、對象和消息傳遞,來支持面向對象的程序設計范式。對象則指的是類的實例。它將對象作為程序的基本單元,將程序和數(shù)據(jù)封裝其中,以提高軟件的重用性、靈活性和擴展性,對象里的程序可以訪問及經(jīng)常修改對象相關連的數(shù)據(jù)。在面向對象程序編程里,程序會被設計成彼此相關的對象

面向對象程序設計可以看作一種在程序中包含各種獨立而又互相調用的對象的思想,這與傳統(tǒng)的思想剛好相反:傳統(tǒng)的程序設計主張將程序看作一系列函數(shù)的集合,或者直接就是一系列對計算機下達的指令。面向對象程序設計中的每一個對象都應該能夠接受數(shù)據(jù)、處理數(shù)據(jù)并將數(shù)據(jù)傳達給其它對象,因此它們都可以被看作一個小型的“機器”,即對象。即把事情交給最適合的對象去做。

面向對象和面向過程的區(qū)別最直觀的比喻就如:搖(狗尾巴)和?狗.搖尾巴()的區(qū)別。

面向對象編程的三個基本概念:

  • 封裝,面向對象程序設計隱藏了某一方法的具體執(zhí)行步驟,取而代之的是通過消息傳遞機制傳送消息給它。經(jīng)過深入的思考,做出良好的抽象,給出“完整且最小”的接口,并使得內(nèi)部細節(jié)可以對外隱藏

  • 繼承,在某種情況下,一個類會有“子類”。子類比原本的類(稱為父類)要更加具體化;

  • 多態(tài),指由繼承而產(chǎn)生的相關的不同的類,其對象對同一消息會做出不同的響應;

使用面向對象編程語言,易于構建軟件模型。因為,對象很類似乎很容易和現(xiàn)實世界上的所有事物和概念。

面向對象通過接口

  • 類,類是相似對象的集合。物以類聚——就是說明。每個對象都是其類中的一個實體。類中的對象可以接受相同的消息。換句話說:類包含和描述了“具有共同特性(數(shù)據(jù)元素)和共同行為(功能)”的一組對象。

  • 接口,每個對象都有接口。接口不是類,而是對符合接口需求的類所作的一套規(guī)范。接口說明類應該做什么但不指定如何作的方法。一個類可以有一個或多個接口。?

  • 方法,方法決定了某個對象究竟能夠接受什么樣的消息。面向對象的設計有時也會簡單地歸納為“將消息發(fā)送給對象”。?

面向對象技術一方面借鑒了哲學、心理學、生物學的思考方式,另一方面,它是建立在其他編程技術之上的,是以前的編程思想的自然產(chǎn)物。

如果說結構化軟件設計是將函數(shù)式編程技術應用到命令式語言中進行程序設計,面向對象編程不過是將函數(shù)式模型應用到命令式程序中的另一途徑,此時,模塊進步為對象,過程龜縮到class的成員方法中。OOP的很多技術——抽象數(shù)據(jù)類型、信息隱藏、接口與實現(xiàn)分離、對象生成功能、消息傳遞機制等等,很多東西就是結構化軟件設計所擁有的、或者在其他編程語言中單獨出現(xiàn)。但只有在面向對象語言中,他們才共同出現(xiàn),以一種獨特的合作方式互相協(xié)作、互相補充。

再談編程范式—程序語言背后的思想

從上面可以看到,如果按照面向過程的方法去設計汽車,汽車廠商需要采購一大堆零件,然后研究如何調試、調用這一大堆零件以完成一個功能。但是如果采用面向對象的方法去設計汽車,那么汽車廠商可以采用外包的方式交給專業(yè)的制動系統(tǒng)廠商來設計,只需要約定需要開放哪些public方法,輸入什么輸出什么就可以了。

再談編程范式—程序語言背后的思想

在知乎kevin zou總結的三種面向對象方式:

靜態(tài)函數(shù)包對象

將功能有聯(lián)系的一批函數(shù)放在一起封裝成一個類。這種類可以完全沒有內(nèi)部數(shù)據(jù),也可以有數(shù)據(jù)。當有數(shù)據(jù)時,這些數(shù)據(jù)充當?shù)钠鋵嵕褪桥渲茫ㄅ渲脤τ谝粋€設計優(yōu)秀的對象,是透明的,對象本身內(nèi)部的函數(shù)根本不知道有配置這個東西,它只知道它需要的每一個數(shù)據(jù)在它new之后就已經(jīng)存在this里了,隨取隨用。配置的給予或獲取方式,是構建對象(new)時才需要去考慮的)這種對象的特點是,它的每一個函數(shù)(或方法)對這些數(shù)據(jù)都是只讀的,所以不管方法有無被調用,被誰調用,被調用多少次,它也不會改變它的狀態(tài)。

領域模型對象

這個概念是相對于傳統(tǒng)的面向數(shù)據(jù)庫的系統(tǒng)分析和設計而言的。數(shù)據(jù)庫雖然只用了外鍵就描述了復雜的大千世界,但軟件開發(fā)的難點在于適應變化,并且能夠安全地修改。關系模型看似簡單,但它卻像一張蜘蛛網(wǎng)一樣將所有table和欄位包在一塊,牽一發(fā)而動全身,讓你在修改時如履薄冰,一不小心就會顧此失彼,bug此起彼伏。而OO的封裝特性則剛好可以用來解決這個問題。將業(yè)務數(shù)據(jù)整理成一個個獨立的對象,讓它們的數(shù)據(jù)只能被自己訪問。留給外界的基本上只是一些接口(方法),數(shù)據(jù)除非萬不得已,一個都不會公開。外界只能向它發(fā)送消息,它自己則通過修改自身數(shù)據(jù)來響應這種消息。這種對象與第一種對象剛好相反,它一定有數(shù)據(jù),而且它的每一個函數(shù)存在的目的就是修改自己的數(shù)據(jù)。且每一次修改都是粗粒度的,每一次修改后,對象也還是處在valid狀態(tài)。推薦閱讀《領域模型淺析》,《領域模型,你真的理解的了嗎?》

順便拓展下:領域驅動設計(Domain-Driven Design)-貧血模型-領域模型-充血模型

臨時對象

其它用來解決過程式開發(fā)時,超多的變量,超復雜的流程而整理出來的小對象,。這些對象一起協(xié)作,最后完成一個傳統(tǒng)成千上萬行的過程式代碼才能完成的功能。例如現(xiàn)在要連接sql server執(zhí)行查詢語句并取得結果返回。不使用任何類庫和工具,所有步驟都自己進行,例如解析協(xié)議,socket網(wǎng)絡連接,數(shù)據(jù)包收發(fā)等。這時候從頭到尾用一個個函數(shù)來完成,絕對沒有先劃分出一個個職責分明的對象,讓各對象協(xié)作完成這件事情來得更簡單。

?

但編程實踐表明,并不是任何東西成為對象都是一件好事情。舉一個Java中的蹩足的例子:Java中只有對象才能作為參數(shù)傳入函數(shù)(當然還有原始類型primitive type)。所以為了將函數(shù)傳遞給另外一個函數(shù),你需要將函數(shù)包裹在一個對象中,通常會用一個匿名類,因為這個類不會有其他作用,只是為了讓Java的一切皆為對象的設計高興。

Java擁有純粹的面向對象概念。它從設計之初,就希望以一切皆為對象的純對象模型來為世界建模。但發(fā)展到現(xiàn)在,Java中加入了越來越多非對象的東西。引入了閉包,從而獲得了函數(shù)式編程中的一級函數(shù);引入泛型,從而獲得了參數(shù)化的類型。這可能暗示了,這個世界是如此得豐富多彩,使用單一模式為世界建模并不會成功。

聲明式編程:

聲明式編程是以數(shù)據(jù)結構的形式來表達程序執(zhí)行的邏輯。它的主要思想是告訴計算機應該做什么,但不指定具體要怎么做。

SQL 語句就是最明顯的一種聲明式編程的例子,例如:

SELECT * FROM collection WHERE num > 5

除了 SQL,網(wǎng)頁編程中用到的 HTML 和 CSS 也都屬于聲明式編程。

通過觀察聲明式編程的代碼我們可以發(fā)現(xiàn)它有一個特點是它不需要創(chuàng)建變量用來存儲數(shù)據(jù)

另一個特點是它不包含循環(huán)控制的代碼如 for, while。

函數(shù)式編程和聲明式編程是有所關聯(lián)的,因為他們思想是一致的:即只關注做什么而不是怎么做。但函數(shù)式編程不僅僅局限于聲明式編程。

函數(shù)式編程

函數(shù)式編程(functional programming)或稱函數(shù)程序設計、泛函編程,是一種編程范式,它將計算機運算視為函數(shù)運算,并且避免使用程序狀態(tài)以及易變對象。其中,λ演算(lambda calculus)為該語言最重要的基礎。而且,λ演算的函數(shù)可以接受函數(shù)當作輸入(引數(shù))和輸出(傳出值)。

函數(shù)式編程關心類型(代數(shù)結構)之間的關系,命令式編程關心解決問題的步驟。函數(shù)式編程中的lambda可以看成是兩個類型之間的關系,一個輸入類型和一個輸出類型。lambda演算就是給lambda表達式一個輸入類型的值,則可以得到一個輸出類型的值,這是一個計算,計算過程滿足? -等價和? -規(guī)約。函數(shù)式編程的思維就是如何將這個關系組合起來,用數(shù)學的構造主義將其構造出你設計的程序

比起命令式編程,函數(shù)式編程更加強調程序執(zhí)行的結果而非執(zhí)行的過程,倡導利用若干簡單的執(zhí)行單元讓計算結果不斷漸進,逐層推導復雜的運算,而不是設計一個復雜的執(zhí)行過程。

命令式編程是面向計算機硬件的抽象,有變量(對應著存儲單元),賦值語句(獲取,存儲指令),表達式(內(nèi)存引用和算術運算)和控制語句(跳轉指令),一句話,命令式程序就是一個馮諾依曼機的指令序列。

函數(shù)式編程是面向數(shù)學的抽象,將計算描述為一種表達式求值,一句話,函數(shù)式程序就是一個表達式。

函數(shù)式編程最重要的特點是“函數(shù)第一位”,即函數(shù)可以出現(xiàn)在任何地方,比如你可以把函數(shù)作為參數(shù)傳遞給另一個函數(shù),不僅如此你還可以將函數(shù)作為返回值。

函數(shù)式編程的本質

函數(shù)式編程中的函數(shù)這個術語不是指計算機中的函數(shù)(實際上是Subroutine),而是指數(shù)學中的函數(shù),即自變量的映射。也就是說一個函數(shù)的值僅決定于函數(shù)參數(shù)的值,不依賴其他狀態(tài)。比如sqrt(x)函數(shù)計算x的平方根,只要x不變,不論什么時候調用,調用幾次,值都是不變的。

在函數(shù)式語言中,函數(shù)作為一等公民,可以在任何地方定義,在函數(shù)內(nèi)或函數(shù)外,可以作為函數(shù)的參數(shù)和返回值,可以對函數(shù)進行組合。

純函數(shù)式編程語言中的變量也不是命令式編程語言中的變量,即存儲狀態(tài)的單元,而是代數(shù)中的變量,即一個值的名稱。變量的值是不可變的(immutable),也就是說不允許像命令式編程語言中那樣多次給一個變量賦值。比如說在命令式編程語言我們寫“x = x + 1”,這依賴可變狀態(tài)的事實,拿給程序員看說是對的,但拿給數(shù)學家看,卻被認為這個等式為假。

函數(shù)式語言的如條件語句,循環(huán)語句也不是命令式編程語言中的控制語句,而是函數(shù)的語法糖,比如在Scala語言中,if else不是語句而是三元運算符,是有返回值的。

嚴格意義上的函數(shù)式編程意味著不使用可變的變量,賦值,循環(huán)和其他命令式控制結構進行編程。

從理論上說,函數(shù)式語言也不是通過馮諾伊曼體系結構的機器上運行的,而是通過λ演算來運行的,就是通過變量替換的方式進行,變量替換為其值或表達式,函數(shù)也替換為其表達式,并根據(jù)運算符進行計算。λ演算是圖靈完全(Turing completeness)的,但是大多數(shù)情況,函數(shù)式程序還是被編譯成(馮諾依曼機的)機器語言的指令執(zhí)行的。

函數(shù)式編程的特性

  • 函數(shù)是"一等公民":函數(shù)優(yōu)先,和其他數(shù)據(jù)類型一樣。

  • 只用"表達式",不用"語句":通過表達式(expression)計算過程得到一個返回值,而不是通過一個語句(statement)修改某一個狀態(tài)。

  • 無副作用:不污染變量,同一個輸入永遠得到同一個數(shù)據(jù)。

  • 不可變性:前面一提到,不修改變量,返回一個新的值。

由于變量值是不可變的,對于值的操作并不是修改原來的值,而是修改新產(chǎn)生的值,原來的值保持不便。

通常來說,算法都有遞推(iterative)遞歸(recursive)兩種定義。

由于變量不可變,純函數(shù)編程語言無法實現(xiàn)循環(huán),這是因為For循環(huán)使用可變的狀態(tài)作為計數(shù)器,而While循環(huán)DoWhile循環(huán)需要可變的狀態(tài)作為跳出循環(huán)的條件。因此在函數(shù)式語言里就只能使用遞歸來解決迭代問題,這使得函數(shù)式編程嚴重依賴遞歸。

函數(shù)式語言當然還少不了以下特性:

  • 高階函數(shù)(Higher-order function):就是參數(shù)為函數(shù)或返回值為函數(shù)的函數(shù)。有了高階函數(shù),就可以將復用的粒度降低到函數(shù)級別,相對于面向對象語言,復用的粒度更低。

  • 偏應用函數(shù)(Partially Applied Functions):一個函數(shù)接收一個有多個參數(shù)的函數(shù),返回一個需要較少參數(shù)的函數(shù)。偏函數(shù)將一到多個參數(shù)在內(nèi)部固定,然后返回新函數(shù),返回的函數(shù)接收剩余的參數(shù)完成函數(shù)的應用。

  • 柯里化(Currying):輸入一個有多個參數(shù)的函數(shù), 返回一個只接收單個參數(shù)的函數(shù)。

  • 閉包(Closure):閉包就是有權訪問另一個函數(shù)作用域中變量的函數(shù).閉包的三個特性:1.閉包是定義在函數(shù)中的函數(shù) 。2.閉包能訪問包含函數(shù)的變量。3.即使包含函數(shù)執(zhí)行完了, 被閉包引用的變量也得不到釋放。具體參看《閑話閉包》

函數(shù)式編程的好處?

由于命令式編程語言也可以通過類似函數(shù)指針的方式來實現(xiàn)高階函數(shù),函數(shù)式的最主要的好處主要是不可變性帶來的。沒有可變的狀態(tài),函數(shù)就是引用透明(Referential transparency)的和沒有副作用(No Side Effect)。

函數(shù)即不依賴外部的狀態(tài)也不修改外部的狀態(tài),函數(shù)調用的結果不依賴調用的時間和位置,這樣寫的代碼容易進行推理,不容易出錯。這使得單元測試和調試都更容易。

由于(多個線程之間)不共享狀態(tài),不會造成資源爭用(Race condition),也就不需要用來保護可變狀態(tài),也就不會出現(xiàn)死鎖,這樣可以更好地并發(fā)起來,尤其是在對稱多處理器(SMP)架構下能夠更好地利用多個處理器(核)提供的并行處理能力。

我覺得函數(shù)編程的好處就不用管js里面該死的this指向

函數(shù)式編程語言還提供惰性求值-Lazy evaluation,也稱作call-by-need,是在將表達式賦值給變量(或稱作綁定)時并不計算表達式的值,而在變量第一次被使用時才進行計算。這樣就可以通過避免不必要的求值提升性能。

函數(shù)式編程語言一般還提供強大的模式匹配(Pattern Match)功能。在函數(shù)式編程語言中可以定義代數(shù)數(shù)據(jù)類型(Algebraic data type),通過組合已有的數(shù)據(jù)類型形成新的數(shù)據(jù)類型,如在Scala中提供case class,代數(shù)數(shù)據(jù)類型的值可以通過模式匹配進行分析。

函數(shù)式編程天生親和單元測(特別是黑盒測試),因為FP關注就是輸入與輸出。反觀Java或者C++,僅僅檢查函數(shù)的返回值是不夠的:代碼可能修改外部狀態(tài)值,因此我們還需要驗證這些外部的狀態(tài)值的正確性。在FP語言中呢,就完全不需要。

調試查錯方面,因為FP程序中的錯誤不依賴于之前運行過的不相關的代碼。而在一個指令式程序中,一個bug可能有時能重現(xiàn)而有些時候又不能。因為這些函數(shù)的運行依賴于某些外部狀態(tài), 而這些外部狀態(tài)又需要由某些與這個bug完全不相關的代碼通過某個特別的執(zhí)行流程才能修改。在FP中這種情況完全不存在:如果一個函數(shù)的返回值出錯了,它一直都會出錯,無論你之前運行了什么代碼。而整個程序就是函數(shù)接龍。

推薦閱讀《傻瓜函數(shù)式編程

泛型編程

泛型編程是另外一個有趣的話題。泛型為程語言提供了更高層級的抽象,即參數(shù)化類型。換句話說,就是把一個原本特定于某個類型的算法或類當中的類型信息抽象出來。這個抽象出來的概念在C++的STL(Standard Template Library)中就是模版(Template)。STL展示了泛型編程的強大之處,一出現(xiàn)就成為了C++的強大武器。除C++之外,C#,Java,Haskell等編程語言都引入了泛型概念。

泛型編程是一個稍微局部一些的概念,它僅僅涉及如何更抽象地處理類型,即參數(shù)化類型。這并不足以支撐起一門語言的核心概念。我們不會聽到一個編程語言是純泛型編程的,而沒有其他編程范式。但正因為泛型并不會改變程序語言的核心,所以在大多數(shù)時候,它可以很好的融入到其他的編程方式中。C++,Scala,Haskell這些風格迥異的編程語言都支持泛型。泛型編程提供了更高的抽象層次,這意味著更強的表達能力。這對大部分編程語言來說都是一道美味佐餐美酒。

在Swift中,泛型得到廣泛使用,許多Swift標準庫是通過泛型代碼構建出來的。例如Swift的數(shù)組和字典類型都是泛型集。這樣的例子在Swift中隨處可見。

原文鏈接:再談編程范式-程序語言背后的思想 - 模型設計,領域設計,軟件設計, - 周陸軍的個人網(wǎng)站,再談系列都是搬磚總結性文章,文有不妥之處,請留言告知,多謝!

參考文章:

編程范式[ 程序員的編程世界觀 ]

漢諾塔——各種編程范式的解決?

編程范式:命令式編程(Imperative)、聲明式編程(Declarative)和函數(shù)式編程(Functional)

神奇的λ演算 https://www.cnblogs.com/dragonpig/archive/2010/01/26/1657052.html

編程語言范式 http://www.cnblogs.com/lisperl/archive/2011/11/20/2256165.html?

λ 演算學習?https://www.cnblogs.com/kirohuji/p/7080876.html

函數(shù)式編程漫談?https://cloud.tencent.com/developer/article/1190773

此文大多是本文給出的鏈接文字提煉總結,如果不妥之處,請到本站留言,告知,拜謝!


當前名稱:再談編程范式—程序語言背后的思想
文章轉載:http://weahome.cn/article/jhjdsd.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部