'Missing'(?) 编程语言的特性?

'Missing'(?) feature in programming languages?

让我们以 Haskell 为例,因为它最接近我将要描述的我所知道的语言。

一个类型,例如 Int,可以被视为所有可能值(该类型)的集合。 为什么我们只能处理非常特定的集合? IntDouble 等...而不是类型系统中的所有子集。

我喜欢一种语言,我们可以在其中定义任意类型,例如 Int greater than 5。有这样的语言的例子吗?如果不是,为什么不呢?

您正在寻找 Dependent types。 Idris、Agda 和 Coq 在这一类中很有名。

您实际上可以在 Haskell 中定义它,因为它基本上是 Int 加上一些语义。例如,您必须决定如何处理低于阈值的减法,例如 (-) 6 7 给出的结果。 (Peano 算术的一个常见约定是给出 0——所以在这种情况下它会 return 6,系统的最小值。)你还需要选择是否要 errorfromInteger 3 上,或者您是否要存储 newtype IntGT5 = IntGT5 (Maybe Int) 而不是 newtype IntGT5 = IntGT5 Int。您必须自己编写所有类型class 实例,完成后您将拥有合适的类型。

如果您对这个问题有持久的兴趣,需要注意两件事 liquid types and subtyping。让我告诉你一些关于后者的事。

Alan Kay 发明的 OOP 与现在不同(他希望每个程序都编写为通信计算机的网络),但在现代世界中它基本上是一种做事的方式复杂的子类型。例如,"Duck typing" 是关于创建一堆真正通用类型的 "intersection type"(例如带有 "waddle" 方法的东西,带有 "quack" 方法的东西)其他类型是的子类型。所以子类型化是非常自然的 OOP。

我链接到的论文指出了关于子类型的另一件有趣的事情:您可以使用子类型来消除类型和值之间的区别。当然,将类型变成值不需要子类型;它是例如在 Python 语言中已经是这种情况,您可以在其中调用 type(x) 来获取表示对象类型的对象。但有趣的是,随着子类型的发展,你可以只定义一个类型 3 :: Int3 of kind Int),它是所有 Int 的类型,它们是相等的至 3。它本质上是一个 unit/void 类型,是更大的 class 的子类型。通过模糊 3 of kind Int3 of type Int 之间的区别,你得到每个值也是一个类型。然后你可以用这种方法做一些 JSON-like 的事情,其中​​ {x: Int, y: 3 :: Int} 是一种包含两个属性 xy 的对象类型,其中 x 是任何 Inty 是整数 3 :: Int.

Ada language 支持范围数值类型。我真的不能对这种语言发表明智的评论,但我已经被知道它的人理解为范围检查是由编译器插入的运行时检查强制执行的。

关系数据库理论也有与此相关的概念。属性可以采用的值集是它的 domain, which is a function of its data type and the constraints 。但是,实际的 RDBMS 通常不会完全通用地实现这些概念。

依赖类型是一个更通用的系统,可以对这种约束和许多其他约束进行编码。我对依赖类型的概括解释是这样的:它们是一种设计编程语言的方法,其中包含 证明作为第一个 class 值 。证明是一种价值,凭借其存在和遵守的规则,保证 命题 (a.k.a. "sentence," "statement," 等)。

所以在依赖类型下,你可以有一个类型 x > 5,其值证明 x 大于 5。如果您有这种类型的实际值,那么 x 确实大于 5,因此在该假设下可以安全地执行此证明范围内的代码。您可以使用 dependent sum type 将数字和证明打包在一起,我们可以将其标记为 ∃x : Int. x > 5,其值为 pairs这样:

  1. 第一个元素是整数x
  2. 第二个元素是x > 5
  3. 的证明