论坛首页 综合技术论坛

静态类型语言的优势究竟是什么?

浏览 53727 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2006-11-13  
在参与这个讨论的过程中,产生了一个新的话题,很想和大家探讨一下:

http://www.iteye.com/topic/33890

引用
是像Java或者C#这样强类型的准静态语言在实现复杂的业务逻辑、开发大型商业系统、以及那些生命周期很长的应用中也有着非常强的优势


这是一个存在于大家心里常识了。我承认我自己在潜意识里面也觉得静态强类型语言适合开发复杂,大型系统。而弱类型脚本语言不适合开发太复杂,太大型的项目。但是在参与这个讨论过程中,我突然开始置疑这个观点,事实究竟是不是这样的呢?

先定义一下标准:

强类型语言(静态类型语言)是指需要进行变量/对象类型声明的语言,一般情况下需要编译执行。例如C/C++/Java/C#

弱类型语言(动态类型语言)是指不需要进行变量/对象类型声明的语言,一般情况下不需要编译(但也有编译型的)。例如PHP/ASP/Ruby/Python/Perl/ABAP/SQL/JavaScript/Unix Shell等等。

引用
观点一:静态类型语言因为类型强制声明,所以IDE可以做到很好的代码感知能力,因为有IDE的撑腰,所以开发大型系统,复杂系统比较有保障。


对于像Java来说,IDEA/Eclipse确实在代码感知能力上面已经非常强了,这无疑能够增加对大型系统复杂系统的掌控能力。但是除了Java拥有这么强的IDE武器之外,似乎其他语言从来没有这么强的IDE。C#的Visual Studio在GUI开发方面和Wizard方面很强,但是代码感知能力上和Eclipse差的不是一点半点。至于Visual C++根本就是一个编译器而已,羞于提及Visual这个字眼。更不要说那么多C/C++开发人员都是操起vi吭哧吭哧写了几十万行代码呢。特别是像Linux Kernel这种几百万行代码,也就是用vi写出来的阿,够复杂,够大型,够长生命周期的吧。


引用
观点二:静态语言相对比较封闭的特点,使得第三方开发包对代码的侵害性可以降到很低。动态语言在这点上表现的就比较差,我想大家都有过从网上下载某个JS包,然后放到项目代码里发生冲突的经历


也就是说静态类型语言可以保障package的命名空间分割,从而避免命名冲突,代码的良好隔离性。但是这个观点也缺乏说服力。

静态类型语言中C,VB都缺乏良好的命名空间分割,容易产生冲突,但是并没有影响他们做出来的系统就不够大,不够复杂。

而Visual C++开发的DLL版本冲突也是臭名昭著的,似乎C++的命名空间没有给它带来很大的帮助。

而动态类型语言中Ruby/Python/Perl都有比较好的命名空间,特别是Python和Perl,例如CPAN上面的第三方库成吨成吨的,也从来没有听说什么冲突的问题。

诚然像PHP,JavaScript这样缺乏命名空间的动态语言很容易出现问题,但是这似乎是因为他们缺乏OO机制导致的,而不是因为他们动态类型导致的吧?

说到大型系统,复杂业务逻辑系统,Google公司很多东西都是用python开发的,这也证明了动态类型语言并非不能做大型的复杂的系统。其实我个人认为:

动态类型语言,特别是高级动态类型语言,反而能够让人们不需要分心去考虑程序编程问题,而集中精力思考业务逻辑实现,即思考过程即实现过程,用DSL描述问题的过程就是编程的过程,这方面像Unix Shell,ruby,SQL,甚至PHP都是相应领域当之无愧的DSL语言。而显然静态类型语言基本都不满足这个要求。

那静态类型语言的优势究竟是什么呢?我认为就是执行效率非常高。所以但凡需要关注执行性能的地方就得用静态类型语言。其他方面似乎没有什么特别的优势。
   发表时间:2006-11-13  
引用
说到大型系统,复杂业务逻辑系统,Google公司很多东西都是用python开发的,这也证明了动态类型语言并非不能做大型的复杂的系统。其实我个人认为:

动态类型语言,特别是高级动态类型语言,反而能够让人们不需要分心去考虑程序编程问题,而集中精力思考业务逻辑实现,即思考过程即实现过程,用DSL描述问题的过程就是编程的过程,这方面像Unix Shell,ruby,SQL,甚至PHP都是相应领域当之无愧的DSL语言。而显然静态类型语言基本都不满足这个要求。

