在学术CS界,“未打字”是否还意味着“动态打字”?


166

我正在读一张幻灯片,上面写着“未键入JavaScript”。这与我认为是正确的相矛盾,因此我开始努力尝试以了解更多信息。

JavaScript的所有答案都是非类型化语言吗?他说JavaScript 并不是没有类型的,而是提供了我熟悉和满意的各种形式的静态,动态,强和弱类型的示例,所以这不是走的路。

因此,我问了JavaScript的创建者Brendan Eich,他说:

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

以学术为重点的计算机科学人员是否使用“未类型化”作为“动态类型化”的同义词(这是否有效?),或者还有更深层的我想念的东西吗?我同意布伦丹(Brendan)的观点,即上下文很重要,但任何引用的解释都将是非常有用的,因为我目前的“继续阅读”书籍都没有在这个主题上发挥作用。

我想详细说明这一点,以便提高我的理解力,因为即使Wikipedia也没有提及这种替代用法(无论如何我还是可以找到)。如果我弄错了,我不想在将来混用该术语或质疑该术语的使用:-)

(我也看过一个顶级Smalltalker,说Smalltalk也是“未键入的”,所以它不是一次性的,这使我着手完成此任务!:-))


5
其他人对术语的误用不必改变您的习惯-只需使用(更多)正确的短语即可。显然,您必须注意阅读的问题。
拉斐尔2012年

2
我一直认为变量是无类型的,因为任何变量都可以保存任何类型的数据。变量中的类型可以动态更改。
Izkata 2012年


1
同样(相对于计算机语言,更多地谈论自然语言)“ untyped” =“ single-typed”(所有值都使用一种类型)。
philipxy

Answers:


148

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

“动态类型”一词的发明很晚-面对“类型”一词的常见数学用法,这在术语上是矛盾的。

例如,这是本杰明·皮尔斯在其标准教科书“ 类型和编程语言 ”中使用的“类型系统”的定义:

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

他还说:

有时会明确地添加“静态”一词(例如,我们称为“静态类型的编程语言”),以区分我们正在考虑的编译时分析类型与诸如以下语言中的动态或潜在类型方案(Sussman和Steele,1975; Kelsey,Clinger和Rees,1998; Dybvig,1996),其中使用运行时类型标记来区分堆中的不同类型的结构。诸如“动态类型化”之类的术语可以说是错误的,应该用“动态检验”代替,但是用法是标准的。

在该领域工作的大多数人似乎都在分享这种观点。

请注意,这并不能意味着“类型化”和“动态类型”是同义词。相反,对于前者的特定情况,后者是一个(技术上令人误解的)名称。

PS:FWIW,我碰巧既是类型系统方面的学者,也是JavaScript的非学术实现者,所以我必须忍受这种分裂。:)


5
非常有益的,甚至有可能在提供一些历史给它的条款我最喜欢的答案。
彼得·库珀

2
@PeterCooper顺便说一句,您可能想知道形式语义的一个主要分支是基于键入的lambda calculi的谓词(ha pun)。例如Montague语义学。但是,作为一个声明性的,非生成性的系统,我个人总是将诸如Montague Semantics之类的系统中的键入与编程语言中的键入分隔开来。
Knowtheory 2012年

+1。"[dynamically typed] is a (technically misleading) name for a particular case of [untyped]"
史蒂夫

1
关于“类型”的历史,这不是很正确。它们甚至比丘奇在lambda微积分上的工作还要古老。罗素在集合论的建构中使用类型来避免悖论。
Sam Tobin-Hochstadt

1
@ SamTobin-Hochstadt,是的,是的。我只谈到了历史中与PL基础直接相关的部分。我会澄清。
Andreas Rossberg 2013年

68

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

鲍勃·哈珀(Bob Harper)喜欢说诸如Scheme,Javascript之类的语言应被视为只有一种类型:值的类型化语言。我倾向于这种观点,因为仅使用一种类型形式主义就可以构建一致的世界观。

PS在纯lambda演算中,唯一的“值”是标准形式的项,而唯一的闭合形式的正规项是函数。但是大多数使用lambda演算的科学家都会添加基本类型和常量,然后要么为lambda包括静态类型系统,要么就回到动态类型标签。

PPS原始海报:当涉及到编程语言,特别是类型系统时,Wikipedia上的信息质量很差。不要相信


12
我认为CS(包括学术界)存在一个更广泛的问题,即名称使用时没有严格的定义。这与数学和(大多数)科学形成了鲜明的对比。缺乏适当的定义似乎引起了大量争议(例如,有关OOP的争议)。很烦人。
康拉德·鲁道夫

2
@KonradRudolph:我想知道,不是因为缺乏适当的定义而引起的纠纷,而是由于缺乏适当的定义而不是由于缺乏适当的定义而引起的纠纷?一些术语获得情感上的效价(正面或负面),然后特定语言的支持者以包括或排除其语言(并排除或包括其喜欢的“敌人”语言)的方式定义这些术语。举一个数学示例-如果仍然有人支持朴素集合论而不是公理集合论,那么您可以确定他们会称自己的观点为“公理集合论”并定义为“朴素
ruakh 2012年

4
@Norman,我很惊讶您将其称为滥用-如您所知,类型的概念比所谓的动态类型语言早了几十年,而后者所谓的“类型”与前者几乎没有关系。因此,我认为可以公平地说,滥用是另一回事。
Andreas Rossberg'2

5
@Norman:当涉及到编程语言,特别是类型系统时,如果您认为Wikipedia上的信息质量很差,请不要任其改善。(只是拖钓)
Gyom

3
当我意识到Wikipedian的过程奖励变革而不是专业知识时,@ Gyom就放弃了改进Wikipedia的那一天。我的时间最好花在改善SO上:-)
Norman Ramsey 2012年

43

我调查了一下,发现您的问题的答案简单而令人惊讶地是“是”:学术CS类型或至少其中一些确实使用“未键入”来表示“动态键入”。例如,《编程语言:原理和实践》第三版(由Kenneth C. Louden和Kenneth A. Lambert于2012年出版)说:

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

[ 链接 ](请注意:原始字体为粗体),并以此方式继续使用“未键入”字样。

我发现这令人惊讶(出于与afrischke和Adam Mihalcin相同的原因),但是您就在那里。:-)


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

[…]这是许多未键入语言的主要信息隐藏机制。例如,PLT方案[4]使用生成structs,[…]

—雅各布·马修斯和阿马尔·艾哈迈德,2008 [ 链接 ]

[…],我们提出了对无类型功能语言[…]的绑定时间分析。[…]它已经实现,并用于Scheme的无副作用方言的部分评估程序中。但是,该分析足够全面,对于非严格类型的功能语言(例如Haskell)有效。[…]

-查尔斯·康塞尔(Charles Consel),1990年[ 链接 ]

顺便说一句,在浏览这些搜索结果后,我的印象是,如果研究人员写出“无类型的”功能语言,他很可能会认为它与无类型的lambda一样具有“无类型”的含义。亚当·米哈尔辛(Adam Mihalcin)提到的微积分。至少,一些研究人员在同一口气中提到了Scheme和lambda演算。

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

然后,我意识到实际上并没有循环性,因为动态类型化的语言不是非类型化的语言-只是类型通常在程序文本中通常不是立即显而易见的。

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

但是很明显,大多数拒绝这种身份的人并不需要明确声明。


2
哇。令人震惊 谢谢(你的)信息。
2012年

正是我想要的那种引用,谢谢!Kinda吓我一跳,尽管该书在亚马逊上获得了平均2星的好评,但受到了更多的引用,但这是一个很好的开始。
彼得·库珀

@PeterCooper:我已经编辑了答案以添加更多引用。他们通过发表论文来规避亚马逊评级问题:据我所知,它们仍然可能是垃圾,但至少我们不必担心亚马逊这样告诉我们。:-P
ruakh 2012年

将“未类型化”与“动态类型化”混为一谈是不合逻辑的。开发人员不应不合逻辑。
rotman '02

10

