溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

匯編語言的函數(shù)式編程實(shí)例分析

發(fā)布時(shí)間:2022-03-17 16:22:01 來源:億速云 閱讀:197 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要介紹了匯編語言的函數(shù)式編程實(shí)例分析的相關(guān)知識(shí),內(nèi)容詳細(xì)易懂,操作簡(jiǎn)單快捷,具有一定借鑒價(jià)值,相信大家閱讀完這篇匯編語言的函數(shù)式編程實(shí)例分析文章都會(huì)有所收獲,下面我們一起來看看吧。

一切都是為了消除副作用

要了解函數(shù)式編程,我們需要首先了解函數(shù)。 這聽起來可能很無聊,但總而言之,它很有見地。

簡(jiǎn)單地說,函數(shù)是將輸入轉(zhuǎn)換為輸出的東西。只是事情并沒有那么簡(jiǎn)單。思考一下,在Python中的下面這個(gè)函數(shù)的意義:

def square(x):
    return x*x

這個(gè)函數(shù)很簡(jiǎn)單。 它需要一個(gè)變量x,可能是一個(gè)int,或者是一個(gè) floatdouble,然后輸出該變量的平方。

再思考一下下面的這個(gè)函數(shù):

global_list = []
def append_to_list(x):
    global_list.append(x)

乍一看,這個(gè)函數(shù)接受了一個(gè)變量 x,無論是哪種類型,由于沒有 return 語句,它什么也不返回。事實(shí)真的是這樣嗎?

如果事先沒有定義 global_list,那么這個(gè)函數(shù)就不能工作,它的輸出是相同的列表,盡管經(jīng)過了修改。雖然 global_list 沒有聲明輸入,但當(dāng)我們使用該函數(shù)時(shí),它就會(huì)發(fā)生變化:

append_to_list(1)
append_to_list(2)
global_list

它返回了 [1,2],而不是空列表。這可能就是問題所在,列表確實(shí)是函數(shù)的一個(gè)輸入,雖然我們沒有明確說明。

1.不忠于函數(shù)

這些隱含的輸入,或者其他情況下的輸出,有一個(gè)官方名稱:副作用。雖然我們只列舉了一個(gè)簡(jiǎn)單的例子,但在更復(fù)雜的程序中,這些可能會(huì)讓我們面臨真正的困難。

大家可以思考一下該如何測(cè)試 append_to_list:我們不僅需要閱讀第一行并使用任何 x 來測(cè)試函數(shù),還需要閱讀整個(gè)定義,了解其作用,定義 global_list 并以這種方式進(jìn)行測(cè)試。這個(gè)例子告訴我們,當(dāng)你在處理有數(shù)千行代碼的程序時(shí),簡(jiǎn)單的東西很快就會(huì)變得乏味。

好消息是,有一個(gè)簡(jiǎn)單的解決方法:對(duì)函數(shù)作為輸入的內(nèi)容誠(chéng)實(shí)。這樣更好:

newlist = []
def append_to_list2(x, some_list):
    some_list.append(x)
append_to_list2(1,newlist)
append_to_list2(2,newlist)
newlist

我們并沒有作太大的改變,輸出結(jié)果仍然是 [1,2],其他所有內(nèi)容也保持不變。

但是,我們已經(jīng)更改了一件事情:該代碼現(xiàn)在沒有副作用。

現(xiàn)在,當(dāng)我們查看函數(shù)聲明時(shí),能確切知道發(fā)生了什么。如果程序運(yùn)行不正常,我們也可以輕松地單獨(dú)測(cè)試每個(gè)功能并查明哪個(gè)功能有問題。

2.函數(shù)式編程正在編寫純函數(shù)

具有明確聲明的輸入和輸出的函數(shù)是沒有副作用的函數(shù),而沒有副作用的函數(shù)就是純函數(shù)。

函數(shù)編程的一個(gè)非常簡(jiǎn)單的定義是:僅用純函數(shù)編寫程序。純函數(shù)永遠(yuǎn)不會(huì)修改變量,只會(huì)創(chuàng)建新的變量作為輸出。

此外,對(duì)于給定輸入的純函數(shù),我們可以得到特定的輸出。相反,不純函數(shù)可能依賴于某些全局變量。因此,如果全局變量不同,則相同的輸入變量可能導(dǎo)致不同的輸出。后者會(huì)讓調(diào)試和代碼維護(hù)變得更加困難。

這里有一個(gè)容易發(fā)現(xiàn)副作用的簡(jiǎn)單規(guī)則:由于每個(gè)函數(shù)必須具有某種輸入和輸出,因此沒有任何輸入或輸出的函數(shù)聲明必須是不純的。如果采用函數(shù)式編程,這是你可能想要更改的第一個(gè)聲明。

函數(shù)式編程不僅是 map 和 reduce

循環(huán)不是函數(shù)式編程中的東西。首先,我們先來思考以下的Python循環(huán):

