函数式编程:为什么将配对作为基本构造单元?

Functional Programming: why pair as a basic constructed unit?

Basic cons-cell 将两个任意的东西粘在一起,是允许构造链表和任意数据对象的基本单元。问题:是否有理由坚持这种简单的语言设计决策(例如,在所有 lisp 家族中)?
为什么不为此目的使用固定长度的数组(或一些嵌套堆栈)?我无法预见到任何问题,但是更多 "packed" 内存、更少的指针分辨率和更少的 "dead-weight" cons-cells 来定义数据的层次结构有明显的优势。

您将问题命名为“函数式编程:为什么将 pair 作为基本构造单元?”,但是这个标题并没有正确反映许多重要且众所周知的函数式语言(例如 Haskell、F# , Scala, SML, Clojure 等)有代数数据类型或不同的 collection 数据结构,其中这对只是不同类型的构造函数之一,如果可用的话。对于其他支持函数式编程的多范式语言,情况类似,如 C++、Java、Objective-C、Swift 等

在所有这些情况下,该对(如果存在)完全是“基本的”数组、记录或列表,或任何其他类型的数据构造函数。

剩下的是 Lisp 语言家族,特别是 Common Lisp 和 Scheme,它们除了拥有丰富的数据结构集(如 Rainer Joswig 评论中引用的那些)外,还使用它们来完成一项重要任务:作为表示程序的基本数据构造器。

Lisp 代码是 s-expression(即列表和原子的列表)这一事实具有根本性的影响,其中最显着的是宏系统的兴起,它允许程序员轻松创建新的语法,甚至是新的 domain-specific 语言。

关于函数式编程中的其他结构是正确的。函数编程是关于将编程与逻辑和数学对齐,其中表达式表示值,并且没有副作用这样的东西。 (当然,在实践中,我们需要 I/O 等的副作用)函数式编程不需要单链表作为基本构造。

列表 使 Lisps 口齿不清的原因之一。 对在 Lisp 语言家族中如此普遍的原因之一可能是有序对很容易在 Lisp 受到启发的 lambda 演算中实现。 (我说 "inspired by" 而不是 "based on" 是因为在语法和使用 lambda 表示匿名函数之后,有很多差异,最好不要假设一个适用于另一个。)见Use of lambda for cons/car/cdr definition in SICP 的答案,快速了解如何只使用词法闭包来实现 cons、car 和 cdr。