compiler-construction - 为什么解释的 langs 大多是ducktyped,而编译有强类型?

标签 compiler-construction programming-languages interpreted-language

我只是不知道,这有什么技术原因吗?为弱类型语言实现编译器是否更困难?它是什么?

最佳答案

问题背后的前提有点狡猾 .解释型语言大多是ducktyped 是不正确的。编译语言大多具有强类型,这是不正确的。 类型系统是语言的属性 . 编译与解释是实现的一个属性。

例子:

  • 编程语言 Scheme 是动态类型的(又名鸭子类型),它有许多解释实现,但也有一些很好的 native 代码编译器,包括 Larceny、Gambit 和 PLT Scheme(其中包括解释器和 JIT 编译器,使无缝过渡)。
  • 编程语言 Haskell 是静态类型的;最著名的两个实现是解释器 HUGS 和编译器 GHC .还有其他几个令人尊敬的实现在编译为 native 代码 (yhc) 和解释 (Helium) 之间平均分配。
  • 编程语言标准 ML 是静态类型的,它有许多 native 代码编译器,其中最好和维护最积极的编译器之一是 MLton ,但最有用的实现之一是解释器莫斯科 ML
  • 编程语言 Objective Caml 是静态类型的。它只有一个实现(来自法国的 INRIA),但是这个实现包括一个解释器和一个本地代码编译器。
  • 编程语言 Pascal 是静态类型的,但由于 UCSD 构建的基于 P 代码解释器的出色实现,它在 1970 年代开始流行。在后来的几年中,出现了精美的 native 代码编译器,例如用于 370 系列计算机的 IBM Pascal/VS 编译器。
  • 编程语言 C 是静态类型的,今天几乎所有的实现都是编译的,但在 1980 年代,我们这些幸运地使用 Sabre C 的人正在使用解释器。

  • 尽管如此 您的问题背后有一些道理 ,所以你应该得到一个更周到的答案。事实是动态类型语言似乎确实与解释实现相关 .为什么会这样?
  • 许多新语言是由实现定义的。构建解释器比构建编译器更容易。动态检查类型比静态检查更容易。如果您正在编写解释器,静态类型检查几乎没有性能优势。
  • 除非您正在创建或改编一个非常灵活的多态类型系统,否则静态类型系统很可能会妨碍程序员。但是,如果您正在编写解释器,一个原因可能是创建一个不受程序员影响的小型轻量级实现。
  • 在某些解释性语言中,许多基本操作都非常昂贵,以至于在运行时检查类型的额外开销并不重要。 一个很好的例子是 PostScript:如果你打算马上跑掉并光栅化 Bezier 曲线,你不会犹豫在这里或那里检查类型标签。

  • 顺便说一下,请警惕术语“强”和“弱”打字 ,因为它们没有普遍认可的技术含义。相比之下,静态类型 表示程序是 执行前检查 ,并且程序可能在启动之前就被拒绝。 动态打字 表示 的类型在执行期间检查值 ,错误类型的操作可能会导致程序停止或以其他方式停止 在运行时发出错误信号 .静态类型的一个主要原因是排除可能具有此类“动态类型错误”的程序。 (这是编写解释器的人通常对静态类型不太感兴趣的另一个原因;在类型检查后立即执行,因此保证的区别和性质并不那么明显。)

    强类型 一般表示有无漏洞在类型系统中,而 弱类型意味着可以破坏类型系统(使任何保证无效)。这些术语经常被错误地用于表示静态和动态类型。
    要查看差异,请考虑 C:该语言在编译时进行类型检查(静态类型),但存在大量漏洞;您几乎可以将任何类型的值转换为相同大小的另一种类型——特别是,您可以自由地转换指针类型。 Pascal 是一种旨在强类型化的语言,但众所周知有一个无法预见的漏洞:没有标签的变体记录。

    随着时间的推移,强类型语言的实现经常会出现漏洞,通常这样一部分运行时系统可以用高级语言实现。例如,Objective Caml 有一个名为 Obj.magic 的函数。它具有简单地返回其参数的运行时效果,但在编译时它将任何类型的值转换为任何其他类型之一。我最喜欢的例子是 Modula-3,它的设计者称他们的类型转换结构 LOOPHOLE .

    总之:
  • 静态 vs 动态是语言 .
  • 编译与解释是实现 .
  • 原则上这两个选择可以并且是正交的 ,但出于合理的技术原因 动态类型经常与解释相关联 .
  • 关于compiler-construction - 为什么解释的 langs 大多是ducktyped,而编译有强类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/376611/

    相关文章:

    ruby - 偏差算法

    c# - Shell 脚本与高级解释语言(C#/Java/等)的性能比较

    programming-languages - 我需要学习什么来构建解释器?

    c++ - gcc的奇怪行为。带有{}和=的C++对象定义是否相等?

    flash - ASC 2.0 是否识别 [Frame] 元数据标签(例如 : for Preloader factoryClass)?

    c - 长正整数和搜索的结果以及数组中的元素

    programming-languages - 保留关键字按编程语言计数?

    ruby-on-rails - Ruby 变量定义

    c++ - 指导编译器如何优化我的代码

    c++ - Error C2084 函数已有主体