【问题标题】:Compiled implementation and dynamically typing system of a programming language一种编程语言的编译实现和动态类型系统
【发布时间】:2016-11-19 20:43:11
【问题描述】:

我正在查看 this post 关于静态类型语言和动态类型语言之间的差异的评论,并指出了从 this reference 中获取的以下定义:

静态类型经常被误解为表示值与 CompileTime 的类型相关联,而这意味着 ReferenceValue 明显(与 CompileTime 不同)相对于它的值的类型受到限制可以表示,并且语言实现,无论是编译器还是解释器,都尽可能地强制和使用这些约束。

如果我没记错的话,这个定义表明是否静态类型并不取决于是否有(或没有)该语言的编译实现。

但是这样说,使用静态类型系统的解释实现有什么好处?我的意思是,检查总是在运行时进行。

【问题讨论】:

  • 它仍然会在实际执行任何代码之前发现错误。
  • 你的意思是在开始执行第一行代码之前完成了整个类型检查吗?不是和执行并行吗?
  • 重读您的报价时,我不明白它在说什么。我最好的猜测是它完全是错误的。

标签: typing dynamic-typing static-typing


【解决方案1】:

您的问题有几个方面。

首先我要说的是,静态类型代码与解释的动态运行时的组合是最常见的,作为现有动态语言的补充解决方案。 JavaScript、Python 和 Racket/Scheme/Lisp 都有带有静态类型检查的变体*。尽管如此,所有这些仍然使用原始语言的运行时。静态类型检查即使静态类型信息并未被运行时引擎实际使用,也会为程序员提供价值。

第二个方面是我认为你引用的定义可能指的。虽然一些静态语言在编译时会丢弃类型信息,并使用它只是为了使代码不必检查类型,但 Java 和 C# 等其他语言也会保留类型信息以供运行时使用。使静态类型检查成为静态的原因在于它可以在不执行代码的情况下完成。可以在运行时进行额外的检查(例如在 Java 中导致 ClassCastException 的检查),但这就是动态类型检查(根据来自静态类型代码的信息完成)。

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

*:TypeScriptFlowmypyTyped Racket 等等。


编辑:评论中提到的示例。 Standard ML of New Jersey(SML/NJ) 是静态类型语言 Standard ML 的解释器。采取以下非常简单的程序:

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

在 SML/NJ 中,每个语句都经过类型检查,然后在现有类型环境中单独评估,然后再转到下一个语句。因此,所有代码在执行之前都会进行类型检查,但上述程序在失败之前仍会打印 hello。但是,以下程序不会打印任何内容:

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

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

【讨论】:

  • 那么,据我所知,即使有解释器,也会对所有源代码进行完整的类型检查?
  • 如果它是静态类型的checked,那么是的,但我可以想象一种静态类型的语言,但只在运行时进行类型检查(但我不知道任何例子)。然而,即使在静态类型检查的情况下,也有一些边缘情况会模糊边界。我将在答案中添加一个示例,因为此评论越来越长。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-18
  • 2013-04-03
  • 2012-09-17
  • 1970-01-01
  • 1970-01-01
  • 2020-02-16
  • 2011-04-08
相关资源
最近更新 更多