征服复杂性,Eckel关于Java和Python以及块理论

时间:2010-06-24 19:52:25

标签: java python complexity-theory

在Bruce Eckel的Thinking In Java简介中,他说,1998年:

  

编程是关于管理   复杂性:复杂性   你要解决的问题,放在上面   机器的复杂性   它解决了。因为这   复杂性,我们的大多数编程   项目失败。然而,在所有的   我是编程语言   意识到,他们都没有全力以赴   并决定了他们的主要设计   目标是征服   发展的复杂性和   维护计划。

在第二版及后续版本中,他添加了这个脚注(大约2003年):

  

我把它带回第二版:我相信Python   语言最接近于做   确切地说。见www.Python.org。

我是java的dabbler,有Delphi(Pascal),C,C ++和Python的背景。 这是我想知道的:

  1. Eckel在征服复杂性时称Python为“更好”的时候究竟考虑了什么?他的想法是否已经与其他人同时使用?

  2. 您如何看待征服复杂性? Python的更短和更简洁的语法是一种克服复杂性的关键方法(因此,例如,Jython可能是Java优秀库的一个很好的桥梁,以及Python的简洁语法),或者是Java的强类型思维,从C ++继承了这个想法,从Simula继承了这个想法,我认为它是征服复杂性的关键?或者它是Rapid Application Designer(想想Delphi,还是Java,优秀的免费NetBeans窗口/表单设计器工具)或组件,bean或J2EE?是什么征服了所有人,对你而言?

  3. 这已经被标记为主观的。 [编辑]

    Note: More on Bruce's thoughts, on why he loves Python are found here.文章的主要引用:

      布鲁斯埃克尔:他们说你能坚持下去   七加减两件   信息在你的脑海里。我不能   记得如何用Java打开文件。   我写过章节。我弄完了   它很多次,但它太多了   脚步。当我真正分析它时,   我意识到这些只是愚蠢的设计   他们做出的决定。即使他们   坚持使用装饰器   在java.io中的模式,他们应该有   有一个方便的构造函数   简单地打开文件。因为我们开放   文件一直都在,但没人能   记得怎么样。实在是太多了   要记住的信息。

    所以,块理论。通过块理论度量,Python杀死了其他所有人。我会批他的。但您使用的指标是什么?如果你愿意的话,我想特别邀请人们支持Java,反对布鲁斯。

    [请不要投票重新开放,这个主题本质上是煽动性的,而且我的失言已经让它变得更加如此。我同意主持人的意见。]

5 个答案:

答案 0 :(得分:5)

  布鲁斯埃克尔:他们说你能坚持下去   七加减两件   信息在你的脑海里。我不能   记住如何用Java打开文件。

我可以:

new FileInputStream(filename);
  

我写过章节。我弄完了   它很多次,但它太多了   脚步。当我真正分析它时,   我意识到这些只是愚蠢的设计   他们做出的决定。即使他们   坚持使用装饰器   在java.io中的模式,他们应该有   有一个方便的构造函数   简单地打开文件。

通过使用简单的api编写该实用程序方法,可以在几分钟内解决这个问题。 And it has been。如果这是针对Java的最强烈的批评,我仍然显然不为所动。

答案 1 :(得分:5)

我认为布鲁斯正在接受弗雷德布鲁克斯的暗示,后者在他的论文“无银子弹”中谈到了复杂性,并描述了两种类型。第一种类型是您试图解决的问题所固有的,他称之为基本复杂性,无论您使用何种语言,它都是相同的。第二个是我们使用的工具和语言所增加的复杂性 - 你必须考虑的所有东西都没有直接增加解决问题。通过这种方法,Java比Python复杂得多。最简单的例子是规范的Hello World程序。在Python(以及其他几种语言)中,它是一行:

print "hello World!"

在Java中它是

class HelloWorld {
  static public void main( String args[] ) {
    System.out.println( "Hello World!" );
  }
}

其中大部分与打印“Hello World”的任务无关,基本上都是噪音。

