噢,老兄,我很高兴能尽我所能回答这个问题。希望我能正确整理思路。
正如@Doval所提到的,以及发问者指出的(尽管很粗鲁),您实际上没有类型系统。您有一个使用标签进行动态检查的系统,该系统通常较弱,并且也不太有趣。
“什么是类型系统”这个问题可以从哲学上讲,我们可以在这本书上充斥不同的观点。但是,由于这是一个面向程序员的网站,因此我将尽量保持答案的实用性(实际上,尽管有人会想到,但类型在编程中非常实用)。
总览
在深入探讨更正式的基础之前,让我们先来了解一下类型系统的优点。类型系统在我们的程序上加上结构。他们告诉我们如何将各种功能和表达方式结合在一起。没有结构,程序就站不住脚,极其复杂,很容易在程序员的丝毫错误下造成伤害。
使用类型系统编写程序就像在薄荷状态下驾驶汽车-制动器起作用,车门安全关闭,发动机已上油等。没有类型系统编写程序就像骑没有头盔的摩托车,并制造轮子没有意大利面。您绝对无法控制自己。
为了使讨论更基础,我们假设我们有一种语言具有文字表达num[n]
,str[s]
并且分别表示数字n和字符串s,plus
以及concat
具有预期含义的原始函数和。显然,您不希望能够编写类似plus "hello" "world"
或的内容concat 2 4
。但是,如何防止这种情况呢?先验地,没有方法将数字2与字符串文字“世界”区分开。我们要说的是,这些表达应在不同的上下文中使用。他们有不同的类型。
语言和类型
让我们退后一步:什么是编程语言?通常,我们可以将编程语言分为两层:语法和语义。它们也分别称为静力学和动力学。事实证明,类型系统对于调解这两个部分之间的交互作用是必需的。
句法
程序就是一棵树。不要被您在计算机上写的几行文字所迷惑;这些只是程序的人类可读表示。该程序本身是一个抽象语法树。例如,在C语言中,我们可以这样写:
int square(int x) {
return x * x;
}
这是程序(片段)的具体语法。树表示为:
function square
/ | \
int int x return
|
times
/ \
x x
甲编程语言提供了一种语法定义,语言的有效树(混凝土或抽象语法可以使用)。通常使用BNF表示法完成此操作。我认为您已经针对创建的语言完成了此操作。
语义学
好的,我们知道程序是什么,但这只是一个静态树结构。大概,我们希望我们的程序实际计算一些东西。我们需要语义。
编程语言的语义学是一个广泛的研究领域。广义上讲,有两种方法:指称语义和操作语义。指称语义通过将程序映射到一些基础数学结构(例如自然数,连续函数等)中来描述程序。为我们的程序提供了意义 相反,操作语义通过详细说明程序的执行方式来定义程序。在我看来,操作语义对程序员(包括我自己)更加直观,因此,让我们坚持下去。
我不会介绍如何定义形式化的操作语义(细节涉及到一点),但是基本上,我们需要如下规则:
num[n]
是一个值
str[s]
是一个值
- 如果
num[n1]
和num[n2]
评估为整数n_1$ and $n_2$, then
plus(num [n1],num [n2])`评估为整数$ n_1 + n_2 $。
- 如果
str[s1]
和str[s2]
评估为字符串s1和s2,则concat(str[s1], str[s2])
评估为字符串s1s2。
等等,这些规则实际上更加正式,但是您可以理解要点。但是,我们很快就会遇到问题。当我们写以下内容时会发生什么:
concat(num[5], str[hello])
嗯 这是一个难题。我们尚未在任何地方定义有关如何将数字与字符串连接的规则。我们可以尝试创建这样的规则,但是我们凭直觉知道此操作是没有意义的。我们不希望该程序有效。因此,我们不可避免地被引向类型。
种类
程序是语言语法定义的树。程序由执行规则赋予含义。但是某些程序无法执行。也就是说,某些程序是没有意义的。这些程序类型错误。因此,打字可以用一种语言表征有意义的程序。如果程序类型正确,我们可以执行它。
让我们举一些例子。再次,与评估规则一样,我将非正式地提出打字规则,但是可以使它们变得严格。以下是一些规则:
- 形式的令牌
num[n]
具有类型nat
。
- 形式的令牌
str[s]
具有类型str
。
- 如果expression
e1
具有type nat
且expression e2
具有type nat
,则表达式plus(e1, e2)
具有type nat
。
- 如果expression
e1
具有type str
且expression e2
具有type str
,则expression concat(e1, e2)
具有type str
。
因此,根据这些规则,存在plus(num[5], num[2])
has type nat
,但是我们不能将类型分配给plus(num[5], str["hello"])
。我们说一个程序(或表达式)如果可以分配任何类型,则它是正确类型的,否则它是错误类型的。如果可以执行所有类型正确的程序,则类型系统是正确的。Haskell声音不错;C不是。
结论
关于类型还有其他观点。类型在某种意义上相当于直觉逻辑,它们也可以被视为范畴论中的对象。了解这些联系很有趣,但是如果只想编写甚至设计一种编程语言就不是必需的。然而,理解类型作为控制程序结构的工具是对编程语言设计和发展至关重要。我只是摸索了什么类型可以表达。我希望您认为它们值得将其纳入您的语言。