我对类型系统的理解是否正确?

Mic*_*rdt 16 language-agnostic type-systems

以下陈述代表了我对类型系统的理解(它在Java世界之外的实践经验太少); 请更正任何错误.

静态/动态区别似乎非常明确:

  • 静态类型语言为每个变量,字段和参数分配一个类型,编译器会阻止不兼容类型之间的分配.示例:C,Java,Pascal.
  • 动态类型语言将变量视为可以保存任何所需内容的通用容器 - 只有在您对值实际执行操作时才会在运行时检查类型(如果有的话),而不是在分配它们时.示例:Smalltalk,Python,JavaScript.
  • 类型推断允许静态类型语言看起来像(并具有一些优点)动态类型语言,通过从上下文推断类型,这样您就不必在大多数时间声明它们 - 但与动态语言不同,不能例如最初使用变量来保存字符串然后为其分配一个整数.示例:Haskell,Scala

我不太确定强弱差别,我怀疑它的定义不是很明确:

  • 强类型语言为每个运行时值分配一个类型,并且只允许执行为该类型定义的操作,否则会出现显式类型错误.
  • 弱类型语言没有运行时类型检查 - 如果您尝试对不支持的值执行操作,则结果是不可预测的.它实际上可能会做一些有用的事情,但更有可能你会得到损坏的数据,崩溃或一些难以理解的二次错误.
  • 似乎至少有两种不同类型的弱类型语言(或者可能是连续统一体):
    • 在C和汇编程序中,值基本上是比特桶,因此任何事情都是可能的,如果你让编译器解除引用以空字符结尾的字符串的前4个字节,你最好希望它引导一个不包含合法机器代码的地方.
    • PHP和JavaScript通常也被认为是弱类型的,但不要将值视为不透明的位桶; 但是,它们将执行隐式类型转换.
  • 但是这些隐式转换似乎主要适用于字符串/整数/浮点变量 - 这是否真的能保证分类为弱类型?或者还有其他问题,这些语言的类型系统可能会混淆错误?

Jör*_*tag 17

我不太确定强弱区别,我怀疑它的定义不是很明确.

你是对的:事实并非如此.

这就是类型和编程语言以及高级类型和编程语言的作者Benjamin C. Pierce 所说的:

我花了几个星期......试图理清" 强类型 "," 静态类型 "," 安全 "等术语,并发现它非常困难....这些术语的用法如此多样化使他们几乎无用.

Luca Cardelli在他的Typeful Programming文章中将其定义为缺少未经检查的运行时类型错误.托尼霍尔称同样的财产"安全".其他论文称之为"类型安全"或简称为"安全".

几年前,Mark-Jason Dominus 在comp.lang.perl.moderated新闻组中写了一篇经典的咆哮,讨论了Perl是否是强类型的.在这种咆哮中,他指出,在短短几个小时的研究中,他能够找到8种不同的,有时相互矛盾的定义,主要来自大学教科书或同行评审论文等受人尊敬的来源.特别是,那些文本包含的示例旨在帮助学生区分强类型和弱类型语言,并且根据这些示例,C是强类型的,C是弱类型的,C++是强类型的,C++是弱类型的,Lisp是强类型,Lisp是弱类型的,Perl是强类型的,Perl是弱类型的.(这会清除任何混淆吗?)

我一直看到的唯一定义是:

  • 强类型:我的编程语言
  • 弱类型:你的编程语言

  • 它实际上不是我的,但我不记得我在哪里看到它,即使我可以,它也不是最初的来源.让我们把它归结为民间传说. (2认同)

Nor*_*sey 5

关于静态和动态类型,你已经花了不少钱。静态类型意味着程序在执行之前会被检查,并且程序可能会在启动之前被拒绝。动态类型意味着在执行期间检查值的类型,类型错误的操作可能会导致程序停止或在运行时发出错误信号。静态类型的主要原因是排除可能存在此类“动态类型错误”的程序。

Bob Harper认为动态类型语言可以(并且应该)被视为具有单一类型的静态类型语言,Bob 称之为“值”。这种观点是公平的,但它只在有限的上下文中有用,例如试图精确地了解语言的类型论。

尽管我认为您掌握了这个概念,但您的项目符号并没有明确说明类型推断只是静态类型的一个特例。在大多数具有类型推断的语言中,类型注释是可选的,但不一定在所有上下文中都是如此。(例如:ML 中的签名。)高级静态类型系统通常会在注释和推理之间进行权衡;例如,在 Haskell 中,您可以键入更高级别的多态函数(全部位于箭头左侧),但只能带有注释。因此,如果您愿意添加注释,则可以让编译器接受没有注释就会被拒绝的程序。我认为这是类型推断的未来浪潮。

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

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

我鼓励您避免使用关于类型系统的术语“强”和“弱”,而是准确地说出您的意思,例如,“类型系统保证在运行时不会发生以下类别的错误”(强) 、“静态类型系统不能防止某些运行时错误”(弱)或“类型系统有漏洞”(弱)。仅仅将类型系统本身称为“强”或“弱”并不能很好地传达信息。