与其他语言(如Python)相比,恕我直言增加了Java的复杂性有几个因素。

1)一切都必须在课堂上。这会强制您使用OO范例,即使它不合适,如上例所示,并添加许多不必要的boilplate类定义。

2)即使它强迫你使用类,它也不是完全面向对象的。我的意思是,并非所有东西都是对象,例如原始类型和方法。在python中,您可以继承所有内置类型并传递函数&像任何其他对象一样的方法。

3)Java不起作用 - 实际上它不会阻止你使用功能范例。能够传递函数并创建闭包和lambda可以简化许多代码。 Java中最接近的是使用匿名内部类来处理回调。

3)Java强迫你在任何地方放入类型声明,这会增加很多混乱,而不会添加有用的信息。这不仅仅是静态与动态问题 - 像Scala这样的静态类型语言可以在90%的时间内推断出类型并消除所有噪音。

4)尽管Java强制您使用静态类型,但许多(可能是大多数)现实世界的Java程序在某些时候使用动态类型检查。每次从Object转换为特定类型时,您都在进行动态类型检查 - 在Java 5中添加泛型之前,这意味着每次使用容器类时都是如此。即使使用通用容器,它们的某些类型检查也是在运行时完成的。此外,每当你有一个带有类或方法名称的XML文件时,它们必须在代码中的某处进行动态类型检查,以确保它与真实类匹配。如此多的Java程序仍然存在动态类型的所谓“危险”,但是Java的静态类型强迫您添加的所有冗长。

我可以继续(并经常这样做),但我会停下来观察我已经看到很多代码在Python中比在Java中更简单,更简洁,更简单,但没有其他方法。如果有人能指出我,那么我很乐意看到它。

答案 2 :(得分:4)

  

然而,在我所知道的所有编程语言中,他们都没有全力以赴,并决定他们的主要设计目标是克服开发和维护程序的复杂性。

几乎每种语言都基于征服复杂性。没有其他目标值得追求。汇编,C ++,Java,Python以及几乎所有其他语言都基于使编程更容易。

  

python如何擅长征服复杂性?

Python肯定有一些任何语言恕我直言的最直观的语法。它使用块缩进解决了很多问题,其中大部分都是close to plain language as you should getM = [x for x in S if x % 2 == 0]是一个很好的例子,可以看到任何更多的python书。

  

Python的更短,更简洁的语法是否是征服复杂性的关键方法?

我相信python的简单语法是征服复杂性的好方法。但是,这是我可以为您的其他查询提供的唯一明确答案:

  

您如何看待征服复杂性?

你问的是语言理论的整个核心问题,其中包括可能会持续到战争结束的战争。 static vs dynamic typing就是这样一场辩论。在语言理论方面还有许多其他发展,例如Procedural vs OO vs Functional语言和面向方面编程,它们试图简化编程。查看语言的最新版本(或任何版本),以查看“征服复杂性”所做的一些示例。永远不会有一个明确的答案,对每种方法的完整讨论需要几个月的时间来阅读,并且可能会在您完成时完全改变。 :d

答案 3 :(得分:3)

对我来说,从Java切换到Python是一个巨大的胜利。我可以更快地编写代码,具有相同或更少的错误,并且更容易修改它。代码也更具可读性,所以当我几个月后回到它时,我可以更快地找出它正在做什么(并且在我不能的时候重写它而没有太多麻烦)。

Java是强类型的,需要大量的工作来设计和维护正确的类型定义。如果您将变量声明为int,然后确定它应该是float,那么您需要在整个程序中更改该类型。您是否将该值存储在数组中?您还需要更改该类型声明。决定重构几个类来共享一个通用接口?您将不得不在整个代码库中更改函数定义来处理它。如果你有一个特别复杂的设计,你会发现自己必须处理很多这些问题。

Python在语言中也有很多支持来改变某些事情的工作方式。例如,Python装饰器可以抽象出复杂代码的 lot (处理缓存或注册函数),从而保持代码维护。复杂的IDE可以帮助维护您的代码,但最好从较简单的语言开始。

