Does “untyped” also mean “dynamically typed” in the academic CS world?
我正在读一个幻灯片,上面写着"javascript是非类型化的"。这与我认为的是真的相矛盾,所以我开始钻研,试图了解更多。
每个答案都是javascript是一种非类型化语言?说javascript不是非类型化的,它提供了各种形式的静态、动态、强和弱类型的例子,我对此很熟悉,也很满意。所以不是这样的。
所以我问了javascript的创建者brendan eich,他说:
academic types use"untyped" to mean"no static types". they are smart enough to see that values have types (duh!). context matters.
以学术为中心的计算机科学工作者是否使用"非类型化"作为"动态类型化"的同义词(这是否有效?)还是有什么更深层的东西让我错过了?我同意布伦丹的观点,即上下文是重要的,但任何解释的引证都是很好的,因为我目前的"去"书没有在这个问题上发挥作用。
我想把它写下来,这样我就可以提高我的理解力,因为即使是维基百科也没有提到这种替代用法(我无论如何都能找到)。如果我错了,我不想再乱用这个词了,也不想在将来质疑这个词的用法。
(我也看到过一个顶尖的小说家说,小说家也是"非类型化的",所以这不是一个一次性的,这是我开始这个任务的原因!-)
是的,这是学术文献中的标准做法。为了理解它,有助于了解"类型"的概念是在20世纪30年代,在lambda微积分的背景下发明的(事实上,甚至更早的时候,在集合论的背景下)。从那时起,计算逻辑的一个分支出现了,被称为"类型理论"。编程语言理论是建立在这些基础之上的。在所有这些数学环境中,"类型"有一个特定的、确定的含义。
"动态打字"这个术语是后来发明的——在面对"打字"这个词在数学上的常见用法时,这是一个矛盾。
例如,以下是本杰明·皮尔斯在其标准课本类型和编程语言中使用的"类型系统"的定义:
A type system is a tractable syntactic method for proving the absence
of certain program behaviors by classifying phrases according to the
kinds of values they compute.
他还表示:
The word"static" is sometimes added explicitly--we speak of a
"statically typed programming language," for example--to distinguish the
sorts of compile-time analyses we are considering here from the
dynamic or latent typing found in languages such as Scheme (Sussman
and Steele, 1975; Kelsey, Clinger, and Rees, 1998; Dybvig, 1996),
where run-time type tags are used to distinguish di?erent kinds of
structures in the heap. Terms like"dynamically typed" are arguably
misnomers and should probably be replaced by"dynamically checked,"
but the usage is standard.
在这个领域工作的大多数人似乎都认同这一观点。
注意,这并不意味着"非类型化"和"动态类型化"是同义词。相反,后者对于前者的特定情况是一个(技术上具有误导性的)名称。
附:还有fwiw,我恰好是类型系统的学术研究者,也是javascript的非学术实现者,所以我必须忍受这种分裂。:)
我是一个专门研究编程语言的学术计算机科学家,是的,单词"untyped"经常(mis)这样使用。最好保留这个词用于不带动态类型标记的语言,如forth和汇编代码,但是这些语言很少使用,甚至很少研究,而且说"未类型化"比说"动态类型化"要容易得多。
BobHarper喜欢说,像Scheme、javascript等语言应该被认为是只有一种类型的类型化语言:value。我倾向于这种观点,因为它可以用一种形式主义来构建一致的世界观。
在纯lambda微积分中,唯一的"值"是正规形式的项,而正规形式中唯一的闭项是函数。但是大多数使用lambda演算的科学家会添加基类型和常量,然后您要么为lambda包含静态类型系统,要么直接返回动态类型标记。
原版海报:说到编程语言,尤其是打字系统,维基百科上的信息质量很差。不要相信。
我已经研究过了,发现你的问题的答案很简单,而且令人惊讶的是,"是的":学术CS类型,或者至少其中一些,确实使用"非类型化"来表示"动态类型化"。例如,《编程语言:原则与实践》,第三版(作者:Kenneth C.Louden和Kenneth A.Lambert,2012年出版)指出:
Languages without static type systems are usually called untyped languages (or dynamically typed languages). Such languages include Scheme and other dialects of Lisp, Smalltalk, and most scripting languages such as Perl, Python, and Ruby. Note, however, that an untyped language does not necessarily allow programs to corrupt data—this just means that all safety checking is performed at execution time. […]
[链接](注意:在原文中加粗),然后用这种方式继续使用"untyped"。
我觉得这很令人惊讶(与阿非schke和亚当·米哈尔辛给出的理由大致相同),但你在这里。-)
编辑添加:你可以通过把
[…] This is the primary information-hiding mechanism is many untyped languages. For instance PLT Scheme [4] uses generative
struct s, […]
—Jacob Matthews和Amal Ahmed,2008年[链接]
[…], we present a binding-time analysis for an untyped functional language […]. […] It has been implemented and is used in a partial evaluator for a side-effect free dialect of Scheme. The analysis is general enough, however, to be valid for non-strict typed functional languages such as Haskell. […]
—Charles Consel,1990年[链接]
顺便说一下,我的印象是,在浏览了这些搜索结果之后,如果一个研究人员写了一种"非类型化"的功能语言,他很可能会认为它是"非类型化"的,就像亚当·米哈尔辛提到的非类型化lambda微积分一样。至少,一些研究人员同时提到了方案和lambda微积分。
当然,搜索并没有说明,是否有研究人员拒绝接受这种识别,并且不认为这些语言是"非类型化的"。嗯,我确实发现了:
I then realized that there is really no circularity, because dynamically typed languages are not untyped languages — it's just that the types are not usually immediately obvious from the program text.
—某人(我不知道是谁),1998年[链接]
但很明显,大多数拒绝这种身份证明的人不会觉得有必要明确地这么说。
非类型化和动态类型化绝对不是同义词。最常被称为"非类型化"的语言是lambda微积分,它实际上是一种统一类型的语言——一切都是一个函数,所以我们可以静态地证明一切的类型都是函数。动态类型语言有多种类型,但没有为编译器添加静态检查它们的方法,从而强制编译器插入变量类型的运行时检查。
那么,javascript是一种动态类型的语言:它可以用javascript编写程序,这样一些变量
这两个语句都是正确的,这取决于您是在谈论值还是变量。javascript变量是非类型化的,javascript值具有类型,并且变量可以在运行时覆盖任何值类型(即"动态")。
在JavaScript和许多其他语言中,值和非变量携带类型。所有变量都可以覆盖所有类型的值,并且可以被视为"动态类型"或"非类型化"——从类型检查的角度来看,没有/不可知类型的变量和可以接受任何类型的变量在逻辑上和实际上是等效的。当类型理论家谈论语言和类型时,他们通常谈论这一点——携带类型的变量——因为他们对编写类型检查程序和编译器等感兴趣,这些程序对程序文本(即变量)进行操作,而不是在内存中运行的程序(即值)。
与其他语言(如C)不同,变量携带类型,但值不携带类型。在像Java这样的语言中,变量和值都携带类型。在C++中,一些值(带有虚拟函数的值)携带类型,而其他值则不携带。在某些语言中,值甚至可能更改类型,尽管这通常被认为是糟糕的设计。
这个问题都是关于语义的。
如果我给你这个数据:
如果我给你一种假想的语言,它允许你在这个数据和一些其他任意的数据上使用诸如"加"、"减"和"连接"之类的操作符,"类型"与(我的假想语言)有些不相关(例如:也许
让我们谈谈C。C几乎可以让你用任意的数据块做任何你想做的事情。如果您使用的函数接受两个
然而,说到布兰登的观点,如果我告诉你"我的年龄是
这就是我一开始说的原因——你的问题是语义学。"非类型化"是什么意思?我想布兰登说"禁止静态类型"的时候,他就直截了当了——因为这就是所有可能的意思。人类自然地把事物分为不同的类型。我们凭直觉知道,汽车和猴子之间有本质上的区别——从来没有人教过我们做出这些区别。
回到我的例子开始-一种"不关心类型"的语言(本身)可能会让你"添加"一个"年龄"和一个"名字",而不会产生语法错误…但这并不意味着这是一个合乎逻辑的操作。
JavaScript可以让你做各种疯狂的事情而不考虑它们的"错误"。这并不意味着你所做的是合乎逻辑的。这是开发人员要解决的问题。
在编译/构建/解释时,系统/语言是否不强制类型安全"非类型化"或"动态类型化"?
语义学。
编辑
我想在这里添加一些东西,因为有些人似乎开始关注"是的,但javascript确实有一些"类型"。
我在评论别人的回答时说:
在javascript中,我可以拥有我构建的"猴子"对象和我构建的"人类"对象,并且一些功能可以设计为仅对"人类"操作,其他功能仅对"猴子"操作,而其他功能仅对"有手臂的东西"操作。不管语言是否被告知,有这样一类对象,"有武器的东西"与汇编("非类型化")都与JavaScript("动态")无关。这完全是一个逻辑完整性的问题——唯一的错误就是使用了一些不支持这种方法的东西。
因此,如果您认为Javascript在内部有一些"类型的概念",因此也有一些"动态类型",并且认为这与非类型化系统有着明显的区别,那么从上面的例子中,您应该看到它在内部有任何"类型的概念"都是不相关的。
例如,要使用C_执行相同的操作,我需要一个名为
显然,javascript是否对"类型"有任何理解是无关紧要的。
虽然大多数关于类型的研究人员基本上只考虑具有语法派生类型的语言作为类型化语言,但我们中有很多人使用的是动态/延迟类型化语言,他们对这种用法感到不满。
我认为有3种类型的语言:
非类型化-只有运算符确定值的解释-它通常适用于任何事物。示例:汇编程序、BCPL
静态类型化-表达式/变量具有与其相关联的类型,并且该类型决定了编译时运算符的解释/有效性。实例:C、Java、C++、ML、Haskell
动态类型化-值具有与其关联的类型,并且该类型决定了运行时运算符的解释/有效性。示例:lisp、scheme、smalltalk、ruby、python、javascript
据我所知,所有动态类型语言都是类型安全的-即只有有效的运算符才能对值进行操作。但对于静态类型语言来说,情况并非如此。根据所用类型系统的功率,某些操作员只能在运行时进行检查,或者根本不进行检查。例如,大多数静态类型的语言不正确处理整数溢出(添加2个正整数可以产生负整数),并且超出界限数组引用根本不被检查(C,C++),或者只在运行时检查。此外,一些类型系统非常弱,因此有用的编程需要转义图案填充(在C和Family中进行强制转换)来更改表达式的编译时类型。
所有这些都导致了荒谬的说法,比如C++比Python更安全,因为它是(静态类型的),而事实是Python本质上是安全的,而你可以用C++来截断你的腿。
同意布伦丹的观点——上下文就是一切。
我的拿手:
我记得大概是在2004年,当时有人对Ruby是非类型化还是动态类型化争论不休。旧的C/C++的人(我是其中之一)正在思考编译器,并说露比是非类型化的。
记住,在C语言中,没有运行时类型,只有地址,如果正在执行的代码决定将该地址中的任何内容视为不存在的内容,那就糟糕了。这绝对是非类型化的,与动态类型化非常不同。
在那个世界里,"打字"是关于编译器的。C++具有"强类型",因为编译器的检查更加严格。Java和C更"弱类型"(甚至有关于Java是强类型还是弱类型)的争论。在这个连续体中,动态语言是"非类型化的",因为它们没有编译器类型检查。
今天,对于程序员来说,我们已经习惯了动态语言,很明显我们认为非类型化意味着没有编译器和解释器类型检查,这将是非常难以调试的。但有一段时间,这并不明显,在更理论化的CS世界中,这甚至可能没有意义。
在某种深层意义上,没有什么可以被非类型化(或者说几乎没有什么),因为您必须有一些意图来操纵一个值来编写一个有意义的算法。这是理论CS的世界,它不处理如何为给定语言实现编译器或解释器的细节。因此,在这种情况下,"非类型化"完全没有意义(我可能不知道)。
我不是一个计算机科学家,但如果"非类型化"在CS社区(至少在科学出版物中)真的被用作"动态类型化"的同义词,就像这两个术语描述不同的概念一样,我会感到非常惊讶。动态类型化语言有类型的概念,它在运行时强制执行类型约束(例如,在Lisp中,不能在不出错的情况下将整数除以字符串),而非类型化语言根本没有任何类型概念(例如,汇编程序)。即使是维基百科关于编程语言的文章(http://en.m.wikipedia.org/wiki/programming_language typed诳vs诳untyped诳languages)也有这种区别。
更新:可能混淆源于这样一个事实:有些文本在javascript中说了"变量没有被输入"(这是真的)。但这并不意味着语言是非类型化的(这是错误的)。