【问题标题】:Intepreters and static type checking解释器和静态类型检查
【发布时间】:2016-09-08 09:29:35
【问题描述】:

看完这篇文章后:

How does an interpreter/compiler work

我有这个问题:

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

【问题讨论】:

  • 根据定义,“解释器”不是指“无类型”吗?
  • 这取决于您对“静态类型”的定义。如果您的意思是“在编译时已知”,那么不,仅解释语言不能仅仅因为没有“编译时”步骤而具有静态类型的变量。如果您的意思是“变量被锁定为一种类型”,那么是的,解释语言可以具有静态类型的变量。我已经看到了这两个定义,这就是我提出它的原因。通常该术语指的是第一个定义。
  • 但是整个问题是模糊的,因为许多解释语言也有编译步骤,它只是发生在运行时。因此,您要问的情况应该明确说明,否则唯一可以给出的答案是“视情况而定”。
  • @Lasse V. Karlsen,我的意思是“在编译时知道”,感谢您的回答,我只是想确定我是否认为这是正确的谢谢!!!!
  • 举个例子:Haskell 是众所周知的静态类型 PL。您可以通过解释器 runhaskell hello.hs 运行 Haskell 程序。 Haskell 确实首先检查类型——编译时间就在运行时间之前。

标签: types programming-languages interpreter static-typing


【解决方案1】:

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

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

那么根据这个定义,静态类型语言可以使用解释器来实现吗?当然。只需让解释器在程序开始执行任何操作之前发现程序中的类型错误(使用编译器将使用的相同算法),瞧,您就有了静态类型检查。

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


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

【讨论】:

    【解决方案2】:

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

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

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

    Foo foo = new Foo();
    
    let foo = new Foo();
    

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

    话虽如此,在严重依赖运行时信息的无注释语言中,在某些情况下,不可能知道变量在运行时之前的类型。在这种情况下,静态类型分析器或编译器无法提前提供帮助,也无法在编译时捕获由不兼容类型导致的错误。例如,TypeScript 是针对 Javascript 的静态类型的附加解决方案,它走这条线。您在 TypeScript 中注释的所有内容都经过严格的类型检查;您所做的任何注释或留下any 都无法进行类型检查,并且可能在运行时在你的脸上炸毁。

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

    【讨论】:

    • deceze,我同意一种语言的特性取决于语言的设计过程,但我不能检查我认为类型检查是独立的类型(如你还提到)从语言中,我认为我们不能只用解释器静态检查类型??
    • 我不确定我是否理解您的要求,但是……如果您为变量分配一个数字,很明显该变量将保存一个数字类型的值。如果然后代码继续只对该值进行数字运算,那么很容易跟踪该值将继续是一个数字。这就是静态分析器可以做的非常好的事情。在代码中存在分析器无法提前推断类型的情况,例如foo = rand(0, 1) ? 42 : 'bar'。在这种情况下,它可以发出关于类型安全的警告,或者放弃可预测性功能。
    猜你喜欢
    • 2021-11-25
    • 2014-05-18
    • 2021-02-28
    • 2015-04-05
    • 1970-01-01
    • 2019-07-11
    • 2018-06-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多