那静态类型语言的优势究竟是什么呢?我认为就是执行效率非常高。所以但凡需要关注执行性能的地方就得用静态类型语言。其他方面似乎没有什么特别的优势。

嗯,我的一点感觉,动态语言足够灵活,因此虽然它能够让人更集中精力思考业务逻辑的实现,同时也向人工智能的方向走得更近一些,但因此它也更依赖于开发人员本身的技术功底,初学者、中级开发者,难以很好的利用它。

而静态类型语言,与我们计算机教学的基本科目(c/pascal/basic)延续性比较好,所以对于刚毕业的学生而言,更好接受和学习。

因此我觉得还是学习/培训/开发成本占主要因素。

一个不太恰当的例子:javascript的正则表达式,虽然功能强大,但并不易理解和学习。一般只能copy/paste来用。所以很多情况下,还是宁愿手写标准js来处理。
0 请登录后投票
   发表时间:2006-11-13  
我感觉类似Java这样的强类型的准静态语言还有一个重要的特点。一旦程序员基本掌握了语法规则和书写规范,写出来的程序的可读性会强很多,因为它本身的限制更多。在一个大型系统中,Team成员之间互相可以知道对方在写什么是非常关键的,这也成为了交流的重要基础。

然而Ruby这样的语言,虽然看上去更加符合“描述问题即解决问题”,但是对于同一段逻辑,同样可以满足要求,写法上却差别很大。我曾经见过用1行写出来的解决数读算法的Ruby解法,谁能看懂?
0 请登录后投票
   发表时间:2006-11-13  
downpour 写道

然而Ruby这样的语言,虽然看上去更加符合“描述问题即解决问题”,但是对于同一段逻辑,同样可以满足要求,写法上却差别很大。我曾经见过用1行写出来的解决数读算法的Ruby解法,谁能看懂?


对这一点我也有类似的看法,有人曾经用例子试图说明ruby在写代码时如何短小,经常写在一行,其实逻辑单元都一样多,反而降低了可读性。看上去并不诱人。
0 请登录后投票
   发表时间:2006-11-13  
robbin兄,关于敏捷开发,我需要你的一些建议:

最近我自己有一个网站项目(小型房产网站的部分模块),周期很紧,加上平时工作也较忙,不想采用已经很熟悉的ww+spring(那个开发速度简直是),后来想选用Seam/RoR的,考虑到Seam都是java标准的东西,一是比较熟悉,学习起来可能比较快一点,二来j2ee的东西以后功能和规模扩展肯定没问题,但是发现实际上手进行很不顺利 -- seam/jboss as版本间的不兼容,开发工具也不好用,也没有详细可用的指导,seam的例子按照tutorial很多跑不起来,很是受挫,真没信心短时间内掌握seam并付诸实际开发。
后来看了你的《应用Rails进行敏捷Web开发》中文版书评,很是心动,但现在问题是我对于Ruby / rails一点都不了解,能很快从一点不懂到开发上面所说的站点么,在一个月的时间内?
谢谢robbin.
0 请登录后投票
   发表时间:2006-11-13  
引用
我感觉类似Java这样的强类型的准静态语言还有一个重要的特点。一旦程序员基本掌握了语法规则和书写规范,写出来的程序的可读性会强很多,因为它本身的限制更多。在一个大型系统中,Team成员之间互相可以知道对方在写什么是非常关键的,这也成为了交流的重要基础。

然而Ruby这样的语言,虽然看上去更加符合“描述问题即解决问题”,但是对于同一段逻辑,同样可以满足要求,写法上却差别很大。我曾经见过用1行写出来的解决数读算法的Ruby解法,谁能看懂?


从何讲Java的可读性?

我更经常见到的是Java程序员屁大点事写几百行,Ruby几行就搞定了。哪一个更好读?

代码量虽然不是全部,但是从一个侧面反映了代码的可读性。
0 请登录后投票
   发表时间:2006-11-13  
我更经常见到的是Java程序员屁大点事写几百行,Ruby几行就搞定了。哪一个更好读?
---------------
我怀疑是程序员的问题。
和语言的关系不大。
0 请登录后投票
   发表时间:2006-11-13  
静态类型的运行效率不一定高。
haskell的运行效率就不高。
汇编语言也不需要声明什么类型。
C 语言的类型也不是很强。
(根据charon下面的指出。发现这个地方写的有些不对。把静态类型等同于强类型了。)

