Intepreters和静态类型检查

时间:2016-09-08 09:29:35

标签: types programming-languages interpreter static-typing

阅读这篇文章后:

How does an interpreter/compiler work

我有这个问题:

在只有解释器的编程语言中(例如Basic)(如上面链接第二个答案中的照片所示)是否可以进行静态类型检查??。
 据我所知,每次执行程序时,解释器都会运行每个单行命令。那么在运行程序之前怎样才能静态检查类型?

2 个答案:

答案 0 :(得分:1)

语言是一种语言,它既不被解释也不被编译,直到它。意思是,同一种语言可以动态解释它可以被编译成二进制。实际上,解释器会将代码编译成字节代码。

编译语言和解释语言之间的主要区别在于,解释的程序需要单独的运行时,而编译的程序通常可以单独运行,也可以在操作系统的最小引导程序帮助下运行。编译器通常也会在编译步骤上花费更多时间而不是解释器,在解释器中,编译器可以进行更深入的错误检查和代码优化。口译员不这样做只是因为这是一个缓慢的过程,而不是因为它根本不可能。

类型提示/推理是一个完全独立的问题。许多主要编译的语言都广泛使用类型提示,因为编译器有时间使用该信息。主要解释的语言通常会放弃类型提示,因为额外的类型检查会花费时间在运行时,并且该语言的设计目标是一个快速开发周期,其中包括更少的输入。这并不意味着这些语言"免费输入" ,每个值仍然具有类型,并且该类型已知。事实上,即使很多编译语言现在也放弃了显式类型注释,因为它不需要简洁。例如:

Foo foo = new Foo();

let foo = new Foo();

这里的Foo类型提示相当多余;当然编译器可以在这里推断foo类型为Foo,只是查看赋值的右侧。任何其他类型也是如此,包括数字,字符串等。编译器或静态类型分析器可以跟踪分配给变量的值或从函数返回的值,并在没有单个显式注释的情况下推断出很多类型。

话说回来,在严重依赖于运行时信息的未注释语言中,在某些情况下, 可能无法知道变量在运行时的类型。在这种情况下,静态类型分析器或编译器无法提前帮助,并且无法捕获在编译时由不兼容类型导致的错误。例如,TypeScript是一个用于Javascript静态类型的固定解决方案,它可以走这一行。您在TypeScript中进行 注释的所有内容都经过严格的类型检查;你做的任何事情注释或留下any都不能进行类型检查,可能会在运行时爆炸。

以静态类型语言键入系统,动态类型语言用于不同目的(请注意静态动态键入,"编译" vs."解释")。静态类型主要用于在编译时捕获错误,并为编译器提供更多信息以生成更好的代码;动态类型用于定义程序行为,即两种类型的值在操作时应如何表现,包括在不兼容类型上抛出错误。静态分析仪仍然可以预测这种不兼容的类型错误,即使并非在所有情况下也是如此。

答案 1 :(得分:1)

通常说静态类型编程语言是“在编译时”进行类型检查的,因此可能很容易说“解释器没有编译时间 1 因此可以“静态类型”,但真正“静态”并不一定意味着“在编译时”,它意味着“在运行时之前”或“没有运行代码”。

因此,静态类型语言是程序中任何位置的类型错误都会导致程序无法运行的语言。而在动态类型语言中,类型错误只会在控制流到达错误类型语句时中止执行。

所以鉴于这个定义,可以使用解释器实现静态类型语言吗?当然。只需让解释器在程序中找到类型错误(使用编译器将使用的相同算法),然后再开始执行任何操作,并且你有静态类型检查。

您可能不希望这样做的原因是它增加了启动时间,因为它在代码开始执行之前引入了一个额外的步骤。根据类型系统的复杂性,类型检查实际上可能会消耗大量时间。这对于翻译来说可能非常烦人,但这绝对是可能的。

1 但这仅适用于非常简单的解释器。大多数现实世界的解释器涉及一些代码生成,无论是字节码还是JITed机器代码。