成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

大辯論:Java不是C++ 閉包讓Java更簡單

原創
開發 后端
Java真的需要閉包嗎?或者說,Java真的不需要閉包嗎?Java閉包的三個提案中,FCM提案最終得到了通過。這增加的一個語言特性,真的會令Java變得異常復雜么?本文作者認為,人們不應太擔心這個,而是應該為了閉包使Java更簡單而感到高興。

【51CTO精選譯文】編者按:在上個月舉行的Devoxx大會上,Sun宣布Java 7中將包含簡單的閉包特性。這與之前一年Sun的宣布完全相反——當時他們說Java將不會考慮閉包,因為Java不需要。Java社區對此是有人欣喜有人怒,不過,到底有什么好爭論的呢?一位對C++和Java十分了解,一直關注編程語言的資深開發者Marek Krj在最近的一篇博文中詳細的分析了Java需要閉包的理由,并引申C++和C#的一些情況做為自己的論據。以下是Marek的討論:

#t#多年前,Sun這樣描述微軟對Java的擴展提案:

Visual J++的許多優點——類型安全、面向對象、且易于組件互聯(component interconnection)——只是對Java對象模型的安全性和靈活性的繼承………

方法綁定(Bound)引用根本沒有必要,它們并不屬于Java編程語言的一個部分,因此它們也不能被標準的編譯器接受。此外,這些做法會讓Java語言損失掉簡便性和統一性(unity)。
   
如此等等,這都是些營銷時所說的胡言亂語。我不知道還有什么比這更惱人的:1.自詡面向對象的正統地位;2.自滿:“我們更理解Java”。但無論如何,James Gosling(Java之父本人)也很可能會常說他希望閉包(closure)包含在Java中,而不是匿名內部類(anonymous inner classes);3. 對于如何將函數作為Java語言的頭等公民(first class citiciens)那樣包含進去,沒有一個完整的提案!這就是他們所謂的“根本沒有必要”的論據……

圍繞著閉包的思想存在著相當大的爭議,這有點像我們最近討論過的關于C++ concepts特性的爭論:人們認為它不必要,而且太復雜了(51CTO編者注:作者此處意為今年7月下旬,C++標準委員會確定將concepts特性從C++0x中移除一事。C++編程語言的作者Bjarne Stroustrup為此聲稱C++0x已死,將希望放在新一代C++標準上。)。由于在C++0x中,我們可以使用lambda函數,這沒引起多少爭議,因此Java社區對于閉包的這一爭論激起了我的興趣。來啊,為什么不引入閉包呢?甚至C#都包含了一些閉包!

那么,什么是閉包(Closure)呢?在這篇博文中,我們把它認為是類似于C++(或Python和Groovy)中lambda那樣的函數,即一個匿名的、獨立式的函數,比如下面這種:

  1. auto print = [] (int x) { cout << x; } 

現在,讓我們用Java語言來表示這一概念。

1.提案

那么,讓我們來看一看這三個提案。

a) BGGA(源自Bracha、Gafter、Gosling 和 Ahe的首字母)

這是最雄心勃勃的一個提案。它引入了一個新的語言類型:函數類型,以及它的一個全新的標記方法(notation),這讓我想起了的Haskell或lambda函數的演算類型(calculus types):

{T => U} 表示一個從T到U的函數{T => U => V} (或者這種形式{T,U => V}?) 表示一個從 T和U到V的函數

我認為,這種標記方法是許多Java從業者不太喜歡此提案的原因之一。另一個原因顯然歸因于非局部(nonlocal)環境語句(return ,break等)。新問題再次出現,非局部是指那個局部?嗯,舉個例子來說吧,這意味著返回語句將不會從閉包返回,而是從調用該閉包的區域內返回。它們不是綁定在閉包上,而是綁定在一個環境中。為什么這會是一件好事呢?親愛的讀者,下一節將為您詳細說明。

一個使用的例子:

  1. {Integer => void} print = { Integer x => System.out.println(x); } 

b) CICE (簡明實例創建方式,Concise Instance Creation Expressions)

這是三個提案中最簡單的一個。基本上,它只起到在語法上不斷定義匿名類的作用而已,沒有其他的用處。沒有第一類函數(first class functions)!沒有晦澀難懂的函數編程理論!

