Javascript SICP 3.2 - The Environment Model of Evaluation (完

图片皆摘录于 https://www.comp.nus.edu.sg/~cs1101s/sicp/

前言:

经过3.1赋值之后,光用“名字”对应值已经不再适用了,需要一个“位置”去储存这些值,这些“位置”会维持在一个结构,称为“environments”

Environment, frame, binding

environments 就是一个 “frame”的序列,而每个 frame 是一个 “binding”的表格(可能为空),binding将变量与值对应起来,一个frame中的binding最多只会对应一个变量,如果变量在任何frame中都没有定义binding,就称为“unbound”。
http://img2.58codes.com/2024/20117516nnjCyAuUtV.png

Figure 3.1 有三个 frame I, II, III,观察x,在每个frame里面的值 I: 3, II:7, III: 3
可看到 x 在 frame III中并没有 binding, ,所以沿着D回去找发现 frame I有x的binding,因此x在frame II中的值与frame I中相同。

The Rules for Evaluation

Evaluate the subexpressions of combination 对组合式的子表达式求值Apply the value of the function subexpression to the values of the argument subexpressions. 将子表达式function的值应用在子表达式的参数上

其实跟1.1.3说的是一样的事情,但这次用environment model的求值方式,不一样的是,会将compound function带入argument。

Function definition

在environment model中,一个function是一个pair,一边指向程式码与指向environment的pointer所组成,只有一个方法能创造function: by evaluating a function definition expression。

funciton square(x) {    return x * x;}

其实是以下方式的syntactic sugar:

const square = x = x * x; 

http://img2.58codes.com/2024/20117516qJnzatUsmS.png

Function evaluating

http://img2.58codes.com/2024/201175160YHKZdCoTK.png

当对square(5)求值

创造新的Environment E1,且有x变数在初始的frame中,bound to 5,pointer指向global environment.

square在E1对body进行求值,回传xx,x值已绑定5,55=25。

Applying Simple Functions

function square(x) {    return x * x;}function sum_of_squares(x, y) {    return square(x) + square(y);}function f(a) {    return sum_of_squares(a + 1, a * 2);}

http://img2.58codes.com/2024/20117516pvCBoUJSZp.png

http://img2.58codes.com/2024/20117516IoUi9xYFOA.png

其实就是上一个段落的複杂版,只要记得对一个function求值的规则就对了!另一个有趣的地方就是,square(x) + square(y)其实是创造了两个environment各自有自己的binding。

Frames as the Repository of Local State

利用Environment来分析3.1.1的 “withdrawal processor”

function make_withdraw(balance) {    function withdraw(amount) {        if (balance >= amount) {            balance = balance - amount;            return balance;        } else {            return "Insufficient funds";        }    }    return withdraw;}

在加入

const w1 = make_withdraw(100);

在对其求值
w1(50);

以environment model来解析:
http://img2.58codes.com/2024/20117516hIUrqKEamc.png

const w1 = make_withdraw(100); 开始就非常有趣了
http://img2.58codes.com/2024/20117516SDeL0IBmIe.png

首先一样新建一个E1环境且存在一个参数balance绑定100,接着对make_withdraw求值,产生了一个新的function object,且被w1绑定在global环境中。

求值 w1(50);
http://img2.58codes.com/2024/20117516OfJAGBKrZg.png

同样新建了一个环境,包含amount bound to 50,但这个环境的pointer是指向E1而不是global环境,而在这个环境中对function的body求值,求值后如下图

http://img2.58codes.com/2024/20117516TMA1oWC1Mk.png

求值后由于function body含有一个assignment balance = balance — amount ,执行后改变了E1中的 balance 变成50,且function object w1依然指向E1,原先的amout binding的frame已经不复存在,下次再求值w1,就又会产生新的frame、binding amount to 新的值,且指向E1。

如果再定义新的 w2 = make_withdraw(100); 呢?
http://img2.58codes.com/2024/20117516eeLB3hAgkI.png

将产生一个新的environment E2,其绑定着balance = 100,w2的指针一面指向E2、一面指向与w1相同的function。

最好玩的部分就是写习题惹~
http://img2.58codes.com/2024/20117516QI4C34QlvW.png
http://img2.58codes.com/2024/20117516jap3EadHFU.png
手画了一个,有点丑XD
http://img2.58codes.com/2024/20117516Y5YSexCfkE.png

Internal Definitions

function abs(x) {    return x >= 0 ? x : -x;}                function square(x) {    return x * x;}                function average(x,y) {    return (x + y) / 2;}              function sqrt(x) {    function good_enough(guess,x) {        return abs(square(guess) - x) < 0.001;    }    function improve(guess) {        return average(guess,x/guess);    }    function sqrt_iter(guess){        if (good_enough(guess,x)) {            return guess;        } else {            return sqrt_iter(improve(guess));        }    }    return sqrt_iter(1.0);}sqrt(5);

http://img2.58codes.com/2024/20117516MvU2EODFWh.png

当 sqrt(2) 执行,创造了一个E1环境,当中的binding 有x 及一些function object,接着对 sqrt_iter(1.0) 求值,创造了E2环境,接着对 good_enough 求值,又创造了E3环境,虽然 sqrt_iter 与 good_enough 的参数都叫做guess ,但其实是创造在不一样的环境里的不同变数。

总结来说environment model提供了一些技巧:

function内部的名称不会与外部环境名称相互干扰

function 内部名称可以直接使用外部环境的,只要单纯的将变数是free variables就好


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章