征服复杂性,Eckel谈Java、Python及块理论
在布鲁斯·埃克尔的《Java编程思想》一书的开头,他在1998年提到:
编程就是管理复杂性:你想解决的问题的复杂性,加上你用来解决这个问题的机器的复杂性。正因为这种复杂性,我们的大多数编程项目都失败了。然而,在我知道的所有编程语言中,没有一种语言完全致力于征服开发和维护程序的复杂性。
在第二版及后续版本中,他补充了这段脚注(大约在2003年):
我在第二版中收回这句话:我认为Python语言在征服复杂性方面做得最接近。请见www.Python.org。
我对Java有一点了解,之前学过Delphi(Pascal)、C、C++和Python。以下是我想知道的:
埃克尔认为Python在征服复杂性方面“更好”的具体原因是什么?他的看法是否与其他使用过这两种语言的人一致?
你对征服复杂性有什么看法?Python更简洁的语法是否是征服复杂性的关键(因此,Jython可能是连接Java强大库和Python简洁语法的好桥梁),还是Java的强类型思想(这个思想是从C++继承来的,而C++又是从Simula继承的)是征服复杂性的关键?或者是快速应用设计工具(比如Delphi,或者Java的优秀免费NetBeans窗口/表单设计工具)或组件、beans、J2EE?对你来说,什么才是征服一切的关键?
这个话题已经被标记为主观讨论。[编辑]
注意:关于布鲁斯为什么喜欢Python的更多想法可以在这里找到。文章中的一句关键引用:
布鲁斯·埃克尔:人们说你能在脑海中记住七个加减二的信息。我记不住如何在Java中打开文件。我写过关于这个的章节,做过很多次,但步骤太多了。当我真正分析时,我意识到这些只是他们做出的愚蠢设计决定。即使他们坚持在java.io中使用装饰器模式,他们也应该有一个方便的构造函数来简单地打开文件。因为我们总是需要打开文件,但没有人能记住怎么做。这太多信息了,无法在脑海中保持。
所以,关于信息块理论。根据信息块理论的标准,Python在这方面远远超过其他语言。我承认这一点。但你用什么标准来衡量?我特别邀请大家为Java辩护,反对布鲁斯,如果你愿意的话。
[请不要投票重新开启,这个话题本身就很敏感,而我的失误让它更加敏感。我同意版主的看法。]
5 个回答
然而,在我知道的所有编程语言中,没有一种语言完全致力于解决开发和维护程序的复杂性这个主要设计目标。
几乎每一种编程语言都是为了应对复杂性而设计的。 其实没有其他更值得追求的目标。汇编语言、C++、Java、Python,以及几乎所有存在的语言,都是为了让编程变得更简单。
那么,Python是如何应对复杂性的呢?
在我看来,Python的语法是所有语言中最直观的之一。它使用缩进来表示代码块,这解决了很多问题,而且它的语法接近于自然语言。比如,M = [x for x in S if x % 2 == 0]
就是一个很好的例子,想了解更多可以看看任何一本Python书。
Python更简洁的语法是应对复杂性的关键吗?
我认为Python的简单语法确实是应对复杂性的一个好方法。不过,这也是我能给你关于你另一个问题的唯一明确答案:
你怎么看待应对复杂性的问题?
你问的问题正是语言理论的核心,这个问题的争论可能会持续到世界的尽头。比如,静态类型和动态类型就是一个这样的争论。语言理论中还有很多其他的发展,比如过程式编程、面向对象编程、函数式编程和面向方面编程,它们都在尝试简化编程。看看最新的(或任何)语言版本,看看他们是如何“应对复杂性”的。永远不会有一个明确的答案,全面讨论每种方法可能需要几个月的时间,而且到你读完的时候,情况可能已经完全改变了。:D
布鲁斯·埃克尔:人们说你大脑里能同时记住七个左右的信息。我却记不住怎么在Java里打开文件。
我可以:
new FileInputStream(filename);
我写过关于这个的章节,也做过很多次,但步骤实在太多了。当我仔细分析的时候,才发现这些其实都是他们做出的愚蠢设计决定。即使他们坚持在java.io中使用装饰器模式,他们也应该提供一个方便的构造函数,让打开文件变得简单。
通过写一个简单的工具方法,这个问题几分钟就能解决。而且确实已经解决了。如果这是对Java的最强烈批评,那我对它的印象就不太深刻了。
我觉得布鲁斯是受到了弗雷德·布鲁克斯的启发,他在他的文章《没有银弹》中谈到了复杂性,并描述了两种类型。第一种是问题本身固有的复杂性,他称之为“本质复杂性”,无论你用什么语言,这种复杂性都是一样的。第二种是我们使用的工具和语言带来的复杂性——这些都是你需要考虑的内容,但并不直接帮助解决问题。按照这个标准,Java的复杂性远远超过Python。最简单的例子就是经典的“Hello World”程序。在Python(和其他几种语言)中,它只需要一行:
print "hello World!"
而在Java中,它是
class HelloWorld {
static public void main( String args[] ) {
System.out.println( "Hello World!" );
}
}
其中大部分内容和打印“Hello World”这个任务没有关系,基本上是多余的噪音。
在我看来,有几个因素使得Java相比于Python等其他语言更复杂。
1) 所有东西都必须放在一个类里面。这迫使你使用面向对象的编程方式,即使在不合适的情况下,比如上面的例子,还要添加很多不必要的类定义。
2) 尽管它强制你使用类,但它并不是完全的面向对象。我的意思是,并不是所有东西都是对象,比如基本数据类型和方法。在Python中,你可以对所有内置类型进行子类化,并像其他对象一样传递函数和方法。
3) Java不是函数式编程语言——实际上,它还特别阻止你使用函数式编程。能够传递函数、创建闭包和匿名函数可以简化很多代码。在Java中,最接近的做法是使用匿名内部类来处理回调。
4) Java要求你到处都要写类型声明,这增加了很多杂乱无章的内容,却没有提供有用的信息。这不仅仅是静态类型和动态类型的问题——像Scala这样的静态类型语言可以在90%的情况下推断类型,从而减少噪音。
5) 尽管Java强制使用静态类型,但许多(可能大多数)实际的Java程序在某些情况下使用动态类型检查。每次你将一个对象转换为特定类型时,都是在进行动态类型检查——在Java 5之前,每次使用容器类时都是如此。即使在使用泛型容器时,它们的一些类型检查也是在运行时进行的。此外,每当你有一个包含类或方法名称的XML文件时,代码中的某个地方都必须进行动态类型检查,以确保它与真实的类匹配。因此,许多Java程序仍然面临动态类型的“危险”,但却要添加Java静态类型所强迫的冗长代码。
我可以继续说下去(而且经常会这样做),但我在这里结束,观察到我看到的很多Python代码比Java的代码更简单、更清晰、复杂性更低,但反过来却没有。如果有人能给我指个例子,我会很想看看。