新聞中心
【精選譯文】之前的一段時(shí)間,Scala社區(qū)掀起了一陣討論,主要觀點(diǎn)包括“Scala不是一個(gè)函數(shù)式語(yǔ)言”以及“Scala不夠函數(shù)式”,并把Scala與F#、Erlang等“純粹的”函數(shù)式語(yǔ)言放在一起進(jìn)行對(duì)比以證明(編輯注:函數(shù)式語(yǔ)言以其并行編程的優(yōu)勢(shì)正逐步擴(kuò)大自己在多核時(shí)代的影響力,而上述的三個(gè)語(yǔ)言都是相關(guān)討論涉及的焦點(diǎn))。有觀于此,Scala創(chuàng)始人Martin Odersky于前日在Scala官方網(wǎng)站上更新了一篇文章,稱(chēng)Scala是一門(mén)“后函數(shù)式語(yǔ)言”。雖然Martin提出的是一個(gè)新概念,但文章對(duì)于函數(shù)式語(yǔ)言的特點(diǎn)進(jìn)行了非常全面而簡(jiǎn)短的總結(jié),如果你對(duì)函數(shù)式語(yǔ)言到底如何強(qiáng)大并不十分了解,那么這篇文章是很好的學(xué)習(xí)材料。以下是全文——

Scala 是否是一門(mén)函數(shù)式語(yǔ)言?過(guò)去幾年,我們長(zhǎng)時(shí)間地對(duì)這個(gè)問(wèn)題進(jìn)行了討論。一方面,Scala 在本質(zhì)上提供給了那些常常與函數(shù)式編程關(guān)聯(lián)在一起的編程結(jié)構(gòu),而且大量的 Scala 代碼是純函數(shù)式的。另一方面,有相當(dāng)多的人并不認(rèn)同 Scala 為函數(shù)式語(yǔ)言這一說(shuō)法。
相關(guān)閱讀:
- Scala講座:函數(shù)式語(yǔ)言的體驗(yàn)
- Scala簡(jiǎn)介:面向?qū)ο蠛秃瘮?shù)式編程的組合
- Scala如何改變了我的編程風(fēng)格:從命令式到函數(shù)式
我認(rèn)為用來(lái)描述 Scala 的一個(gè)非常不錯(cuò)的形容詞是:后函數(shù)式 (postfunctional)。函數(shù)式編程所有必要的組成部分都被 Scala 吸收了,即使某些“看起來(lái)的感覺(jué)”是不同的。此外,函數(shù)式編程只是 Scala 這個(gè)更大的工具箱中的一部分,也是非常重要的部分。函數(shù)式編程正在逐漸主流語(yǔ)言吸收,對(duì)于這個(gè)大趨勢(shì),我認(rèn)為 Scala 是其中的一個(gè)領(lǐng)先者。這種變化正來(lái)勢(shì)洶洶。例如,C# 的每個(gè)新版都要比之前的版本更具函數(shù)式(雖然根據(jù)之前文章的介紹,C#的嘗試似乎不太成功),甚至 Java 最終也會(huì)擁有閉包(closure)。當(dāng)然,增加閉包或類(lèi)型推理并不能成為一門(mén)函數(shù)式語(yǔ)言,但這個(gè)趨勢(shì)是有目共睹的。
對(duì)于 Scala 是后函數(shù)式語(yǔ)言的觀點(diǎn),我應(yīng)首先澄清在我看來(lái)什么是函數(shù)式語(yǔ)言。對(duì)于函數(shù)式語(yǔ)言這種說(shuō)法,基本上包含兩個(gè)定義,一個(gè)是狹隘的定義,一個(gè)是寬泛的定義。狹隘的定義認(rèn)為函數(shù)式編程語(yǔ)言應(yīng)僅認(rèn)可純函數(shù),而且不可具有副作用。根據(jù)這種定義,幾乎沒(méi)有一門(mén)函數(shù)式語(yǔ)言還在使用中:即使 Haskell 也具有 I/O 單子(monad)和 unsafePerformIO。因此我更喜歡那個(gè)寬泛的定義:函數(shù)式語(yǔ)言讓以函數(shù)為中心的編程變得容易和自然。我認(rèn)為這正是 Scala 所具有的特性,所以這個(gè)就是它應(yīng)被視為函數(shù)式語(yǔ)言的原因。
為了挖掘更多詳細(xì)的細(xì)節(jié),下面我們做一個(gè)功能列表,這些功能通常是與函數(shù)式語(yǔ)言相關(guān)聯(lián)的。
◆作為第一類(lèi)(first class)值的函數(shù):具有
◆方便的閉包句法:具有
◆列表解析(list comprehension):具有。 Scala 的表達(dá)式可以表示列表以及其他單子。
◆柯里化(curry)函數(shù)定義和應(yīng)用:具有。lazy val 以及 lazy stream 的形式。
◆模式匹配:具有
◆Tailcall 優(yōu)化:半具有。Scala 自動(dòng)優(yōu)化直接循環(huán) tailcall。對(duì)于其他調(diào)用,存在顯式的 tailcall 方法,使用 trampolining 技術(shù)。
將焦點(diǎn)進(jìn)一步縮小到靜態(tài)類(lèi)型函數(shù)式語(yǔ)言,還有幾點(diǎn):
◆強(qiáng)大的泛型,包括較高類(lèi)別的類(lèi)型:具有
◆類(lèi)型類(lèi):具有,通過(guò)隱式參數(shù)進(jìn)行模塊化。
◆類(lèi)型推理:半具有。Scala 具有局部類(lèi)型推理,很有用;但相對(duì)于 Haskell、ML 和 OCaml 語(yǔ)言中所用的 Hindeley/Milner 類(lèi)型的推理,功能沒(méi)有那么強(qiáng)大。不過(guò)從另一方面來(lái)看,局部類(lèi)型推理對(duì)于子類(lèi)型化更好。
人們是否像使用函數(shù)式語(yǔ)言那樣使用 Scala?當(dāng)然是的。比如,Scala 編譯器資源和 Scala 庫(kù)主要是用函數(shù)式風(fēng)格編寫(xiě)的。Map、filter、fold 無(wú)處不在。模式匹配也是處處使用。非常少的可變變量,并且其中多數(shù)用于單賦值形式。
為什么有人不同意 Scala 是函數(shù)式語(yǔ)言的說(shuō)法?看起來(lái)存在兩個(gè)主要原因:句法選擇和面向?qū)ο笳Z(yǔ)言的角色。
Scala 感覺(jué)更少是函數(shù)式語(yǔ)言,因?yàn)?strong>其核心句法大部分是繼承了 Java 的傳統(tǒng),而不是 Lisp、ML 或 Haskell。這三個(gè)編程語(yǔ)言是函數(shù)式語(yǔ)言家族里最重要的先行者。
尤其特別之處在于,Scala 不具有一個(gè)不同的、通常比較笨拙的句法,用于用?。╠ereference)可變變量以及用于定義有效計(jì)算。你也許會(huì)認(rèn)為這是不好的,因?yàn)樗€不足夠打消程序員繼續(xù)他們命令式編程的老習(xí)慣。這是一種裁決:你想要用一門(mén)語(yǔ)言來(lái)獲得什么。這種判斷是完全必要的。不過(guò)在這篇文章中,我感興趣的只是描述 Scala 是什么,而不是為什么 Scala 會(huì)是這樣,或者它是否應(yīng)該是其他模樣。
此外,Scala 也沒(méi)有某些被視為典型函數(shù)式語(yǔ)言的句法。比如,相對(duì)于其他函數(shù)式語(yǔ)言,curry化更為冗長(zhǎng),在 Scala 使用更少。還有,它沒(méi)有代數(shù)數(shù)據(jù)類(lèi)型,你必須編寫(xiě)一系列 case 類(lèi)作為替換。
Scala 不被視為函數(shù)式語(yǔ)言,某些時(shí)候還有其他原因,因?yàn)樗?strong>接受了面向?qū)ο?/strong>而不是拒絕它。某些使用函數(shù)式編程的人誤解了面向?qū)ο笳Z(yǔ)言,認(rèn)為面向?qū)ο笳Z(yǔ)言天生與可變狀態(tài)相關(guān)聯(lián)(平心而論,其實(shí)是許多關(guān)于面向?qū)ο笳Z(yǔ)言的出版物加強(qiáng)了這種觀點(diǎn))。Scala 建立在這樣一個(gè)前提之上:一門(mén)語(yǔ)言既可以是函數(shù)式的也可以是面向?qū)ο蟮?,并且兩者的結(jié)合讓人獲益良多。
總之,如果你看看 Scala 提供的功能,它基本上是一門(mén)函數(shù)式語(yǔ)言,但從表面上它不總是像一門(mén)函數(shù)式語(yǔ)言,而且它不會(huì)強(qiáng)迫你去采用函數(shù)式編程風(fēng)格。對(duì)于它的許多用戶(hù),函數(shù)式編程構(gòu)造是 Scala 中最主要的工具,但并不是唯一的工具。事實(shí)上,在 Scala 的設(shè)計(jì)中,函數(shù)式構(gòu)造、命令式構(gòu)造花費(fèi)了大量的心血,并且所有對(duì)象都能夠在一起很好地運(yùn)行。我認(rèn)為對(duì)于這種混合“后函數(shù)”一詞是非常恰當(dāng)?shù)摹?/p>
#t#一個(gè)有趣的對(duì)比對(duì)象是結(jié)構(gòu)化編程。在七十年代,結(jié)構(gòu)化編程曾是最主要的新編程風(fēng)格,諸如 Pascal、Modula 和 Ada 被創(chuàng)造出來(lái),它們比其他語(yǔ)言更好地迎合了這種風(fēng)格。二十年后,你還會(huì)問(wèn) Java 是否屬于結(jié)構(gòu)化編程語(yǔ)言嗎?既然看起來(lái)不同,它從本質(zhì)上包含了那些較早的語(yǔ)言的所有功能。而且它還沒(méi)有 goto 語(yǔ)句,這讓 Java 成為了結(jié)構(gòu)化語(yǔ)言?也許吧。事實(shí)上所有這些都不再重要。結(jié)構(gòu)化編程已經(jīng)成功達(dá)到了一個(gè)層次:幾乎所有語(yǔ)言現(xiàn)在都遵循它制定的原則,既然表面的句法不同。而且,對(duì)于今天的編程語(yǔ)言,結(jié)構(gòu)化控制只是很多風(fēng)格中的一種而已。
我希望函數(shù)式語(yǔ)言將會(huì)走上同樣的道路:它被主流語(yǔ)言吸收,直到人們不再認(rèn)為函數(shù)式編程是一種不同的、新穎的、外來(lái)的代碼編寫(xiě)方式,并且在每天的如此工作中使用它。相同的事情已經(jīng)發(fā)生在之前的結(jié)構(gòu)化編程和面向?qū)ο缶幊躺砩?。函?shù)式編程很可能就是下一個(gè),因此 Scala 將是后函數(shù)式語(yǔ)言飄來(lái)的第一縷新風(fēng)。
文章名稱(chēng):Scala:Java+函數(shù)式=后函數(shù)式?
網(wǎng)站網(wǎng)址:http://m.5511xx.com/article/dpshogh.html


咨詢(xún)
建站咨詢(xún)
