这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » 脚本语言:21世纪的高级编程语言(一)

共1条 1/1 1 跳转至

脚本语言:21世纪的高级编程语言(一)

助工
2008-04-12 21:16:39     打赏

Perl和Tcl等脚本语言代表一种与c或JavaTM为代表的系统程序设计语言完全不同的编程形式。脚本语言为"胶着"应用程序而设计,它使用无类型方法来实现高级编程和比系统程序设计语言更快的发展应用。计算机速度的增长和混合应用的改变使脚本语言在今后的应用中越来越重要。

 

1.简介
    在过去的十五年里,人们编写计算机程序的方法发生了根本的转变。这种转变是从c或c++等系统程序设计语言到Perl或Tcl等脚本语言的过渡。虽然很多人参与了转变,却很少有人意识到它的发生,更不用说知道为什么会发生。这篇文章是我关于为什么在下个世纪脚本语言可以比系统程序设计语言更好的处理许多编程工作的一点看法。

   与系统程序设计语言相比,不同的脚本语言为不同的工作而设计,这导致了语言间的根本不同。系统程序设计语言起源于像内存字等最初期的计算机元素,它为建立数据结构和算法而创建。相反的,脚本语言为胶着而设计:他们假设已经存在一套强大的组件,而它主要是把组件连在一起。系统程序设计语言使用强类型定义来帮助处理复杂事务,而脚本语言使用无类型定义来简化组件间的联系,并提供快速应用开发.

    脚本语言和系统程序设计语言互为补充,并且二十世纪六十年代以来的大多数主要的计算机平台都同时提供这两种类型的语言。这些语言在组件框架中有着典型的应用:组件由系统程序设计语言创建,并由脚本语言组合在一起。然而,速度更快的机器,更好的脚本语言,图形用户界面和组件构造重要性的不断提高,因特网的发展等发展趋势大大提高了脚本语言的应用。在今后的十年中,这种趋势将继续,而且越来越多的完全使用脚本语言和系统程序设计语言书写的应用程序将主要用来创建组件。

2.系统程序设计语言
    为了理解脚本语言和系统程序设计语言的不同,最好先了解一下系统程序设计语言是如何发展的.系统程序设计语言是作为除汇编语言外的另一种选择而引入的.在汇编语言里,实际上机器的每一个细节都被反映在程序里.每个状态代表一个简单的机器指令,而程序员必须处理像寄存器分配和程序调用顺序等低层细节.因此,用汇编语言编写和维持大型程序是很困难的.

   二十世纪五十年代后期像Lisp,Fortran和Algol等高层语言开始出现.这些语言里的状态和机器指令不再完全一致,编译程序把过程程序中的每个状态翻译成一系列二进制指令.经过一段时间,一系列系统程序设计语言包括PL/1,Pascal,C,C++和Java由Algol发展而来.系统程序设计语言没有汇编语言的效率高,但他们使应用程序更快的发展起来,因此,系统程序设计语言在大型应用项目的发展中几乎完全取代了汇编语言.

    系统程序设计语言与汇编语言在两个方面有所不同:它是高层语言并且是强类型."高层"意味着很多细节被自动处理以便编程人员可以写更少的代码而做同样的工作.例如:

★编译程序处理寄存器分配,所以编程人员不需要写代码来在寄存器和内存间转移数据
★自动设计程序调用顺序:编程人员不需要担心调用栈之间的参数转移
★编程人员可以使用像while和if等简单的关键字来控制结构,编译器执行所有的指令细节来完成控制结构

    平均每行系统程序设计语言代码翻译成大约五条机器指令,与此相比,每行汇编语言代码翻译成一条机器指令(由5个不同的人写的8个c文件的非正式分析中,我发现这个比率为每行3到7条指令;Capers Jones从大量语言的研究中发现对于一个给定的工作,汇编语言需要的代码长度大约是系统程序设计语言代码长度的3-6倍)不管是什么语言,编程人员每年可以写大体上相同数量的代码行,因此,系统程序设计语言允许用比汇编语言快得多的语言写应用程序.

   汇编语言和系统程序设计语言的第二个不同是类型设置.我使用"类型"来说明信息的意义在它被使用前就被特殊化.在强类型语言中编程人员声明如何使用每条信息,并避免此信息被用于其他方式.在弱类型语言中信息应用是没有优先权限制:信息的意思完全由它的使用方法确定,而不是任何初始约定.

   现代计算机基本上是无类型的:内存中的任何字对任何类型的值比如整型,浮点数,指针或结构体都是有效的.值的意思由它的使用方法确定:如果指向一个内存字,那么他就被认为是结构体;如果一个字涉及一个整型加结构体,那么他就被认为是整型,如此等等.相同的字在不同的时间可用于不同的方法.

  与此相反,现在的系统程序设计语言是强类型定义的.例如:

★系统程序设计语言中的每个变量都必须被声明为整型或指针或字符串等特殊类型,并且必须用于适合这种类型变量的方法
★数据与代码完全分离:创建新的代码很困难或根本不可能.
★变量可以集中在结构体中或者定义好的子结构体和过程或方法的对象中以便于使用;一种类型的对象不能用于期待其他类型对象处.

    确定类型由几个好处.第一,声明变量如何使用使大型程序更易于管理并区分那些必须被分别对待的变量.第二,编译器可以利用类型信息来侦测某些类型的错误,比如,试图把一个浮点值作为一个指针.第三,定义类型能使编译器更好的执行特殊代码.例如,如果编译器知道一个变量总是对整型值有效,那么他就可以产生一个整型指令来操纵这个变量;如果编译器不知道变量的类型,那么他就必须产生额外的指令在运行时检查变量类型.

    总之,系统程序设计语言被设计来处理与汇编语言相同的工作,即随机地产生请求.系统程序设计语言比汇编语言层次更高,类型更强.这就使请求产生更迅速并且处理更容易,除了在运行时有一点损失,图示1是汇编语言和其他几种系统程序设计语言的比较.


3.脚本语言
    脚本语言,像Perl,Python,Rexx,Tcl,Visual Basic和Unix shells代表了与系统程序设计语言完全不同的编程.脚本语言假设已经存在了一系列由其他语言写成的有用的组件.脚本语言不希望随机地产生请求,他希望主要是把组件接在一起.例如,Tcl和Visual Basic可以被用于在屏幕上安排一系列用户图形控制,而Unix shells scripts被用于把过滤程序集合入管道.脚本语言常用于扩展组件特性,但他们很少用于复杂的算法和数据结构;这些东西常由组件提供.脚本语言有时涉及胶着语言或系统整体语言.

    为了简化连接组件的工作,脚本语言被设计为无类型的:所有的东西无论是看起来还是使用起来都是完全一样的,因此他们可以互换.例如,在Tcl或Visual Basic中一个变量可以一会儿处理字符串,一会儿又处理整型.代码和数据也常可互换,因此,可以用一个程序写另一个程序,然后高速执行,脚本语言一般是面向字符的,因为它为许多不同的事物提供了一致的描述.

    无类型语言使组件更容易连在一起.在使用时没有优先级限制,并且所有的组件及其值都用统一的方式描述.除此之外,任何组件和值都可以在任何情况下使用;为某一目的而设计的组件可以被用于设计者完全没有预见过的完全不同的目的.例如,在Unix shells中,所有的过滤程序从输入读入字节流,并把字节组成的字符串写入输出;任何两个程序都可以通过把一个的输出连到另一个的输入而把两者联系起来.

   下面的shell命令把三个过滤堆在一起来计算选中区域中包含单词"scripting" 的行数:

select | grep scripting | wc

    select程序读入当前显示选中的文本并把它输出;grep程序读取输入并把包含"scripting"的行输出;wc程序对输入的行数求和.其中的每个 程序都可以用于许多其他情况来做不同的工作.

     系统程序设计语言的强类型本质上阻止重用.类型鼓励编程人员创建包含不相容接口的类型("接口很好,接口越多越好").每个接口需要特别类型的对象,而编译器不允许接口使用任何其他类型的对象,即使那样有用.为了使用一个已经存在的接口的新的对象,就必须写转换代码以便在对象的类型和接口期望的类型间进行翻译.这反过来又需要重编译部分或全部分布式二进制形式的应用程序,在普通情况下这是不可能的.

     为了能看出无类型语言的优点,考虑下面的Tcl命令:

