论坛首页 Java企业应用论坛

再论闭包

浏览 24733 次
锁定老帖子 主题:再论闭包
该帖已经被评为良好帖
作者 正文
   发表时间:2009-06-25   最后修改:2009-06-25
to楼主:icefishc和幸存者都有其它语言的经历(C#、smalltalk、python、perl),而且给出了不少例证,请重点读读幸存者前面的贴:

幸存者 写道
闭包的核心概念就两个:一等函数(即可以作为参数的函数)和可使用外部变量。
没有什么单纯或不单纯的闭包之说,那些东西完全取决于某种语言如何实现闭包,而不取决于闭包本身的概念。
OO从来没有规定函数不能成为一等公民,也没有规定函数一定不能是对象,事实上早在70年代,函数和类在smalltalk中都是对象。说闭包不是对象或函数不能是对象完全没有道理。


赞同这个说法。能不能给闭包自定义属性和方法,能不能继承、多态,取决于这个语言想不想支持,而不是能不能做到的问题。

看ruby的:

# 用变量closure接收一个闭包
def hello(&closure)
  closure.instance_eval do
    # 给它设置属性
    @var = "hello"

    # 给它添加方法
    def x
      @var + " " + self.call
    end
  end
  
  # 调用这个闭包上新加的方法
  closure.x
end

# 向hello传入一个闭包{"world"}
puts hello{
  "world"
}


看你贴过groovy的代码,仔细研究一下groovy,应该能得到相同的结论(通过metaclass等)。closure作为一等公民,可以被一个普通的变量引用、传递。在ruby里意味着它是Proc的一个对象(实例),自然可以调用Proc的方法(比如call)。以java的视角,类是用来组织数据的,不是描述行为。而对于ruby,行为也是数据,也可以用类描述,类也是对象,类的类还是对象,这才是真正的Everything is Object。楼主受java和java所谓的OO的影响太深,评判这些问题时,应该眼光往外多看看,避免思维定势。尤其应该深入学习一门带闭包的语言,看看它到底是怎么用的。

你主贴的第三点:“易理解吗?” 因为举的例子没有什么业务含义,我觉得两个都不易理解。
但你看,java代码里多出来的ResourceUser类、use方法,使它的代码变得冗长,同时,使用者还要多记忆两个名词。相比groovy代码,这两个名词分明是多余的。重复了!坏味道。重构-消除重复。使用闭包可以做到。

如果不在语法级修改,能消除重复也行,问题是,你后面这段代码灵光吗?
引用

new ResourceHandler(){  
     protected void handle(Resource resource){  
        //doSomething ....  
        resource.doSomething();  
        //doSomething ....  
    }  
 }.handle(request); 
5 请登录后投票
   发表时间:2009-06-25  

to liusong1111: 首先谢谢你的回帖! 前面的所有回复我都认真看过,我不了解ruby,但大约看懂了你的代码, ruby中的闭包确实可以添加方法,添加属性。

因为ruby里的闭包被封装成了对象 groovy也一样,

println ({it*it} instanceof Object)
//output:
//true
 
对闭包的调用,实际上是对封装闭包的对象方法的调用

def closure = {it*it}

println closure(2)
//  ||
println closure.call(2)
 
闭包无疑是从FP中引入的概念(计算机领域)
一种编程语言引入它 是因为它的轻巧,简洁。
我想不是因为它具有OO特性吧



1 请登录后投票
   发表时间:2009-06-25  
没用的东西。
不是骂人。
没有本质差别,不过是个匿名的方法而已,加速不了软件的开发,也不可能用这些东西就把一个低级程序员变成高级程序员,顶多少打几行字而已。
因为软件开发,并不取决于打字的速度,所以,语言是否优秀,也不取决于它的语法是否能够少写几个字。
0 请登录后投票
   发表时间:2009-06-25  
Saito 写道
  暂时把楼主归为 倒 闭包派。。

  就跟 inter 有 挺穆  跟  倒穆。。

       AC milan 有挺安  跟 倒安一样。。 ms现在还可以投票取消闭包。


  说实话。 Java 7 可能是对Java社区的一次强大冲击。 不亚于Java 5 。 企业级应用里面为什么爱用Java。 首先面向对象。 开源社区足够强大。 语法足够简单。一些大公司他们连 泛型都不用。 1.4用到死。。就别提Java 7 了。

  我始终觉得。 Java老向c#靠拢就走歪了。 盖房子的工人没必要还一身amani。。

相当精辟,大公司都倾向于使用稍微老点的版本。
0 请登录后投票
   发表时间:2009-06-28  
步行者 写道

 

interface ResourceUser {
    void use(Resource resource)
}
resourceHandler.handle(new ResourceUser(){
    public void use (Resource resource) {
        resource.doSomething()
    }
});

 

下面是一段等价 Groovy 的代码。

resourceHandler.handle { resource -> resource.doSomething() }

 

惊叹吧 ?  8行JAVA代码居然被 Groovy 如此 easy 地实现了。

惊叹! 惊叹之余再来反思。。。

 

行数比例貌似 8:1 

 

0 请登录后投票
   发表时间:2009-06-29  
步行者 写道

to liusong1111: 首先谢谢你的回帖! 前面的所有回复我都认真看过,我不了解ruby,但大约看懂了你的代码, ruby中的闭包确实可以添加方法,添加属性。

因为ruby里的闭包被封装成了对象 groovy也一样,

 

println ({it*it} instanceof Object)
//output:
//true
 
对闭包的调用,实际上是对封装闭包的对象方法的调用

def closure = {it*it}

println closure(2)
//  ||
println closure.call(2)
 
闭包无疑是从FP中引入的概念(计算机领域)
一种编程语言引入它 是因为它的轻巧,简洁。
我想不是因为它具有OO特性吧



 

争论源于“闭包与OO格格不入“的论断。

你上面的逻辑,如同说“对象上的操作,实际上是对封装对象行为的函数的调用“,因此,”面向对象“与”过程式编程“格格不入,“面向对象”没有意义。

最终又归结到信仰问题了。

0 请登录后投票
   发表时间:2009-08-13  
过十年再看那时的OO是什么样吧,觉得现在的争论毫无意义
0 请登录后投票
   发表时间:2009-08-14  
java 其实应该走像的是 更简单更OO得道路
java 应该像操作系统中的linux 走向简单稳定
菜鸟意见。。。。欢迎攻击。。。
0 请登录后投票
   发表时间:2009-08-18   最后修改:2009-08-18
Juiz 写道
其实 java 不是真正的面向对象,充其量只是“面向类”,java 的啰嗦语法很容易导致冗长重复,继而产生连锁效应:
需要借助 IDE 生成代码,而生成代码的可读性就更差了;
长代码导致出错增加、重构困难、bug 迷雾;
代码越长,要求的注释越多;
为了分而治之,衍生出各种分层理论,design over code 之类的,但是层数越多,调用栈就越复杂,弹出巨大的 stack trace 你根本弄不清问题在哪 ……

这些问题归结到底,就是欠缺清晰、简洁的表达造成的。

OO 到了极致,从指令流程序变成数据流程序,便成为了函数式语言,这里头的东西几十年就研究通透了 …… 在精巧设计的 lambda 面前,很多杂乱的语言特性如 annotation、for in、try...catch 都变得没有价值,很多庞大的库和大量使用了 xml 的框架都会变成鸡肋 —— 因为用闭包可以更简单的做到。像上面的例子,很多人只看到少了 7 行,其实是少了 7/8 ……

可是现在 java 语言做一点点微小的进步都非常困难 …… 不进步便消亡,只是关系到数量庞大的公司和个人的利益,消亡的过程肯定比较缓慢。

照你的逻辑,Java早该灭亡了,有Lisp还要Java干嘛?Lisp是银弹啊?

你的逻辑中有一个很严重的误导就是,程序复杂以及代码可读性差是由于Java本身过于复杂造成的,而实际上绝大多数复杂性是由于固有的业务复杂性造成的,而不是语言本身。语言本身的提高只能缓解一定的编程复杂度,但是不能减少任何业务本来固有的复杂度,不存在银弹的。
0 请登录后投票
   发表时间:2009-08-18  
icewubin 写道
Juiz 写道
其实 java 不是真正的面向对象,充其量只是“面向类”,java 的啰嗦语法很容易导致冗长重复,继而产生连锁效应:
需要借助 IDE 生成代码,而生成代码的可读性就更差了;
长代码导致出错增加、重构困难、bug 迷雾;
代码越长,要求的注释越多;
为了分而治之,衍生出各种分层理论,design over code 之类的,但是层数越多,调用栈就越复杂,弹出巨大的 stack trace 你根本弄不清问题在哪 ……

这些问题归结到底,就是欠缺清晰、简洁的表达造成的。

OO 到了极致,从指令流程序变成数据流程序,便成为了函数式语言,这里头的东西几十年就研究通透了 …… 在精巧设计的 lambda 面前,很多杂乱的语言特性如 annotation、for in、try...catch 都变得没有价值,很多庞大的库和大量使用了 xml 的框架都会变成鸡肋 —— 因为用闭包可以更简单的做到。像上面的例子,很多人只看到少了 7 行,其实是少了 7/8 ……

可是现在 java 语言做一点点微小的进步都非常困难 …… 不进步便消亡,只是关系到数量庞大的公司和个人的利益,消亡的过程肯定比较缓慢。

照你的逻辑,Java早该灭亡了,有Lisp还要Java干嘛?


因为使用者众,程序也多,断无一夜之间全部消失之理。
4 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics