在学术 CS 世界中,“无类型”是否也意味着“动态类型”?

IT技术 javascript types computer-science typing
2021-03-14 11:01:41

我正在阅读一张幻灯片,上面写着“JavaScript 是无类型的”。这与我认为的事实相矛盾,因此我开始挖掘以尝试了解更多信息。

每一个答案是JavaScript的一个类型化的语言?说 JavaScript不是无类型的,并提供了我熟悉和满意的各种形式的静态、动态、强类型和弱类型的示例......所以这不是要走的路。

所以我问了 JavaScript 的创造者 Brendan Eich,他说:

学术类型使用“无类型”来表示“没有静态类型”。他们足够聪明,可以看到值具有类型(废话!)。上下文很重要。

以学术为重点的计算机科学人员是否使用“无类型”作为“动态类型”的同义词(这是否有效?)还是我缺少更深层次的东西?我同意 Brendan 的观点,上下文很重要,但任何对解释的引用都会很好,因为我目前的“去”书籍并没有在这个主题上打球。

我想确定这一点,这样我就可以提高我的理解,因为即使维基百科也没有提到这种替代用法(无论如何我都能找到)。如果我错了,我不想弄乱使用该术语或质疑该术语的使用:-)

(我还看到一位顶级 Smalltalker 说 Smalltalk 也是“无类型”的,所以这不是一次性的,这让我开始了这个任务!:-))

6个回答

是的,这是学术文献中的标准做法。要理解它,了解“类型”的概念是在 1930 年代在 lambda 演算的背景下(实际上,甚至更早,在集合论的背景下)被发明的会有所帮助。从那时起,出现了一个被称为“类型理论”的计算逻辑的整个分支。编程语言理论就是建立在这些基础之上的。在所有这些数学上下文中,“类型”具有特定的、公认的含义。

术语“动态类型”是后来发明的——在“类型”这个词的常见数学用法面前,它是一个矛盾的术语。

例如,这里是 Benjamin Pierce 在他的标准教科书Types and Programming Languages 中使用的“类型系统”的定义

类型系统是一种易于处理的句法方法,用于通过根据短语计算的值的类型对短语进行分类来证明不存在某些程序行为。

他还指出:

有时会明确添加“静态”一词——例如,我们说的是“静态类型的编程语言”——以将我们在这里考虑的编译时分析的种类与在语言中发现的动态或潜在类型区分开来,例如Scheme(Sussman 和 Steele,1975 年;Kelsey、Clinger 和 Rees,1998 年;Dybvig,1996 年),其中运行时类型标签用于区分堆中的不同类型的结构。像“动态类型”这样的术语可以说是用词不当,应该用“动态检查”代替,但用法是标准的。

大多数在该领域工作的人似乎都同意这一观点。

请注意,这并不能意味着“类型化”和“动态类型”是同义词。相反,后者是前者特定情况的(技术上具有误导性的)名称。

PS:还有 FWIW,我碰巧既是类型系统的学术研究员,又是 JavaScript 的非学术实现者,所以我不得不忍受这种分裂。:)

非常有益的,甚至有可能在提供一些历史给它的条款我最喜欢的答案。
2021-04-24 11:01:41
@SamTobin-Hochstadt,是的,对。我只谈了直接关系到 PL 基础的那部分历史。我会澄清的。
2021-04-28 11:01:41
关于“类型”的历史,这并不完全正确。它们甚至比丘奇在 lambda 演算方面的工作还要古老。罗素在集合论的构建中使用类型来避免悖论。
2021-05-03 11:01:41
@PeterCooper 顺便说一句,您可能有兴趣知道形式语义的一个主要分支是基于类型化 lambda 演算的谓词(哈双关语);例如蒙太古语义。但作为一个声明性的、非生成系统,我个人总是将像 Montague Semantics 这样的系统中的输入与编程语言中的输入区分开来。
2021-05-11 11:01:41
+1。 "[dynamically typed] is a (technically misleading) name for a particular case of [untyped]"
2021-05-13 11:01:41

