【问题标题】:Where does type declaration in programming languages come from?编程语言中的类型声明从何而来?
【发布时间】:2014-11-22 04:37:06
【问题描述】:

当我们在 C/C++ 中定义一个函数时,我们会输入类似的内容

int add(int a, int b){
    return a+b;
}

然而,我们在函数中做的实际事情是得到两个可求和的东西的总和并返回它的值。在许多早期创建的编程语言中,如 Algol、C、pascal,您应该在对变量进行一些操作之前声明变量的类型。此外,在 Java、C# 等相当多的主流语言中,这是必需的(尽管它有像“var”这样的关键字)。

在 Python 等许多动态编程语言中,我们将之前的函数重写为:

def add(a,b):
    return a+b

没有函数和参数的“类型标识符”。我在想的是,与C/C++之类的语言相比,Python版本似乎更接近程序员头脑中的原始思想:只是将两个数字相加并返回和的行为封装起来。

另一方面,在实践中,这些类型声明对减少错误有很大帮助,例如,如果我只想要两个数字的和,我不会将字符串传递给“add”函数。如果我传递两个字符串,编译器会将其视为错误。类型声明似乎是对这个例子中代码的保护。

但让我感到困惑的是,为什么这么多早期创建的语言需要对变量进行类型声明?为什么大多数带有类型声明的语言出现得更早,而大多数语法更简单的语言出现得更晚?

我知道我们无法判断哪种方法“更好”并且它们都是图灵完备的,但我只是好奇为什么早期的语言创造者没有选择更直观和更简单的语法,专注于实现功能 100%,但选择添加类型标识符作为语言的必需部分(问题 1)?另外,在早期,人们对代码应该是什么样子的印象非常模糊,所以我猜类型标识符的想法必须来自某个地方。我的第二个问题是类型声明的想法来自哪里(数学?实践?还是其他地方?)?如果我知道答案,我想我会对“类型”有更好的理解。

【问题讨论】:

    标签: types programming-languages


    【解决方案1】:

    可以说,数据类型的概念从一开始就存在于编程语言中。机器语言的第一个语言,甚至对于那些它可能相关的语言,例如,添加整数或添加浮点数。不过,类型区分是通过使用不同的指令来实现的。

    第一个更高级的语言是 Fortran(1950 年代中期)。 Fortran 区分变量类型,但不是基于类型声明,而是基于变量名。例如,变量 i、j k 等将是整数,而 p、q、r 浮点数(IIRC)。这允许使用相同的方便符号,例如另外,不管是什么类型。

    显然,这是一个非常老套的想法,并且无法扩展到任何更有趣的类型系统。因此,下一代语言,尤其是 Algol(1950 年代后期),使这一点更加明确,并引入了类型的语法。

    随着语言变得更加高级并支持更多有趣的数据类型,类型系统也变得更加有趣。在某个时候(大约在 1970 年),人们意识到编程语言中的类型实际上与数学中已知的类型概念非常密切相关:即,在 1930 年代发明的类型化 lambda 演算中。事实上,人们意识到计算逻辑和编程语言之间的关系实际上在各个层面上都是极其密切的,并且编程语言可以解释为 lambda 演算的变体,这是大多数现代编程语言的理论(和设计)可以。

    无类型(或所谓的“动态类型”,明显滥用术语)编程语言也相当古老。第一个是 Lisp(1950 年代后期),它实际上已经从无类型的 lambda 演算中获得了灵感。然而,这种语言直到很久以后才流行起来。原因是它们在运行时系统中需要更昂贵的机器,这在计算的早期是买不起的,现在通常仍然买不起。 (最近对此类语言的炒作似乎在这些天有所消退,因为(重新)发现这种开发形式不能很好地扩展——现在为这些语言发明的所有类型系统都证明了这一点:Typed Scheme、TypeScript、MyPy、Hack 等)

    顺便说一句,编程语言部分地从逻辑中获得的另一个灵感是类型推断。即使最初发明了类型化 lambda 演算,也已经有两种形式:显式类型和隐式类型。函数式语言 ML 是第一个采用与编程类似的想法的语言(1970 年代后期):ML 程序无需编写单个类型声明即可进行完全类型检查。最近,这个想法已经出现在主流语言中,尽管通常以更有限的方式。

    也就是说,类型化和非类型化之间的区别不一定与语法和类型声明的存在有关——一种语言可以(“静态”)类型化,并且不需要类型声明。

    【讨论】:

    • 谢谢,这正是我很好奇的。顺便说一句,我们经常看到数学中定义函数的符号,比如 f:R^2->R,这和编程中的类型声明有关系吗?
    • @sorrow17,嗯,是的,类型论(在计算逻辑中)是作为数学的基础理论发明的,就像集合论一样,所以它自然地借用了符号。从那里它可能会进入编程语言,例如,在 lambda 演算中你会写 f : R × R → R,而在 ML 中 f : real * real -> real 作为类型注释。
    【解决方案2】:

    Andreas 出色的历史并没有解决问题的第一部分。数据类型很早就存在于编程语言中,但问题是为什么需要类型声明。

    原因是内存容量。当时,包括编译器在内的程序必须在非常有限的内存量下运行。这有两个直接后果:

    • 程序员不能使用一种万能的方法来表示数据,因为它使用内存效率低下;他们希望专门针对不同类型的数据表示,以便一次可以将更多数据放入内存中。

    • 编译器无法一次将整个程序放入内存中,因此他们需要能够单独编译其中的一部分,然后再将它们链接起来。要编译一个部分,通常需要知道数据在其他部分中是如何表示的。

    至少在 C 语言中,类型声明为这两个问题提供了解决方案。

    【讨论】:

    • 很好的答案,尤其是“链接”部分。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-12
    • 2018-11-29
    • 2016-03-31
    • 2012-03-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多