答案 4 :(得分:2)

上个学期在我的“OOP With Java”课程中获得了A,并且在Python中自学了几年,加上对编程感兴趣,并用两种语言写了几行K(不包括注释),包括Python中的Jack词法分析器/解析器(并且看到我的同胞用Java执行或不执行),我认为我有足够的经验值得至少花几美分。或者不是,但现在我已经完成tooting my own horn你可以自己决定;)

首先,我完全同意编程是为了降低复杂性。我也同意Java在降低复杂性方面做得不好。

例如,要从命令行获取用户输入吗?

Scanner input = new Scanner(new BufferedReader(System.in));(我认为?自从我使用它以来只有2到3个月)

Python是raw_input(),而在3.0中它只是普通input()

如何从Java中读取文件?嗯,说实话,我不知道。我们没有做太多,而且比Scanner更糟糕。正如已经提到的,Java的复杂性超出了我所知道的任何其他真实语言的复杂程度,但并不像“that”语言那么糟糕。

我认为Java的复杂性的主要问题在于示例meriton用于防御Java。 Java不是导入令人敬畏的社区API并将其作为语言的一部分来实现,而是具有“核心”语言,而API只是其中的一种扩展。我感兴趣的是Java必须为所述API构建API和文档的工具的财富。我的意思是,你编写代码,添加一些注释,并且(至少在Eclipse中)选择菜单中的一个项目,你已经生成了一些漂亮的 javadocs。虽然拥有如此优秀的文档非常棒,但我想知道它是否真的不是必然的,因为查看一个程序会让你没有线索 Java正在做什么。扫描器?缓冲读卡器? WTF?有些层次和层次的复杂性可以(有些人认为应该)被抽象出来。哎呀,我可以打开并阅读程序集中的文件,而不用担心Java。当然,比较几行是非常微不足道的,而且毫无价值,但重点是Java经常引入复杂性,而不是解决它。

这是我认为Python具有优势的最大原因:有用的类型/功能是内置于语言中的,并且它们的名称往往非常好(至少如果它们的名称不是很好,它们就是至少有一些提示)。

例如,假设我想打开逗号分隔文件(不使用额外的API或导入),并将每个元素存储在泛型集合中。

在Python(2.6+或2.5,从未来导入)中,它实际上是两行:

with open('myfile.csv') as f:
    print f.read().split(',')

进行。

在Java中,我不认为你可以在不导入外部类的情况下完成它。当然,实际上我认为任何一种语言都会偏好,可能是遗传学或培训。

有些人认为静态或动态类型引入的复杂性最小。我落入后一阵营,但我理解这个论点。毕竟,如果你尝试传递一个不同的类型,你的编译器会抱怨,并且你总是知道应该是什么,因为它要么被显式声明,要么被强制转换。当然,这增加了铸造操作的复杂性(虽然可能很小),但它不仅要怀疑“我在世界上如何将整数传递给浮动字符串?”

但是当它归结为它时,大多数人们可以看看Python程序并了解正在发生的事情。非常高级程序员的新手程序员将能够通过查看它来理解程序和目的。哎呀,我刚刚通过阅读(差)文档和阅读Bazaar内置函数的代码,为Bazaar编写了一个插件。它花了相对较少的努力,甚至还有一些自定义定义。某些golly脚本也是如此。在我的Java类中编写代码时,我也能够理解其他classes。但是,我认为我在该类中处于非常有利的地位,因为Java概念非常类似于Python概念。反之亦然,无论你喜欢哪种方式。 (或者它们都与Lisp概念相似;)

老实说,我认为复杂性只是学习曲线。 Python具有非常浅的学习曲线,其功能是学习曲线的反函数。 Java具有更陡峭的学习曲线,其功率曲线具有线性(2x?3x?)关系。一旦你学会了语言和基本概念,我认为这两种语言的复杂性都会降到接近零。