button .b -text Hello! -font {Times 16} -command {puts hello}

     这个命令创建了一个新的按钮来显示16点Times字体,当用户敲击控制键时显示一段小的信息.它把六种不同的类型混合成一个单一的状态:一个命令名(button),一个按钮控制(.b),所有权名字(-text, -font, 和-command),简单字符串(Hello! 和hello),包含铅字名(Times)及字点大小(16)的字体名(Times 16)和Tcl脚本(puts hello).Tcl代表所有这些非正式字符串.在这个例子中可以在任何一个命令中为属性赋值,而未赋值的属性使用给定的缺省值.在这个例子中20个以上的属性是不特别赋值的.

    同样的例子在Java中用两种方法执行时需要7行代码.使用C++和微软基本类(MFC)需要三个过程25行代码,在微软基本类中仅仅设置字体就需要几行代码:

CFont *fontPtr = new CFont();
fontPtr->CreateFont(16, 0, 0,0,700, 0, 0, 0, ANSI_CHARSET,
OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
DEFAULT_PITCH|FF_DONTCARE, "Times New Roman");
buttonPtr->SetFont(fontPtr);

    大部分代码是由强类型造成的.为了设置按钮字体,必须运用SetFont方法,但这个方法必须通过指针传给CFont对象,这反过来需要声明和初始化一个新的对象.为了初始化CFont对象必须唤醒它的CreateFont 方法,但CreateFont有一个需要14个特殊化引数的固定接口.在Tcl中字体(Times铅字,16点)的基本特征不用声明或转换就可以立即使用.另外,Tcl允许在创建按钮的命令中直接包含按钮行为,而C++和Java中需要把它放在单独声明的方法中.

    (实际上可以用隐藏基本语言的复杂性的图形开发环境处理一个像这样的不重要的例子:用户在表中输入合适的值,而开发环境输出代码.然而,在更多复杂情况像按计划产生合适值或接口的条件任务中开发人员必须在基本语言下编写代码)
这可能看起来脚本语言的无类型特性不能发现错误,但实际上脚本语言和系统程序设计语言一样安全.例如在上面的按钮例子中如果字体大小被置成非整型字符串,就像xyz,那么就会出现错误.不同的是当一个值被使用时脚本语言在最后一刻进行错误检查,而强类型在编译时发现错误这就避免了运行时的检查.然而提高效率的代价是限制信息如何使用:这导致了更多的代码和更不易改变的程序.

    脚本语言和系统程序设计语言的另一个重要不同是脚本语言是被解释而系统程序设计语言是被编译.被解释的语言由于没有编译时间而提供快速的转换.通过允许用户运行时编写应用程序,解释器使.应用程序更加灵活,例如,许多整体线路的综合分析工具,包括Tcl解释器;程序用户编写Tcl 脚本来使他们的设计具体化并控制工具操作.通过快速设计代码解释器可以实现强大的功能.例如,一个基于Tcl的网页浏览器可以通过把网页中的HTML转换为使用一些常规表达替代物的Tcl脚本,从而从语法上分析网页然后执行脚本把页面翻译显示在屏幕上.

   脚本语言不如系统程序设计语言效率高,部分是因为他们使用解释器而不是编译器,而且因为他们基本组件的选择标准是功能强大和易于使用而不是有效地对应基本硬件.例如,脚本语言经常使用长度可变的字符串,而同样的情况下系统程序设计语言使用对应一个机器字的二进制值;脚本语言经常使用哈希表,而系统程序设计语言使用变址阵列.

    幸运的是,脚本语言的性能不经常是一个主要的问题.脚本语言应用程序通常比系统程序设计语言的应用程序要小,并且脚本应用程序的执行受组件执行的支配,而这些组件是系统程序设计语言提供的典型工具.

    脚本语言比系统程序设计语言更高级,平均一个指令可以做更多的工作.一个典型的脚本语言指令执行成百上千条机器指令,而一个典型的系统程序设计语言指令执行大约五条机器指令(参图一).部分不同是因为脚本语言使用翻译器,这不如系统程序设计语言中被编译的代码.但是主要的不同是因为脚本语言的初期操作有更强大的功能.例如,Perl中唤醒一个常规表达替代和唤醒一个整型加法一样简单.在Tcl中,变量会有与它相联系的图标,因此,设置变量会导致侧面影响.例如,一个图标可能会被用于保持变量的值在屏幕上持续更新.

 