未类型化和动态类型化绝对不是同义词。最常被称为“非类型化”的语言是Lambda演算,它实际上是一种统一语言-一切都是函数,因此我们可以静态证明一切类型都是函数。动态类型的语言具有多种类型,但是并没有为编译器添加一种静态检查它们的方法,从而迫使编译器对变量类型插入运行时检查。

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


AFAIK相同的问题也适用于Lambda表达式。虽然您可以将“我的当前位置”功能传递给计算“我到目标的距离”的功能,但也可以将相同的“我的当前位置”功能传递给计算“泡芙加维克斯效果更好”的功能为你的鼻子”。仅仅因为您不能说它是有效的-就像任何动态系统一样。
2012年

5
@Steve垃圾回收对于任何编程语言都是如此,并且与类型的概念无关。即使使用OCaml或SML之类的强类型语言,我也可以将北极传递给一个计算“我与目标的距离”的函数(不,我的当前位置不是北极)。
亚当·米哈尔辛

只是想补充一下,对于学术界以外的人:诸如汇编之类的东西也算作无类型的。
CoffeeTableEspresso

6

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

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

相反,在其他语言(如C)中,变量带有类型,而值没有。在Java之类的语言中,变量和值都带有类型。在C ++中,某些值(带有虚函数的值)带有类型,而另一些则没有。在某些语言中,值甚至有可能更改类型,尽管通常认为这是错误的设计。


5
我认为关键的区别不是值和变量之间,而是值和表达式之间:在静态类型的语言中,表达式具有类型,而在动态类型的语言中,仅值具有类型。(变量名当然是一种表达方式。)
ruakh 2012年

4

这个问题全与语义有关

如果我给你这些数据:12它是什么类型?您无法确定。可以是整数-可以是浮点数-可以是字符串。从这个意义上讲,它是非常“无类型”的数据。

如果我给您一种虚构的语言,让您在此数据和某些其他任意数据上使用“加”,“减”和“连接”之类的运算符,则“类型”在某种程度上与我的虚构语言无关(例如:也许add(12, a)产量10912加的ASCII值a)。

让我们再谈C。C几乎可以让您对任意数据执行任何操作。如果您使用的函数需要两个uints-您可以强制转换并传递您想要的任何东西-值将简单地解释为uints。从这个意义上讲,C是“无类型的”(如果您以这种方式对待它)。

但是-直达Brendan的要点-如果我告诉您“我的年龄是12-”,则12有一个类型-至少我们知道它是数字。在上下文中,所有内容都有一种类型-与语言无关。

这就是为什么我一开始说的原因-您的问题是语义学之一。untyped是什么意思?我认为布伦丹说“没有静态类型”时就打在了头上-因为这可能意味着全部。人类自然将事物分类。我们从直觉上知道,汽车和猴子之间根本就存在区别-从来没有被教导要做出这些区别。

首先回到我的示例-一种“不关心类型”(每秒)的语言,可以让您“添加”“年龄”和“名称”而不会产生语法错误...但是并不意味着这是合乎逻辑的操作。

JavaScript可以让您做各种疯狂的事情,而无需考虑它们是“错误”。这并不意味着您在做的事在逻辑上是合理的。这就是开发人员要解决的问题。

在编译/构建/解释时不强制类型安全的系统/语言是否为“未键入”或“动态键入”?

语义学。

编辑

我想在这里添加一些内容,因为有些人似乎被“是的,但是Javascript确实有一些”类型”。

在评论别人的回答时,我说:

在Javascript中,我可以将某些对象构建为“猴子”,而将某些对象构建为“人类”,并且可以将某些功能设计为仅对“人类”进行操作,而其他功能则只能对“猴子”进行操作,并且还有其他人只谈“有武器的事情”。无论是否有人告诉过该语言,是否存在诸如“带手臂的东西”这样的对象类别与汇编(“无类型”)与Javascript(“动态”)都没有关系。这全都是逻辑完整性的问题-唯一的错误是使用了没有该方法的武器。

因此,如果您认为Javascript在内部具有某种“类型”概念,因此也具有“动态类型”,并且认为这在某种程度上“与无类型系统不同”,您应该从上面的示例中看到,任何“在内部具有“类型”确实无关紧要。