integers = [1,2,3,4,5,6]
odd_ints = []
squared_odds = []
total = 0
for i in integers:
    if i%2 ==1
        odd_ints.append(i)
for i in odd_ints:
    squared_odds.append(i*i)
for i in squared_odds:
    total += i

相較于我們要執(zhí)行的簡(jiǎn)單操作,以上代碼明顯過長(zhǎng)。而且也沒有起到作用,因?yàn)槲覀冋谛薷娜肿兞俊?/p>

相反,我們可以用以下代碼替代:

from functools import reduce
integers = [1,2,3,4,5,6]
odd_ints = filter(lambda n: n % 2 == 1, integers)
squared_odds = map(lambda n: n * n, odd_ints)
total = reduce(lambda acc, n: acc + n, squared_odds)

這是完整的函數(shù)式。它比較短,也更快,因?yàn)槲覀儾恍枰嗟臄?shù)組元素。如果你理解 filter, mapreduce 如何工作,代碼也就不難理解了。

這并不意味著所有的函數(shù)代碼都使用 mapreduce 等。這也不意味著你需要函數(shù)式編程來理解 mapreduce。只是當(dāng)你抽象循環(huán)時(shí),這些函數(shù)會(huì)彈出很多。

1.Lambda函數(shù)

在談到函數(shù)式編程的歷史時(shí),許多人都是從lambda函數(shù)的發(fā)明開始的。 盡管 lambda 是函數(shù)式編程毫無疑問的基石,但它們并不是根本原因。

Lambda 函數(shù)是可用于使程序起作用的工具。 但是,我們也可以在面向?qū)ο蟮木幊讨惺褂?code>lambda。

2.靜態(tài)類型

上面的示例雖然不是靜態(tài)類型的,但是它依然是函數(shù)式的。

即使靜態(tài)類型為我們的代碼增加了一層額外的安全保護(hù),但是其函數(shù)正常也并非必不可少。 不過,這可能是一個(gè)不錯(cuò)的補(bǔ)充。

有些編程語言的函數(shù)式編程越來越強(qiáng)

1.Perl

Perl 對(duì)副作用的處理方法與大多數(shù)編程語言截然不同。它包含了一個(gè)神奇的參數(shù) $\ 。Perl確實(shí)有它的優(yōu)點(diǎn),但我不會(huì)用它進(jìn)行函數(shù)式編程。

2.Java

如果你在用 Java 進(jìn)行函數(shù)式編程,那我只能祝你好運(yùn)了。因?yàn)槟愕某绦蛴幸话胧怯伸o態(tài)關(guān)鍵字組成的,而且其他 Java 開發(fā)人員也會(huì)把你的程序視為恥辱。

這并不是說 Java 有多糟糕,而是因?yàn)樗⒉皇菫槟切┯煤瘮?shù)式編程解決問題而設(shè)計(jì)的,比如數(shù)據(jù)庫(kù)管理或機(jī)器學(xué)習(xí)應(yīng)用程序。

3.Scala

有趣的是:Scala 的目標(biāo)是統(tǒng)一面向?qū)ο蠛秃瘮?shù)式編程。如果你覺得這有點(diǎn)奇怪,那你不是一個(gè)人,因?yàn)樗腥硕歼@么覺得:函數(shù)式編程的目標(biāo)是完全消除副作用,而面向?qū)ο缶幊淌前迅弊饔帽A粼趯?duì)象內(nèi)部。

盡管如此,很多開發(fā)人員認(rèn)為 Scala 是一種幫助他們從面向?qū)ο缶幊踢^渡到函數(shù)式編程的語言。或許在未來幾年里,它們會(huì)更容易全面發(fā)揮作用。

4.Python

Python 鼓勵(lì)函數(shù)式編程。一個(gè)事實(shí)就能看到這一點(diǎn):每個(gè)函數(shù)在默認(rèn)情況下至少有一個(gè)輸入self。這很像Python的禪:顯式比隱式好!

5.Clojure

據(jù)它的創(chuàng)建者說,Clojure 大約有 80% 是函數(shù)式編程。默認(rèn)情況下,所有值都是不可變的,就像在函數(shù)式編程中需要它們一樣。但是,我們可以通過在這些不可變的值周圍使用可變值包裝器來解決這個(gè)問題。當(dāng)你打開這樣一個(gè)包裝,你得到的東西又是不變的。

6.Haskell

這是為數(shù)不多的純函數(shù)式和靜態(tài)類型的語言之一。雖然在開發(fā)過程中這看起來像是一個(gè)時(shí)間消耗器,但在調(diào)試程序時(shí),Haskell會(huì)付出巨大的代價(jià)。它不像其他語言那么容易學(xué),但絕對(duì)值得投資!

關(guān)于“匯編語言的函數(shù)式編程實(shí)例分析”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對(duì)“匯編語言的函數(shù)式編程實(shí)例分析”知識(shí)都有一定的了解,大家如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI