编译执行和编程语言

问题描述:

我看着this post关于静态和动态类型语言和评论之间的差异的动态输入系统,指出从this reference采取了如下定义:编译执行和编程语言

静态类型是非常频繁误解为意味着这些值与CompileTime中的类型相关联,相反,它意味着ReferenceValue与它可以表示的值的类型相比受到明显限制(与CompileTime不同),并且语言实现,无论是编译器还是解释器,都强制使用t尽可能限制这些限制。

如果我没有错,这个定义指出是否静态类型不依赖于(或不是)编译的语言实现。

但是用这种方式说,静态类型系统有一个解释实现的优点是什么?我的意思是,检查总是在运行时进行。

+0

在实际执行任何代码之前,它仍然会发现错误。 – melpomene

+0

您的意思是在开始执行第一行代码之前,整个类型检查已完成?这不是与执行并行吗? – zer0uno

+0

在重读你的报价时,我不明白它想说什么。我最好的猜测是,这是完全错误的。 – melpomene

您的问题有几个方面。

首先我要说的是静态类型代码与解释的动态运行时间的组合是最常见的,作为对现有动态语言的补充解决方案。 JavaScript,Python和Racket/Scheme/Lisp都具有静态类型检查*的变体。所有这些仍然使用原始语言的运行时(s)。静态类型检查为程序员提供了值,即使运行时引擎没有实际使用静态类型信息。

第二个方面是我认为你引用的定义可能涉及的内容。尽管一些静态语言在编译时丢弃了类型信息,并且只是为了使代码不必检查类型,但其他人(例如Java和C#)也会为运行时保留类型信息以供使用。什么使得静态类型检查是静态的,因为它可以在不执行代码的情况下完成。运行时可能会进行额外的检查(例如导致Java中出现ClassCastException的那种检查),但这是动态类型检查(根据来自静态类型代码的信息完成的)。

至于为静态类型语言实际创建解释实现的好处:编译器很难。并不像以前那样艰难(例如,随着LLVM的兴起),但仍比原型解释的运行时更难。如果您正在尝试使用高级类型的系统,那么解释第一个实现可能会更容易。如果它是静态类型检查,那么你将有一个单独的类型检查阶段而不执行代码。这可能会使运行时不必担心在实际执行代码期间检查类型。

*:TypeScript,Flow,mypyTyped Racket提到一些。


编辑:在评论中提到的示例。新泽西州的标准ML(SML/NJ)是静态类型语言Standard ML的解释器。采取以下非常简单的程序:

val _ = print "hello\n"; 
val foo : string = 4; 

在SML/NJ每个语句是类型检查,然后在现有类型环境单独评估,在移动到下一个语句之前。因此,所有代码在执行前都要进行类型检查,但上述程序在失败之前仍然会打印出问候语。但是下面的程序不会打印任何东西:

val foo : int = print "hello\n"; 

它不会打印你好,然后尝试存储nil到foo。在此之前,在单独的类型检查阶段它失败了。

+0

因此,据我了解,即使有解释器,对所有源代码进行整体类型检查? – zer0uno

+0

如果它是静态类型*检查*,那么是的,但我可以想象一种静态类型的语言,但只有在运行时检查类型(但我不知道任何示例)。但是,即使在静态类型检查的情况下,也存在边界模糊的边界。我会在答案中加入一个例子,因为这个评论越来越长。 –