以下是一個例子:

  1. public interface IPrint { public void invoke(Integer x);} // exacltly 1 method!  
  2. Print print = IPrint(Integer x) { System.out.println(x); } 

雖然CICE是最簡單的提案,但我認為它也是最煩人的一個提案:你必須經常返回去查詢一些接口的定義,真是太差勁了!

c) FCM(第一類方法,First Class Methods)

這是上面兩個方案的折衷:它引入了第一類函數,但其閉包返回語句中并沒有包含非局部綁定,而且去掉了讓人討厭的lambda形式符號。(51CTO編者注:FCM是此次Sun宣布通過的提案,詳見Devoxx大會的相關報道。不過,作者這篇文章寫于Devoxx之前,當時對此還并不知曉。)

以下是一個例子:

  1. #(void(Integer)) print = #(Integer x) { System.out.println(x); } 

從以上三類的語法構成上來說,我最喜歡的BGGA提案,因為你能夠用熟悉的代碼塊(code-block)方式來編程,而不必使用FCM的hash和CICE的接口標簽。

  1. #(void(Integer)) print = #(Integer x) { System.out.println(x); } 

2.爭論

說得客氣一點,我有時覺得這場辯論有點幼稚。下面是典型的辯點:

◆正方觀點:如果沒有閉包,我將永遠不會用Java寫哪怕一行代碼,我會轉而使用Scala進行編程。

◆反方觀點:如果引入閉包,我將會崩潰掉……雖然我不會轉向其它語言,但我會因此而怨恨你!

得了吧,各位!只不過是一個語言的特性而已。如果你不喜歡的話,你不使用它不就得了嗎?而且,選擇什么語言進行開發,是由項目經理決定,而不是由開發人員說了算!如果經理們認為一個語言能夠帶來某種好處,那么該語言就有可能被采用。但這與你是否喜歡Scala或其他所謂更好的語言沒有半點的關系。

那么,閉包是否會使Java變得異常復雜?閉包是否真的如下面所說的那樣:

 “……使編程語言變得復雜,超過了正常的可用范圍:主流程序員將放棄Java,人們還會繼續爭論下去,然后會轉向使用其它更為簡單的編程語言……

Java會變成一個只有小范圍內的專家才會使用的稀有語言”?

那請你告訴我,對JVM而言什么語言是最簡單的!我找不出最簡單的語言(非腳本語言)。專家語言(Guru language)?你在開玩笑嗎?閉包的目的是讓Java變得更簡單,因此每個人都應該開心才對。為什么要害怕呢?

一個可能的答案(非PC)是:認為“太復雜”的一方對Java的現狀很滿意,他們不關注語言優雅性的是否缺失,而且不想學習新的機制。或許這是因為在某種程度上,Java已經存在著太多的機制(或范型(paradigms))了?而對我來說,作為一個使用C++的開發人員,我已習慣了“多范型設計”,因為C++在這方面確實包羅萬象。我不會去考慮那些我目前使用不到的機制。

也許,這對Java領域來說并不簡單,因為多年以來Java程序員一直被灌輸一種常識,即世界上只有面向對象這一種范型。這可以解釋人們為什么認為泛型(generics)的加入會使語言的復雜性大大增加(另一個解釋是設計選擇上(特別對于通配符)需要考慮向后兼容性)。

因此,事情似乎是這樣:要么是由于人們對泛型機制的憤怒,要么是由于BGGA提案中包含非局部變量返回這一不常用的做法,激起了人們的強烈反對。你難道不這樣認為嗎?

3.討論