表1.表的每行描述了被执行了两遍的应用程序,一遍使用系统程序设计语言,像C或Java,一遍使用脚本语言,像Tcl.代码率列给出了两个应用程序的代码行率(>1意味着系统编程语言需要更多的代码),作用率列给出了开发率.在大多数情况下两个版本由不同的开发者执行.表中的信息由comp.lang.tcl新闻组中对文章进行答复的不同人提供。.

    由于上面描述的特性,脚本语言允许基于胶着的应用程序的快速发展.表1提供了有趣的支持.它描述了几个在系统程序设计语言下执行后又在脚本语言中重新执行的应用程序,或反过来也是一样的.

   在每种情况下脚本版本都比系统编程版本需要更少的代码和更短的开发时间,不同点的变化从2到60.脚本语言第一次执行时好处不显著,这使人联想到任何在第一次执行经验上的重执行都会更好,而脚本和系统编程的真正不同相差5到10倍,而不是表中的极端点.脚本的好处同样依赖于应用程序.在表中的最后一个例子中,应用程序的图形用户界面部分是基于胶着的,而模拟装置部分却不是;这可能解释为什么脚本应用程序不如其他应用程序获益多.

    总之,脚本语言被设计成胶着应用程序,他们提供比汇编或系统程序设计语言更高层的编程,比系统程序设计语言更弱的类型,和解译后的开发环境.脚本语言牺牲执行速度来提高开发速度.

4.不同的任务,不同的工具
    脚本语言不是系统程序设计语言的替代品,反过来也一样.他们各自适合不同类型的工作.把胶着和系统合为一体,应用程序可以比脚本语言快5-10倍;系统程序设计语言将需要大量复本和转换代码来连接各块.而这直接使用脚本语言.对于复杂的算法和数据结构,系统程序设计语言的强类型使程序更易于管理.执行速度是关键.系统程序设计语言可以比脚本语言运行快10-20倍,因为它产生更少的运行时检查.

    在决定是否使用脚本语言或系统程序设计语言处理一项特殊任务时考虑以下问题:

★应用程序的主要工作是否是把已经存在的组件联系起来
★应用程序是否要操纵不同种类类型的事物
★应用程序是否包含图形用户界面
★应用程序是否做大量字符串操作
★应用程序函数是否能快速解决问题
★应用程序是否需要可扩展

  如果这些问题回答"是"就表明这个应用程序使用脚本语言会更好.另一方面,如果对下面的问题回答"是"就表明系统程序设计语言更适合这个应用程序:

★应用程序是否执行复杂的算法或数据结构
★应用程序是否操纵大量数据集(像图像中的所有像素)因而执行速度很重要
★应用程序的函数是否已经定义好,并且很少改动

  在过去的30年中,大多数主要的计算机平台同时提供系统编程和脚本语言。例如,第一个脚本语言虽然粗糙,却是一个JCL(作业控制语言),它被用于在OS/360中把工作等级按顺序排好。个别工作等级由PL1,Fortran或汇编语言书写,那时是系统程序设计语言。在二十世纪八十年代时Unix机器上,c被用于系统编程而sh,csh等壳编程被用于脚本。在二十世纪九十年代的PC时代里,c和c++被用于系统编程e而Visual Basic用于脚本。在现在已基本成形的网络时代中,Java被用于系统编程而像JavaScript , Perl和Tcl等语言被用于脚本。

  脚本和系统编程是共生的,共同使用,他们能产生格外强大的编程环境:系统程序设计语言用于产生令人兴奋的组件,然后用脚本语言把他们组装起来。例如,Visual Basic的主要吸引力是系统编程者可以用c编写ActiveX组件,而不太老练的编程者可以在Visual Basic应用中使用这些组件。在Unix下编写用于唤醒用c编写的应用程序的壳脚本很容易。Tcl普及的一个原因是可以编写执行新命令的c代码来扩展该语言的能力。




关键词: 脚本     语言     21世纪     高级     编程语言     系统     程序设    

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]