----------------------------------

静态类型的优势,就在于有编译期类型检查这个步骤。
静态类型,迫使程序员采用强契约。模块实现者和模块调用者都要遵守一个带有强参数类型的强契约。
如果类型是必须声明的,可读性倒是有一点优势,因为一眼可以看到这个变量的类型。
不过有些静态语言采用type inference,不需要声明。和动态类型语言一样,使用富有含义的名字,表示变量的意义。

如果不在乎编译期类型检查这个功能,就没有优势。如果在乎这个功能,就有优势。
正如,如果一个程序员不在乎减少代码量这个优势,那么Ruby就没有什么优势。
0 请登录后投票
   发表时间:2006-11-13  
robbin 写道
先定义一下标准:
强类型语言(静态类型语言)是指需要进行变量/对象类型声明的语言,一般情况下需要编译执行。例如C/C++/Java/C#
弱类型语言(动态类型语言)是指不需要进行变量/对象类型声明的语言,一般情况下不需要编译(但也有编译型的)。例如PHP/ASP/Ruby/Python/Perl/ABAP/SQL/JavaScript/Unix Shell等等。


应该说强类型/弱类型和动态类型/静态类型还是有一些微妙的区别的。几年前我也犯过与robbin一样的直觉错误.
静态类型语言是指在编译时变量的数据类型即可确定的语言,多数静态类型语言要求在使用变量之前必须声明数据类型,某些具有类型推导能力的现代语言可能能够部分减轻这个要求.
动态类型语言是在运行时确定数据类型的语言。变量使用之前不需要类型声明,通常变量的类型是被赋值的那个值的类型。
强类型语言是一旦变量的类型被确定,就不能转化的语言。实际上所谓的貌似转化,都是通过中间变量来达到,原本的变量的类型肯定是没有变化的。
弱类型语言则反之,一个变量的类型是由其应用上下文确定的。比如语言直接支持字符串和整数可以直接用 + 号搞定。当然,在支持运算符重载的强类型语言中也能通过外部实现的方式在形式上做到这一点,不过这个是完全不一样的内涵
通常的说,java/python都算是强类型的,而VB/Perl/C都是弱类型的.
不过相比于动态/静态语言的分类,强类型/弱类型更多的是一个相对的概念。
0 请登录后投票
   发表时间:2006-11-13  
buaawhl 写道

静态类型的优势,就在于有编译期类型检查这个步骤。
静态类型,迫使程序员采用强契约。模块实现者和模块调用者都要遵守一个带有强参数类型的强契约。
如果类型是必须声明的,可读性倒是有一点优势,因为一眼可以看到这个变量的类型。
不过有些静态语言采用type inference,不需要声明。和动态类型语言一样,使用富有含义的名字,表示变量的意义。

如果不在乎编译期类型检查这个功能,就没有优势。如果在乎这个功能,就有优势。
正如,如果一个程序员不在乎减少代码量这个优势,那么Ruby就没有什么优势。


其实编译期类型检查可以做的比想象的要多。不仅仅是确定了类型,而且确定了这个类型上可以做的操作。
比如动态类型
def a(arg1):
    ....
    arg1.xxx(yyy,zzz)

这个写法和静态类型的
void a(Circle arg):
    arg.xxx(yyy,zzz)

后者验证的不仅仅是调用方传入的参数类型如何,而且也验证了针对这个类型的传入参数a这个函数能够干些什么。在某种意义上说,这也是一个解耦合的做法。调用方只需要确保参数类型正确,方法执行方确保自身内部的执行序列在语法上必然可以执行。调用方只需要根据a函数的较为概略的文档知道要传入一个什么类型,会有什么结果发生就可以了,是相对黑盒的。
而对前者而言,a的这个文档不仅仅要说明干什么事情,而且要说明怎么干的(即对传入参数干了些什么事情),如果传入的arg不支持被这么干,就不能把它传进去。这个说明是相对白盒的。这里其实有个很有意思的问题,既然我对传入参数有要求,为什么不把它显式固定下来。
另一方面,在实际的处理过程中,如果采用了更多的测试,是可以排除动态类型调用中由于参数误传入而导致的错误的。但是,有一点不可否认,这个错误会在被调用方抛出,针对被调用方是框架或库的情况,有时候会出现烦人的情况,不利于准确定位。
0 请登录后投票
论坛首页 综合技术版

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