为什么解释langs大多是ducktyped而编译有强类型? [英] Why interpreted langs are mostly ducktyped while compiled have strong typing?

查看:404
本文介绍了为什么解释langs大多是ducktyped而编译有强类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是不知道,有什么技术原因吗?对于弱类型的语言,实现一个编译器更困难吗?是什么?

解决方案

问题背后的前提有点诡异。这不是真的,解释的语言大多是ducktyped。编译语言大多数都有强类型,这不是真的。 类型系统是语言的属性编译与解释是实现的属性。



示例:




  • 编程语言Scheme是动态类型的(也叫做鸭类型),它有许多解释的实现,但也有一些优秀的本地代码编译器,包括Larceny, Gambit和PLT Scheme(其中包括解释器和JIT编译器进行无缝转换)。


  • Haskell的编程语言静态类型;两个最着名的实现是解释器HUGS和编译器 GHC


  • 编程语言标准ML是静态类型的,并且它有许多本地代码编译器,其中最好的和最积极维护之一是 MLton ,但是最有用的实现之一是解释器莫斯科ML


  • 编程语言Objective Caml是静态类型。它只有一个实现(来自法国的INRIA),但是这个实现包括解释器和本地代码编译器。


  • 编程语言Pascal是静态类型的,但是它在20世纪70年代变得流行,因为在UCSD中构建的优秀实现基于P代码解释器。在以后的几年中,精简的本地代码编译器变得可用,例如用于370系列计算机的IBM Pascal / VS编译器。


  • 编程语言C是静态类型,今天几乎所有的实现都编译,但在20世纪80年代,我们幸运地使用Sabre C正在使用解释器。




不过,你的问题背后有一些事实,所以你应该得到一个更周到的答案。事实是动态类型语言似乎与解释的实现相关。为什么会是这样?




  • 许多新语言由实现定义。构建解释器比构建编译器更容易。与静态检查类型相比,动态检查类型更容易。如果你正在编写一个解释器,对静态类型检查几乎没有什么性能优势。


  • 除非您正在创建或修改非常灵活的多态类型系统,否则静态类型系统很可能会遇到程序员的方式。


  • 在某些解释语言中,如果你正在编写一个解释器, 许多基本操作是如此昂贵,以至于在运行时检查类型的额外开销并不重要。一个很好的例子是PostScript:如果你要跑掉并在Bezier曲线




顺便说一下,警告强和弱打字这两个术语,因为它们没有通用的技术含义。相比之下,静态类型意味着程序在执行之前被检查,并且程序可能会在开始之前被拒绝。 动态键入表示执行期间选中 类型,而键入错误的操作可能导致程序停止或以其他方式在运行时发出错误。静态打字的主要原因是排除可能有这种动态类型错误的程序。 (这是另一个原因,即编写解释器的人通常对静态类型感兴趣;执行类型检查后立即执行,因此保证的区别和性质不是那么明显。)



强类型通常表示类型系统中存在无漏洞,而弱类型表示类型系统可以被转义(使任何担保无效)。这些术语常常不正确地用于表示静态和动态类型。
为了看到差别,想想C:语言是在编译时进行类型检查(静态类型),但有很多漏洞;你几乎可以将任何类型的值转换为相同大小的另一种类型 - 特别是,你可以自由地投射指针类型。 Pascal是一种强烈打字的语言,但是有一个不可预见的漏洞:一个没有标签的变体记录。



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



/ p>


  • 静态与动态是语言 / li>

  • 编译与解释是实现


  • p>原则上两个选项可以正交,,但由于正确的技术原因动态类型常常与解释相关。



I just don't know that, is there any technical reason for that? Is it more difficult to implement a compiler for a language with weak typing? What is it?

解决方案

The premises behind the question are a bit dodgy. It is not true that interpreted languages are mostly ducktyped. It is not true that compiled languages mostly have strong typing. The type system is a property of a language. Compiled versus interpreted is a property of an implementation.

Examples:

  • The programming language Scheme is dynamically typed (aka duck-typed), and it has many dozens of interpreted implementations, but also some fine native-code compilers including Larceny, Gambit, and PLT Scheme (which includes both an interpreter and a JIT compiler making seamless transitions).

  • The programming language Haskell is statically typed; the two most famous implementations are the interpreter HUGS and the compiler GHC. There are several other honorable implementations split about evenly between compiling to native code (yhc) and interpretation (Helium).

  • The programming language Standard ML is statically typed, and it has had many native-code compilers, of which one of the best and most actively maintained is MLton, but one of the most useful implementations is the interpreter Moscow ML

  • The programming language Objective Caml is statically typed. It comes with only one implementation (from INRIA in France) but this implementation includes both an interpreter and a native-code compiler.

  • The programming language Pascal is statically typed, but it became popular in the 1970s because of the excellent implementation built at UCSD, which was based on a P-code interpreter. In later years fine native-code compilers became available, such as the IBM Pascal/VS compiler for the 370 series of computers.

  • The programming language C is statically typed, and today almost all implementations are compiled, but in the 1980s those of us lucky enough to be using Saber C were using an interpreter.

Nevertheless there is some truth behind your question, so you deserve a more thoughtful answer. The truth is that dynamically typed languages do seem to be correlated with interpreted implementations. Why might that be?

  • Many new languages are defined by an implementation. It is easier to build an interpreter than to build a compiler. It is easier to check types dynamically than to check them statically. And if you are writing an interpreter, there is little performance benefit to static type-checking.

  • Unless you are creating or adapting a very flexible polymorphic type system, a static type system is likely to get in the programmer's way. But if you are writing an interpreter, one reason may be to create a small, lightweight implementation that stays out of the programmer's way.

  • In some interpreted languages, many fundamental operations are so expensive that the additional overhead of checking types at run time doesn't matter. A good example is PostScript: if you're going to run off and rasterize Bezier curves at the drop of a hat, you won't balk at checking a type tag here or there.

Incidentally, please be wary of the terms "strong" and "weak" typing, because they don't have a universally agreed technical meaning. By contrast, static typing means that programs are checked before being executed, and a program might be rejected before it starts. Dynamic typing means that the types of values are checked during execution, and a poorly typed operation might cause the program to halt or otherwise signal an error at run time. A primary reason for static typing is to rule out programs that might have such "dynamic type errors". (This is another reason people who write interpreters are often less interested in static typing; execution happens immediately after type checking, so the distinction and the nature of the guarantee aren't as obvious.)

Strong typing generally means that there are no loopholes in the type system, whereas weak typing means the type system can be subverted (invalidating any guarantees). The terms are often used incorrectly to mean static and dynamic typing. To see the difference, think of C: the language is type-checked at compile time (static typing), but there are plenty of loopholes; you can pretty much cast a value of any type to another type of the same size---in particular, you can cast pointer types freely. Pascal was a language that was intended to be strongly typed but famously had an unforeseen loophole: a variant record with no tag.

Implementations of strongly typed languages often acquire loopholes over time, usually so that part of the run-time system can be implemented in the high-level language. For example, Objective Caml has a function called Obj.magic which has the run-time effect of simply returning its argument, but at compile time it converts a value of any type to one of any other type. My favorite example is Modula-3, whose designers called their type-casting construct LOOPHOLE.

In summary:

  • Static vs dynamic is the language.

  • Compiled vs interpreted is the implementation.

  • In principle the two choices can be and are made orthogonally, but for sound technical reasons dynamic typing frequently correlates with interpretation.

这篇关于为什么解释langs大多是ducktyped而编译有强类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