我是一名专门研究编程语言的学术计算机科学家,是的,“无类型”一词经常(错误地)以这种方式使用。保留这个词用于不带有动态类型标签的语言,例如 Forth 和汇编代码,会很好,但这些语言很少使用,甚至很少研究,而且说“无类型”要容易得多而不是“动态类型”。

Bob Harper 喜欢说像 Scheme、Javascript 等语言应该被视为只有一个类型:值的类型化语言。我倾向于这种观点,因为它可以仅使用一种形式主义来构建一致的世界观。

PS 在纯 lambda 演算中,唯一的“值”是范式的项,范式中唯一的封闭项是函数。但是大多数使用 lambda 演算的科学家都会添加基本类型和常量,然后你要么为 lambda 包含一个静态类型系统,要么马上回到动态类型标签。

PPS 致原帖:说到编程语言,尤其是类型系统,维基百科上的信息质量很差。不要相信它。

我认为在 CS(包括学术界)中存在一个更广泛的问题,即名称的使用没有严格的定义。这与数学和(大多数?)科学形成鲜明对比。大量的争议(例如关于 OOP)似乎源于缺乏正确的定义。很烦人。
2021-04-24 11:01:41
@Norman:当涉及到编程语言,尤其是类型系统时,如果您觉得 Wikipedia 上的信息质量很差,请不要管它并改进它。(只是拖拉)
2021-04-30 11:01:41
@KonradRudolph:我想知道,不是由于缺乏适当的定义而引起的争议,而是缺乏适当的定义可能部分是由争议引起的。一些术语具有情感value(无论是积极的还是消极的),然后特定语言的支持者以包括或排除他们的语言(并排除或包括他们最喜欢的“敌对”语言)的方式定义这些术语。举个数学例子——如果仍然有人支持朴素集合论而不是公理集合论,你可以肯定他们会称他们自己的观点为“公理集合论”并定义“朴素的集合论”
2021-05-08 11:01:41
@Norman,我很惊讶你称它为滥用——如你所知,类型的概念早于所谓的动态类型语言几十年,而后者所谓的“类型”与前者几乎没有关系。所以我认为可以公平地说滥用是相反的。
2021-05-16 11:01:41
@Gyom 当我意识到维基百科流程奖励变化而不是专业知识的那一天,我放弃了改进维基百科我的时间最好花在改进 SO 上 :-)
2021-05-18 11:01:41

我已经调查过了,发现您的问题的答案很简单,而且令人惊讶的是,“是”:学术 CS 类型,或者至少其中一些,确实使用“无类型”来表示“动态类型”。例如,编程语言:原则和实践,第三版(Kenneth C. Louden 和 Kenneth A. Lambert,2012 年出版)说:

没有静态类型系统的语言通常称为无类型语言(或动态类型语言)。此类语言包括 Scheme 和 Lisp 的其他方言、Smalltalk,以及大多数脚本语言,如 Perl、Python 和 Ruby。但是请注意,无类型语言不一定允许程序破坏数据——这只是意味着所有安全检查都在执行时执行。[…]

[链接](注意:原文中加粗)并继续以这种方式使用“untyped”。

我觉得这很令人惊讶(原因与 afrischke 和 Adam Mihalcin 给出的原因大致相同),但您就是这样。:-)


编辑添加:您可以通过插入"untyped languages"Google 图书搜索找到更多示例例如:

[…] 这是许多无类型语言的主要信息隐藏机制。例如 PLT Scheme [4] 使用生成式structs,[…]

— Jacob Matthews 和 Amal Ahmed,2008 年 [链接]

[...],我们提出了一个无类型函数式语言的绑定时间分析 [...]。[…] 它已被实现并用于Scheme 的无副作用方言的部分评估器。然而,该分析足够通用,适用于非严格类型的函数式语言,例如 Haskell。[…]

— 查尔斯康塞尔,1990 [链接]

顺便说一句,在浏览这些搜索结果后,我的印象是,如果研究人员写了一种“无类型”函数式语言,他很可能确实认为它与无类型 lambda 具有相同意义上的“无类型” Adam Mihalcin 提到的微积分。至少,有几位研究人员同时提到了 Scheme 和 lambda 演算。