为了使用C#执行相同的操作,例如,我需要一个称为ICreatureWithArms或类似名称的接口。在Javascript中不是-在C或ASM中不是。

显然,Javascript是否对“类型”有任何了解都是无关紧要的。


4
-1。该问题询问是否在特定圈子中使用了具有特定含义的特定单词,您的回答是要解释这是一个单词是否具有该含义的问题?确实,我认为您在完成OP似乎已经知道的所有事情的过程中做得很出色,却没有添加任何新内容。。。
ruakh

似乎有几个问题需要建立一个定义,也许?类型强制(静态或动态)类型和已定义类型的存在。因此,JavaScript具有类型,但是由于在执行操作之前缺少检查类型有效性的原因而被视为“未类型化”?
彼得·库珀

@ruakh-我能理解您的观点。但是,OP问:is there something deeper to this that I am missing而且,我认为,未能理解这是一个语义问题是更深层次的事情-因此,我尽我所能尽力而为。
2012年

@PeterCooper-查看我的编辑,并告诉我是否为您添加了任何内容(因为您JavaScript has types在回复中说了)。
2012年

2
“显然,Javascript是否完全对“类型”没有任何了解。” 不对。正如我在回答中所暗示的那样,无论上下文如何,您都不能将12视为函数。由于JavaScript确实具有函数类型(或者,根据您的观点,为多种函数类型),所以这是一个重要的区别。
亚当·米哈尔辛

4

的确,大多数写类型的CS研究人员基本上只将语法上可衍生的类型的语言视为类型化语言,但我们当中有更多人使用动态/潜在类型化语言对此表示怀疑。

我认为有3种语言[SIC]:

无类型-仅由操作员确定值的解释-并且它通常可用于任何内容。示例:汇编程序,BCPL

静态类型-表达式/变量具有与之关联的类型,并且该类型确定了编译时运算符的解释/有效性。示例:C,Java,C ++,ML,Haskell

动态类型-值具有与之关联的类型,该类型确定运行时运算符的解释/有效性。示例:LISP,Scheme,Smalltalk,Ruby,Python,Javascript

就我所知,所有动态类型化的语言都是类型安全的,即只有有效的运算符才能对值进行操作。但是对于静态类型的语言却不是这样。根据所用类型系统的功能,某些操作员可能仅在运行时检查,或根本不检查。例如,大多数静态类型语言不能正确处理整数溢出(添加2个正整数可以产生一个负整数),并且完全不检查(C,C ++)或仅在以下位置检查越界数组引用运行。此外,某些类型系统太弱了,以至于有用的编程都需要使用转义填充(C和Family中的转换)来更改表达式的编译时类型。

所有这些都导致荒谬的说法,例如C ++比Python更安全,因为它是(静态类型的),而事实是Python本质上是安全的,而您可以用C ++击退。


已投票。很高兴知道“所有动态类型的语言都是类型安全的”。“但是对于静态类型的语言却并非如此”,您是说所有或大多数静态类型的语言都是类型不安全的吗?
蒂姆(Tim)

已投票。(1)很高兴知道“所有动态类型的语言都是类型安全的”,但是Javascript是动态类型的而弱类型的,请参阅stackoverflow.com/questions/964910/…。(2)“但是对于静态类型的语言并非如此”,您是说所有或大多数静态类型的语言都是类型不安全的吗?
蒂姆(Tim)

如果您将强制转换失败,下标越界或空指针异常作为类型包括在内,则很少有语言是静态类型安全的(大多数人的确将强制转换失败作为类型错误)。例如,Rust在静态类型上比Java更安全,因为您不能具有空指针。Java是动态类型安全的,因为您会获得任何非法操作的异常,并且所有内容都已指定(本机方法除外)。同样,Rust(如此指定的“不安全”代码除外)。
戴夫·梅森

然而,C ++,C甚至没有动态类型安全的,因为有语言的“未指定”的部分,如果你这样做了“不确定”的操作之一,从字面上看东西是从语言中的合法反应无关的变量(值可能变化,病毒可能会感染您的程序,程序可能会在磁盘上进行写操作,然后崩溃,程序甚至可能会执行您期望的操作:-)。
戴夫·梅森

