人们对"脚本语言"有很多误解。我自己也用了十几年的各种脚本语言,现在终于可以谈谈我对它们的理解。其实"脚本语言"本来是跟"编程语言"完全对等的概念,它们之间并没有明确的界限。只是因为历史原因,一些语言被称为"脚本语言",而另一些被称为"编程语言"。
最早的"脚本语言"出现在 1960 年代,叫做 "job control language"(JCL)。它不是用来写程序的,而是用来"控制"程序如何运行的。Unix 系统里的 shell 脚本,Windows 下的批处理文件,都是这一类语言。它们的用途是告诉操作系统如何运行其它程序,如何连接它们的输入输出,如何根据运行结果做出判断。因为它们是用来"导演"其它程序的运行的,就像戏剧的"脚本"一样,所以叫做"脚本语言"。
后来人们发现这些脚本语言也可以用来直接写程序,于是它们的功能越来越强大。Unix 的 shell 脚本可以调用各种系统命令,也可以定义函数,进行条件判断和循环。Windows 的批处理文件也可以做类似的事情。再后来,人们专门为写程序而设计了脚本语言,比如 Perl, Python, Ruby 等。它们继承了 shell 脚本的很多特性,比如解释执行,语法灵活,开发效率高等。
现在问题来了。既然脚本语言也可以写程序,那么它跟传统的编程语言(比如 C, C++, Java)有什么区别呢?其实没有本质的区别。脚本语言和编程语言的界限已经非常模糊了。Python 可以写大型的软件系统,C 也可以写脚本来控制程序的运行。人们仍然称 Python, Ruby 为"脚本语言",主要是因为历史原因,以及它们解释执行的特性。
有些人认为脚本语言"不够强大",不能写"大型"程序,这是完全错误的。我曾经用 Python 写过超过十万行的大型系统,其模块化和可维护性不亚于 Java 程序。有些人认为脚本语言"效率低",这也是不准确的。脚本语言的执行效率确实通常低于编译语言,但开发效率往往更高。在很多情况下,开发效率比执行效率更重要。
脚本语言最大的优势在于它们的灵活性和开发效率。它们的语法通常比较简单,不需要声明变量类型,有丰富的内置数据结构(比如 list, dict),可以直接操作字符串和文件。这些特性使得它们特别适合于快速开发,原型验证,系统管理等任务。
现在的趋势是,很多传统的"编程语言"也在吸收"脚本语言"的特性。比如 Java 有 auto boxing/unboxing,C++ 有 auto 关键字,它们都在试图减少类型声明的负担。C# 和 Scala 等语言甚至内置了类似脚本语言的数据结构。可见脚本语言的简洁和高效,是编程语言发展的重要方向。
所以不要再把"脚本语言"看成是"二等公民"了。它们不但能够写出强大的程序,而且在很多方面比传统编程语言更适合现代软件开发的需求。