👉原文链接
动态语言
动态语言是“微机时代”的代表,为编写KB级项目而设计的,从技术上讲非常过时。windows95出现之后,绝大多数动态语言都“死掉”了。
微机时代计算机并不是独立学科,而是属于电工学的一个分支。所以严格意义上,当时没有程序员,只有“写代码的电工”。
微机时代的计算机使用软盘储存数据,最大容量才1.4MB,程序都特别简单,一个完整的商业操作系统才几百kb。当时的三大操作系统(MS-DOS、Amiga、Unix)均在500kb以下。
由于动态语言的语法简洁,可以有效节省磁盘空间,因此在那个储存空间非常紧张,计算机还十分“脑残”的年代,非常有优势,处于统治地位。
但从windows95诞生,计算机进入图形化时代,程序就开始变得越来越庞大。商业软件从平均几十KB,增大到几MB,几十MB,甚至几百MB。计算机成为独立学科,职业程序员大量出现。“微机时代”宣告结束,“IT时代”到来。
从此,动态语言越来越难以编写出合格的程序。硬盘普及,磁盘空间不再紧张。智能IDE出现之后,静态语言开始全面崛起,终结了动态语言的统治地位。
动态语言和静态语言最大的区别,在于可读性、可维护性的不同。
举例一
小学生刚刚学习写作文的时候,总有很多字不会写。有的老师会让学生,把不会写的字,画成一个圈儿,即O。
一个句子,原本应该写成写成“今天下雨了”。而有些小学生不会写“雨”字。就可以写成“今天下O了”。这个“O”可以代表任何东西,当然也包括雨。
对于判作业的老师来说,这个“O”就是动态的。直到老师猜出这个“O”是雨之后,才能确定这个句子是不是病句。
这种画圈儿的规则,是一把双刃剑,整体讲是弊大于利的。好处是可以让学生只掌握很少的汉字,就能开始学习写作文。但缺点是圈儿一旦变多,就会失控。常常连作者自己都分不清,每个圈儿分别代表啥?写的时候很容易,可第二天连自己都看不懂。
而对于高年级的学生,就不允许使用“O”了。遇到不会写的字,就要去查字典,只有写出所有的字,才能把作文写完。对于判作业的老师来说,这就是静态的,有没有病句,一眼便知。虽然写出作文的门槛提高了,但表述更加清晰,无论任何时间翻出来,都能一目了然。
编程语言比我们的例子要复杂,但道理是一样的,区别就是它不能只画“O”,而是不同的东西,需要用不同的“名字”表示,为了便于说明,下面的“名字”都使用一个字母来命名。
比如一个句子是“板凳宽,扁担长,板凳不让扁担绑在板凳上”。
用动态语言表示,则写成“A宽,B长,A不让B绑在A上”。
写起来很省事,但读起来就费劲了。因为A和B可以代表任何东西,凭什么一定就是“板凳宽,扁担长”,而不是“肥皂宽,牙刷长”?
而用静态语言表示,则是“板凳A宽,扁担B长,A不让B绑在A上”。
通过对比发现,静态语言比动态语言,多了一开始的“板凳”和“扁担”这两个词语。相当于从一开始,就标明了A是板凳,B是扁担。虽然要多写四个字,但可以避免歧义,增强可读性。
只要用脑子记住“A是板凳,B是扁担”,岂不就能达到同样的效果?仅仅记住两个“名字”,当然毫无难度。可是随着程序越来越大,要记的“名字”越来越多,二十个、两百个、两千个,脑子就炸了。
于是静态语言便崛起了,最初就是为了让IDE来“记名字”。
当你写下“板凳A宽”的时候,IDE就偷偷记下一条信息:“A是个板凳”。
等下次调用的时候,鼠标放在A上,IDE就告诉你:“它是一个板凳”。
嗯嗯,一点也不神奇。。。
可如果换成动态语言,IDE就不会给你提示。因为从IDE的角度来看,A并不是板凳,而是一个“O”。
为了解决这个问题,就需要加注释,来提醒自己。可这样做也是不靠谱的。因为如果对代码进行封装,所需要注释的文字量,就会超过代码量本身,到时候你根本不是“写代码加注释”,而是“写注释加代码”。
总之,动态语言只适合写非常非常小的程序,中型以上的程序,通常要使用静态语言编写,才会比较容易维护。我个人只在编写1000行以内的小工具时,才会使用动态语言,如Python、Lua等。但即便如此,还是常常一不小心,就陷入“第二天看不懂”的窘境。
当然,“不适合”并不代表“绝对不能”,就像“徒手搬砖只适用于小型建筑,大中型建筑要使用工程机械”,这说法我一般认为是正确的。但总有一些人会举极端的例子来反驳,说万里长城和金字塔是用手磊出来的,这就实在没意思了。。。
动态语言存在的的第二个问题,就是容易产生BUG,并且很难在第一时间发现。
举例二
假如我们遇到一个游戏,它是用静态语言编写的,其中有一段代码是这样的(伪代码):
角色 A=李逍遥;
怪物 B=树妖;
技能 C=御剑术;
武器 D=钢剑;
然后我们编写了一段代码:“A装备着D,发动了C,击败了B”
这段代码很容易翻译,就是“李逍遥装备着钢剑,发动了御剑术,击败了树妖”。
假如我们一时不小心,把代码写成“李逍遥装备着树妖,发动了钢剑,击败了御剑术”的话,会怎么样?
这时候IDE会立刻报错,并提示有三个错误:
1,树妖是怪物,不能装备
2,钢剑是武器,不能当做技能使用
3,御剑术是技能,无法被击败
所以你只好先排除这三个问题之后,再继续写代码。套用前面的例子,也就是高年级学生“查字典”了。
由于绝大多数的问题,都必须在写代码的过程中,通过“查字典”排除掉,所以只要你的程序可以顺利写完,运行起来也基本不会有太大的问题了。
但如果这个程序是使用动态语言编写的,则不会报错。既然B可以是任何东西,那凭什么必须是钢剑,而不能是树妖?这完全符合动态语言的语法规则,IDE当然不会报错。
直到你的程序写完,BUG一堆一堆的冒出来,IDE却始终认为你的代码完全正确。
所以使用动态语言,有很多错误,IDE是不会帮你检查的。你就要在每一个可能出错的地方,加上注释,提醒自己A是啥东西,B又是啥东西。。。。。最后你会发现,若要保证你自己写的程序不出BUG,而且日后还可以正常维护的话,那么你需要写的注释,比代码本身还多。
写着写着,你就不像在编程了,而像在写一本说明书。