讓我們的描述得更加技術一點:為什么我們在Java里面需要閉包呢?答案很可能是:因為Ruby語言里面有這個東西。Java 社區似乎還集體性的停留在一個過去Ruby所帶來的創傷,而仿效Ruby的特性在其本身看來理由十分充分。正如過去人們在鐵幕時期常常說的那樣:學習Ruby就是學習如何取勝!所以現在,就像在Ruby(或者Groovy和C#)里一樣,我們能夠用Java這樣編程:

  1. Utils.forEach(names, { Integer x => System.out.println(x); }); // BGGA 

而這是我們在帶有STL和lambda庫的C++里面常常使用的東西。

不過,以上的敘述也不是爭論的全部。上述三個提案中每個都有第二部分,能夠允許包含某些細致的資源管理,可以認為這是一種“現代的析構函數”。我只能說“最終這樣做了”,因為Java后期的資源管理非常麻煩。

BGGA試圖通過上面提到的非本地控制語句來達到這個目標,然后可以允許執行“execute around”模式,即所謂的“控制抽象化”,但是有些不是很直觀。在BGGA提案里,關鍵詞是根據詞匯綁定的,而且會自動指向定義了閉包的嵌套類型(enclosing type)實例。對我來說,Groovy一定程度上比較清楚的解決了非本地綁定的問題——引進了兩個閉包成員:owner(關于嵌套對象)和delegate(定義詞匯綁定)。通過這種方式,總是能夠清楚的說明我們需要什么類型的詞匯綁定,delegate的默認值是owner。

其他的提案也試圖解決同樣的問題:CICE包含了ARM(自動資源管理模塊 —— 一個特殊的模塊類型,當不使用它的時候會自動應用處理方法),而FCM 包含了JCA(Java控制抽象化 —— 這個很像上面提到的“execute around“那種類型,而且和BGGA一樣需要非本地的詞匯綁定)。

在這一點上,讓我們試著得出的一些結論是:

第一:C#的3.0版本里面有lambda,C++0x里面同時包含有lambda和auto specifier,如果Java 7里再不包含閉包的話,就會顯得十分陳舊了。

但也不要絕望,目前有一個庫解決方案(http://code.google.com/p/lambdaj/)。在這種情況下,一個庫解決方案是否足夠呢?我不知道,因為它的語法看起來不是很直觀,但是它可能已經是你能夠得到的最佳方案了。

第二:我發現此處最有教育意義的內容是:我們能夠看到析構函數的老概念其實一點也不過時!既然C#有它的使用聲明,那么Java也理應(而且需要)包含一些類似于析構函數的機制。Java這一(前)“現代語言”也需要如此。

原文:Java's Closures Debate for C++ Eyes  作者:Marek Krj

責任編輯:yangsai 來源: 51CTO.com
相關推薦

2015-10-15 11:27:02

cookie安全總結

2013-06-09 16:49:56

布線系統TIA40Gb

2015-05-26 15:17:44

OpenStack

2011-09-27 09:16:36

JavaScript

2012-04-17 09:17:35

HTML 5App應用

2022-05-06 16:18:00

Block和 C++OC 類lambda

2011-07-27 16:55:12

Objective-c 閉包

2015-05-20 12:50:42

C#開發抽象增刪改

2011-05-16 17:02:44

云計算

2021-03-15 10:29:50

人工智能

2012-06-20 13:36:42

Surface平板

2009-06-15 09:43:11

Java閉包

2019-04-04 14:05:20

consolejs前端

2019-07-10 10:20:36

前端用戶體驗javascript

2015-10-21 16:47:47

Testin云測

2009-08-19 09:57:01

C++ RAII

2024-01-22 09:51:32

Swift閉包表達式尾隨閉包

2009-08-19 10:09:21

C#和C++

2011-08-05 09:33:30

Func局部變量作用域

2010-03-23 09:54:35

好壓壓縮
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久精品欧美视频 | 看片地址 | 中文字幕视频在线观看 | 亚洲一区中文字幕 | 性高湖久久久久久久久3小时 | 搞av.com| 国产精品毛片久久久久久 | 91在线资源 | 黄网免费看 | 91精品久久久久 | 国产日韩欧美在线观看 | 成年免费在线观看 | 日韩在线xx| 久久久一区二区 | 欧美精品一区二区三区四区五区 | 国产精品一区二区久久 | 福利成人| 日韩中文在线 | 视频国产一区 | 国产亚洲欧美日韩精品一区二区三区 | 亚洲欧美中文字幕在线观看 | 欧美一区二区三区在线看 | 欧美精品一区二区在线观看 | 一级欧美黄色片 | 91成人在线 | 国产中文字幕在线观看 | 欧美激情视频一区二区三区在线播放 | 色偷偷噜噜噜亚洲男人 | 综合二区 | 人人人人爽 | 成人午夜黄色 | 日韩在线欧美 | 欧美日韩国产一区 | 91直接看 | 精品国产一区二区三区免费 | 黑人精品xxx一区一二区 | 国产亚洲精品精品国产亚洲综合 | 四虎影院在线观看免费视频 | 最新中文字幕在线 | 狠狠狠干 | 久久国产综合 |