# 2.2分层数据和闭包属性

> 译者： [https://sicp.comp.nus.edu.sg/chapters/29](https://sicp.comp.nus.edu.sg/chapters/29)



如我们所见，对提供了一种原始的&lt;quote&gt;胶水&lt;/quote&gt;，我们可以使用它们来构造复合数据对象。 图 [2.2](29#fig_2.2)![](img/970a4994f13d12157a0c2944f518185d.jpg)在此表示形式中，称为_框和指针符号_，每个复合对象都显示为指向框的_指针_。 一对的盒子有两部分，左边的部分包含该对的头部，右边的部分包含尾部。 [[1]](29#footnote-1)&lt;/split&gt; 

我们已经看到`pair`不仅可以用于组合数字，还可以用于组合对。 （您在练习中利用了这个事实，或者应该在练习中使用 [2.2](26#ex_2.2)[2.3](26#ex_2.3)[2.3](29#fig_2.3)![](img/9d8dd56e7bb3a72cbd3fae3dc7cd4cb0.jpg)&lt;/split&gt;

创建其元素为对的对的能力是列表结构作为表示工具的重要性的本质。 我们将此功能称为`pair`的_关闭属性_。 通常，如果可以使用同一操作将事物与该对象进行合并的结果本身进行合并，则用于合并数据对象的操作将满足闭包属性。 [[2]](29#footnote-2) 闭合是任何组合方式中实现权力的关键，因为它允许我们创建_分层_结构-由零件组成的结构，这些零件本身由零件组成，并且 以此类推。

从第1章开始，我们在处理函数时就使用了闭包，因为除了最简单的程序之外，所有程序都依赖于这样一个事实，即组合的元素本身可以是组合。 在本节中，我们将讨论复合数据关闭的后果。 我们描述了一些使用对来表示序列和树的常规技术，并且我们展示了一种图形语言，以生动的方式说明了闭合。 [[3]](29#footnote-3)

* * *

[[1]](29#footnote-link-1) In this JavaScript adaptation, we choose to draw primitive objects directly inside of the boxes of the pairs that contain them, in an attempt to be consistent with a similar practice introduced in section <ref name="sec:environment-model">[3.2](52)</ref>. The box-and-pointer diagrams in the original version of the textbook include separate boxes for primitive objects, such as 1 and 2, each containing a representation of the object.

[[2]](29#footnote-link-2) The use of the word <quote>closure</quote> here comes from abstract algebra, where a set of elements is said to be closed under an operation if applying the operation to elements in the set produces an element that is again an element of the set. The Lisp community also (unfortunately) uses the word <quote>closure</quote> to describe a totally unrelated concept: A closure is an implementation technique for representing functions with free names. We do not use the word <quote>closure</quote> in this second sense in this book.

[[3]](29#footnote-link-3) The notion that a means of combination should satisfy closure is a straightforward idea. Unfortunately, the data combiners provided in many popular programming languages do not satisfy closure, or make closure cumbersome to exploit. In Fortran or Basic, one typically combines data elements by assembling them into arrays—but one cannot form arrays whose elements are themselves arrays. Pascal and C admit structures whose elements are structures. However, this requires that the programmer manipulate pointers explicitly, and adhere to the restriction that each field of a structure can contain only elements of a prespecified form. Unlike Lisp with its pairs, these languages have no built-in general-purpose glue that makes it easy to manipulate compound data in a uniform way. This limitation lies behind Alan Perlis's comment in his foreword to this book: <quote>In Pascal the plethora of declarable data structures induces a specialization within functions that inhibits and penalizes casual cooperation. It is better to have 100 functions operate on one data structure than to have 10 functions operate on 10 data structures.</quote>

