> For the complete documentation index, see [llms.txt](https://zlt-shadow.gitbook.io/sicp-in-python-cn/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://zlt-shadow.gitbook.io/sicp-in-python-cn/di-3-zhang-jie-shi-ji-suan-ji-cheng-xu/3.1-yin-yan.md).

# 3.1 引言

第1章和第2章描述了编程的两个基本元素：函数和数据之间的紧密联系。 我们看到了如何使用高阶函数将函数作为数据进行操作。 我们还了解了如何使用消息传递和对象系统赋予数据行为。 我们还学习了组织大型程序的技术，如函数抽象、数据抽象、类继承和泛型函数。 这些核心概念构成了构建模块化、可维护和可扩展程序的强大基础。&#x20;

本章着重于编程的第三个基本要素：程序本身。 Python程序只是文本的集合。 只有通过解释的过程，我们才能根据文本执行任何有意义的计算。 像Python这样的编程语言之所以有用，是因为我们可以定义一个解释器，一个执行Python求值和执行过程的程序。 毫不夸张地说，这是编程中最基本的思想，即决定编程语言中表达式的意义的解释器只是另一个程序。&#x20;

要理解这一点，就必须改变我们作为程序员的形象。 我们逐渐把自己看作是语言的设计者，而不仅仅是别人设计的语言的使用者。

### 3.1.1 编程语言

编程语言在语法结构、特性和应用领域上有很大的差异。 在通用编程语言中，函数定义和函数应用程序的构造非常普遍。 另一方面，强大的语言不包括对象系统、高阶函数、赋值，甚至不包括控制结构(如while和for语句)。 作为具有最小功能集的强大语言的一个例子，我们将介绍[Scheme编程语言](https://en.wikipedia.org/wiki/Scheme_\(programming_language\))。 本文中引入的Scheme子集根本不允许可变值。&#x20;

在这一章中，我们研究解释器的设计以及它们在执行程序时产生的计算过程。 为通用编程语言设计一个解释器的前景似乎令人生畏。 毕竟，解释器是可以执行任何可能的计算的程序，这取决于它们的输入。 然而，许多解释器都有一个优雅的共同结构：两个相互递归的函数。 第一个是对环境中的表达式求值; 第二种方法是将函数应用于参数。&#x20;

这些函数是递归的，因为它们是根据彼此定义的：应用函数需要对函数体中的表达式求值，而对表达式求值可能涉及应用一个或多个函数。
