相反地,一个语言环境中也可能存在四种与上述约定不相容的情况。
其一,在执行之前存在标识但没有任何已知的值,代码运行时该标识存有绑定任何值的可能,称为动态绑定③。例如下面的代码行在JavaScript中表示环境中有一个标识age,但直到该行代码执行时,age所指示的存储中才会有值20:1 //示例12 var age = 20;与此相对,我们称标识在运行之前就具有了值和类型的情况为静态绑定。例如在Delphi/Pascal中://示例1Var Age: Integer = 20;其二,对于已经(动态或静态)绑定过的标识,如果通过写值的方式能够使之具有新的数据类型含义,我们称为动态重写④。对此前的示例1,我们可以有如下代码:age ="unknown";这会导致age具有新的数据类型,而这在Delphi/Pascal中会被视为违例。
其三,动态绑定或是动态重写导致标识具有不同数据类型含义的情况,称为动态类型。示例1中的age在动态绑定发生之后,JavaScript环境允许使用typeof()取得其类型为Number,但在绑定发生前则是未定义的5。
①与上述“匿名XX”相对应的,我们称之为“具名”。
②注意这里没有强调值与标识的绑定,这是因为存在变量的缘故。对于Erlang这类语言来说,所有“作为系统计算的前设”的值都必须是常量性质的,即:不可写且类型确定。
③动态/静态绑定这个概念被用在很多的地方,我们这里只明确地阐述其中的一种形式。即一个无类型、无值的变量,可以动态绑定一个值来赋予它类型的概念,即后文的动态类型。除此之外,我们并没有讨论在静态语言中存在的一个有类型变量,在执行期进行绑定(赋值)的情况。yipindushu.com
④重写一个具名函数看起来是一个动态特性,但其实它并没有改变标识上的数据类型,所以不作为这里的动态重写来讨论。从另一个角度来说,具名函数的重写与i++的性质是一样的。
⑤ Undefined在JavaScript中也是一个类型,但这是概念完备性的一种表现,并非我们这里讨论的数据结构。
其四,如果允许将(任意或特定数据类型的)数据作为代码片段加以执行,则称为动态执行。例如:eval("dynamic_code_text");当然,这也意味着多数脚本语言具有动态执行的性质,因为它能读取文本文件内容并执行。
对于支持上述(“静态绑定”是显然被排除在外的其他四种性质)四种性质中的一种或多种性质的语言,我们就称为动态语言。
所以我们此前将部分讨论限定在“静态的、编译型”语言之中,实在是有着严苛的条件:既要能直接编译成机器语言,又要能明确有标识和数据类型含义。接下来,我们的讨论则要广泛得多。不过此前讨论的那些性质,在后续讨论中也仍然是合用的——这本来就是我们构划这样一个讨论路径的原因。
【三】
编译过程将代码变为机器指令,这使得代码必然面临机器环境的限制,例如存储的使用与CPU执行权限的交接就是这类语言中主要的两类复杂问题:内存分配和线程调度。解释型语言将程序的入口由CPU指令序列变成代码的自然入口,散列存储使我们避免面临存储地址的限制,这些技术可以让语言从“机器问题”中解放出来。这一结果让我们认识到,机器环境的限制只是语言实现中的负担。
因此,我们的问题得以回到此前的讨论:程序的所有行为无外乎两点,其一找到(包括逻辑在内的)数据;其二计算。亦即是说,在一个解释性的,或不以机器问题为焦点的语言中,"找到(包括逻辑在内的)数据"必然会成为本质、核心和关键的问题。
版权声明
本站素材均来源与互联网和网友投稿,欢迎学习分享
【节数以及对数据的性质的思考22:http://www.yipindushu.com/xuexifangfa/16531.html
推荐文章
09-03
1 哲理语录大全哲理语录09-13
2 【节应用开发的背景与成因1409-03
3 哲理的语录语句09-03
4 精辟哲理句子大全唯美09-13
5 传递正能量:语录大全的温暖力量