@DaveMason:未定义。在C语言中,“未指定”和“未定义”之间存在巨大差异。未定义行为基本上是违法的事情,可以做您所描述的---而未指定本质上是指“实现定义的地方,实现不必记录它”(到处都有一些细微差别,因此这一种简化)。因此,调用未指定的行为是完全合法的(实际上,只要有人写一个函数调用,这样做就可以了)。
TimČas17年

2

我不是计算机科学家,但是如果CS社区中(至少在科学出版物中)“ untyped”真正被用作“动态类型”的同义词,我会感到非常惊讶,因为这两个术语描述了不同的概念。动态类型语言具有类型概念,并且在运行时会强制执行类型约束(例如,您不能在Lisp中将整数除以字符串而不会出现错误),而无类型语言在此处则没有任何类型概念全部(例如,汇编器)。即使是有关编程语言的Wikipedia文章(http://en.m.wikipedia.org/wiki/Programming_language#Typed_versus_untyped_languages)也会有这种区别。

更新:可能造成混淆的原因是某些文本在Javascript中说了一些“未键入变量”的说法(这是对的)。但这并不意味着该语言是无类型的(这将是错误的)。


1
汇编程序确实有一些非常弱的类型概念。至少在x86中,所有内容都是整数,但是某些整数的大小彼此不同。这甚至还没有进入MMX,x87和其他原始x86规范的扩展之前。
亚当·米哈尔辛

我不同意。在Javascript中,我可以将某些对象构建为“猴子”,而将某些对象构建为“人类”,并且可以将某些功能设计为仅对“人类”进行操作,而其他功能则只能对“猴子”进行操作,并且还有其他人只谈“有武器的事情”。无论是否有人告诉过该语言,是否存在诸如“带手臂的东西”这样的对象类别与汇编(“无类型”)与Javascript(“动态”)都没有关系。这全都是逻辑完整性的问题-唯一的错误是使用了没有这种方法的武器。
2012年

@Adam Mihalcin正确。[宏]汇编语言当然也可以在不同程度上具有某种类型的概念。(例如,查看“类型化汇编语言”。)我仍然认为我的观点成立。
afrischke'2

3
@Steve我不确定是否可以关注您。OP询问在CS圈子中是否对“动态类型”和“未类型”进行区分。这与您是否认为Javascript与汇编语言如何对待内存中的位实际上没有区别无关。根据我所读的内容(由于我不是Java语言程序员,因此我必须专门进行查找):ECMAScript / Javascript标准定义了6种数据类型(布尔,字符串,未定义,数字,空值和对象),并且可以随时定义在时间上,值是一种具体类型...
afrischke 2012年

1
...现在这是(大多数)汇编语言所没有的概念(全部都有位和字节),所以恕我直言,这标志着Javascript与汇编之间的明显区别。
afrischke'2

1

同意布伦丹-环境就是一切。

我的看法:

我记得大约在2004年感到困惑,因为有人争论Ruby是未类型化还是动态类型。老派的C / C ++人(我是其中的一员)在考虑编译器,并说Ruby没有类型。

请记住,在C语言中,没有运行时类型,只有地址,并且如果正在执行的代码决定将该地址中的内容视为不存在,那么,哎呀。这绝对是没有类型的,与动态类型有很大的不同。

在那个世界里,“打字”完全是关于编译器的。C ++具有“强类型”功能,因为编译器的检查更加严格。Java和C的类型更“弱”(甚至有人争论Java是强类型还是弱类型)。在这种情况下,动态语言是“无类型的”,因为它们没有编译器类型检查。

如今,对于熟练的程序员来说,我们已经习惯了动态语言,显然我们认为未类型化意味着没有编译器或解释器类型检查,这将难以调试。但是有一段时期并不明显,在CS的更理论的世界中,它甚至可能没有意义。

从某种意义上说,什么都不能被取消类型化(或者几乎什么也不能被取消),因为您必须有某种意图来操纵值来编写有意义的算法。这是理论CS的世界,没有涉及如何针对给定语言实现编译器或解释器的细节。因此,“未类型化”在这种情况下(可能我不知道)完全没有意义。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.