当然,搜索没有说的是,是否有研究人员拒绝这种识别,并且认为这些语言是“无类型的”。嗯,我确实找到了这个:

然后我意识到真的没有循环性,因为动态类型语言不是无类型语言——只是类型通常不会从程序文本中立即显而易见。

— 某人(我不知道是谁),1998 [链接]

但显然大多数拒绝这种认同的人不会觉得有必要明确说出来。

正是我正在寻找的那种引文,谢谢!这本书在亚马逊上平均有 2 颗星,这让我有点害怕,尽管欢迎更多引用,但这是一个很好的开始。
2021-04-30 11:01:41
@PeterCooper:我编辑了我的答案以添加更多引文。他们通过来自已发表的论文来规避亚马逊评级问题:据我所知,它们仍然可能是垃圾,但至少我们不必担心亚马逊会告诉我们。:-P
2021-05-07 11:01:41
哇。令人震惊。谢谢(你的)信息。
2021-05-15 11:01:41
将“无类型”与“动态类型”混淆是不合逻辑的。开发人员不应该不合逻辑。
2021-05-18 11:01:41

无类型和动态类型绝对不是同义词。最常被称为“无类型”的语言是 Lambda Calculus,它实际上是一种统一语言——一切都是函数,所以我们可以静态地证明一切的类型都是函数。动态类型语言有多种类型,但没有为编译器添加静态检查它们的方法,强制编译器插入对变量类型的运行时检查。

然后,JavaScript 是一种动态类型语言:可以用 JavaScript 编写程序,使得某些变量x可以是数字、函数、字符串或其他东西(并确定哪个需要解决停机问题或某些困难的数学问题),所以你可以应用x一个参数,浏览器必须在运行时检查它x是一个函数。

原始的 lambda 演算是无类型的,因为它的形式没有对类型的引用。可以将系统表述为统一类型,这是一个有效的观点,但原始表述没有提及任何类型。
2021-04-21 11:01:41
@Steve Garbage in Garbage 是任何编程语言的情况,并且与类型的概念无关。即使在像 OCaml 或 SML 这样的强类型语言中,我也可以将北极传递给一个计算“我与目标的距离”的函数(不,我当前的位置不是北极)。
2021-04-27 11:01:41
只是想补充一点,对于学术界以外的人:诸如程序集之类的东西也算作无类型。
2021-05-05 11:01:41
AFAIK 同样的问题适用于 Lambda 表达式。虽然您可以将“我的当前位置”的函数传递到计算“我与目标的距离”的函数中,但您也可以将相同的“我的当前位置”函数传递到计算“是抽吸加上维克斯更好的函数”为了你的鼻子”。仅仅因为你可以并不意味着它是有效的——就像任何动态系统的情况一样。
2021-05-10 11:01:41

这两种说法都是正确的,这取决于您是在谈论值还是变量。JavaScript 变量是无类型的,JavaScript 值有类型,并且变量在运行时可以跨越任何值类型(即“动态”)。

在 JavaScript 和许多其他语言中,值而不是变量带有类型。所有变量都可以覆盖所有类型的值,并且可以被认为是“动态类型化”或“无类型化”——从类型检查的角度来看,一个没有/未知类型的变量和一个可以采用任何类型的变量在逻辑上和实际上是等效的. 当类型理论家谈论语言和类型时,他们通常在谈论这个——携带类型的变量——因为他们对编写类型检查器和编译器等感兴趣,它们对程序文本(即变量)进行操作,而不是在内存中运行的程序(即值)。

相比之下,在其他语言(如 C)中,变量带有类型,但值不带有。在 Java 等语言中,变量和值都带有类型。在 C++ 中,某些值(具有虚函数的值)携带类型而其他值则不携带。在某些语言中,值甚至可以改变类型,尽管这通常被认为是糟糕的设计。

我认为关键的区别不在于值和变量之间,而在于值和表达式之间:在静态类型语言中,表达式具有类型,而在动态类型语言中,只有值具有类型。(当然,变量名是一种表达式。)
2021-04-28 11:01:41