这看起来好像我在自相矛盾。但是C或Java类型检查器所做的是拒绝一个“不合语法”的程序,或者如果它不能成功于2,它就称之为“类型错误”。它不能证明它们不会发生,这并不意味着它们不会发生,它只是意味着它不能证明它。一个没有类型错误的程序很可能会被拒绝,因为它不能被编译器证明。一个简单的例子是if(1) a = 3; else a = "string";,当然,由于它总是为真,else分支永远不会在程序中执行,也不会发生类型错误。但它不能以一般的方式证明这些情况,所以被驳回。这是很多静态类型语言的主要弱点,在保护你不受自己的伤害时,你也必须在你不需要它的情况下受到保护。
为什么他们没有类型?因为每个操作都在每个操作上被定义和允许,那么什么是“运行时类型错误”呢?它来自一个纯粹的理论例子副作用。如果执行打印字符串的print("string")是一个操作,那么length(3)也是一个操作,前者的副作用是将string写入标准输出,后者只是error: function 'length' expects array as argument.,仅此而已。从理论的角度来看,动态类型语言是不存在的。他们是无类型
明显的缺点是,操作可能会产生对人类来说毫无意义的结果。为了防止这种情况,动态类型语言通常会重新定义这些操作,而不是产生那些无意义的结果,而是将其重新定义为具有写出错误的副作用,并可能完全停止程序。这根本不是一个“错误”,事实上,语言规范通常暗示这一点,从理论角度来看,这是语言的行为,就像打印字符串一样。因此,类型系统迫使程序员对代码流进行推理,以确保这种情况不会发生。或者实际上,通过推理使做发生在某些调试点上也很方便,这表明它根本不是一个“错误”,而是语言的一个定义良好的属性。实际上,大多数语言所保留的“动态类型”的唯一残余就是防止除零。这就是动态类型,没有类型,没有比0和其他数字不同的类型。人们所说的“类型”只是数据的另一个属性,就像数组的长度,或者字符串的第一个字符。许多动态类型语言也允许你写出"error: the first character of this string should be a 'z'"这样的东西。
另一件事是,动态类型语言在运行时具有可用的类型,通常可以检查它,处理它,并从中做出决定。当然,从理论上讲,这与访问数组的第一个char并查看它是什么没有什么不同。事实上,你可以创建自己的动态C语言,只使用一种类型,比如long long int,并使用它的前8位来存储你的“类型”,并相应地编写函数来检查它并执行浮点数或整数加法。你有一种静态类型语言和一种动态语言。