“值”:是计算机中存储的实际数据或指令。
你试图从机器的角度来非常具体地思考它,我担心这可能会让你感到困惑。最好从数学角度来思考:值只是一个永远不会改变的东西,就像数字 42、字母“H”或构成“Hello world”的字母序列。
另一种思考方式是心理模型。我们发明心智模型是为了间接推理世界;通过推理心理模型,我们对现实世界中的事物做出预测。我们编写计算机程序来帮助我们可靠地、大量地处理这些心理模型。
那么价值观就是心智模型中的事物。位和字节只是编码将模型融入到计算机的体系结构中。
“变量”:它是一种定位数据的方式,是一种值替换的引用,但它本身并不是计算机中存储的一组数据或指令。
变量只是代表程序特定范围内的值的名称。每次对一个变量求值时,都需要在一个变量中查找它的值环境。这个概念在计算机术语中有多种实现方式:
- Eager 语言中的堆栈帧是一个环境的实现,用于在每次调用例程时查找局部变量的值。
- 链接器提供了在程序编译或加载到内存时查找全局范围名称的环境。
“抽象” “功能” ∈ 句法形式。
抽象和功能并不等同。在 lambda 演算中,“抽象”是一种语法表达式,但函数是一个值。
一个不太寒酸的比喻是名称和描述 vs. things。名称和描述是language,而事物是一部分world。您可以说名称或描述的含义是它命名或描述的事物。
语言包含事物的简单名称(例如,12
是数字十二的名称)和更复杂的事物描述(5 + 7
是对数字十二的描述)。 lambda 抽象是对函数的描述;例如,表达式\x -> x + 7
是对其参数添加 7 的函数的描述。
诀窍在于,当描述变得非常复杂时,要弄清楚它们所描述的是什么并不容易。如果我给你12345 + 67890
,您需要做一些工作才能找出我刚才描述的数字。计算机是比我们更快、更可靠地完成这项工作的机器。
“应用程序”:它接受“抽象”的输入,以及“lambda 表达式”的输入,产生“lambda 表达式”。
应用程序只是一个带有两个子表达式的表达式,它通过以下方式描述一个值:
- 第一个子表达式代表一个函数。
- 第二个子表达式代表某个值。
- 整个应用程序代表将 (1) 中的函数应用到 (2) 中的值所得到的值。
在形式语义中(不要害怕这个词)我们经常使用双括号 ⟦∙⟧ 来代表“的含义”;例如⟦dog⟧ = “狗的意思。”使用该符号:
⟦e1 e2⟧ = ⟦e1⟧(⟦e2⟧)
where e1
and e2
是任意两个表达式 or terms(任何变量、抽象或应用程序)。
“抽象”之所以被称为“抽象”,是因为在通常的函数定义中,我们将(通常较长的)函数体缩写为更短的形式,即函数标识符后跟形式参数列表。 (虽然 lambda 抽象是匿名函数,但其他函数通常确实有名称。)
说实话,我从未停下来思考“抽象”这个词是否适合这个词,或者为什么选择它。一般来说,对于数学来说,提出这样的问题是没有好处的,除非术语选择得非常糟糕并且误导了人们。
“常量” ∈ “变量”
“文字” ∈ “值”
lambda 演算本身没有“常数”或“文字”的概念。但定义这些的一种方法是:
- 文字是一种表达式,由于语言的规则,无论出现在何处,它始终具有相同的值。
- 在纯函数式语言中,常量是程序最顶层范围的变量。该变量的每次(非隐藏)使用在程序中始终具有相同的值。
“形式参数” ∈ “变量”
“实参”(自变量)ε“值”
形式参数是一种use一个变量的。以任何形式表达λv.e
(where v
是一个变量并且e
是一个表达式),v
是一个形式变量。
参数是作为应用程序的第二个子表达式出现的任何表达式(不是值!)。
“变量”可以具有“数据”的“值”=> 例如变量“a”的值为 3
All 表达式有值,而不仅仅是变量。例如,5 + 7
是一个应用程序,它的值为 12。
“变量”也可以具有“一组指令”的“值”=>例如运算符“+”是变量
的价值+
是一个函数——它是添加其参数的函数。该指令集是一个执行该功能的。
将函数视为一个抽象表,它表示对于参数值的每个组合,结果是什么。指令的输入方式是这样的:
- 对于很多函数,我们无法将它们真正实现为表格。在加法的情况下,这是因为表将无限大。
- 即使对于我们可以枚举情况的函数,我们也希望更简单、更高效地实现它们。
但是检查函数是否实现的方式是correct从某种意义上说,是为了检查在每种情况下它都执行与“无限表”相同的操作。以这种方式检查的两组指令实际上是同一功能的两种不同实现。