• 对SCHEME的一些理解(4)


    SICP练习3.10
    (define (make-withdraw initial-amount)
        (let ((blance initial-amount))
            (lambda (amount)
                (if (>= balance amount)
                    (begin (set! balance (- balance amount)) balance)
                    "Insufficient funds"))))

    我们先改写为标准lambda表达式:
    (define make-withdraw
        (lambda (initial-amount)
            ((lambda (balance)
                (lambda (amount)
                    (if (>= balance amount)
                        (begin (set! balance (- balance amount)) balance)
                        "Insufficient funds")))
            initial-amount)))

    以上define语句执行后,会在全局环境E0中注册一个符号make-withdraw,其值为一个
    过程对象,对象内容如下:

    proc0:
    --------------------------------
    |  env-pointer : E0            |
    --------------------------------
    |  parameters : initial-amount |
    --------------------------------
    |  code :                      |
    |  ((lambda (balance)          |
    |      (lambda (amount)        |
    |        ...                   |
    --------------------------------

    E0:
    --------------------------------
    |  outter-env : null           |
    --------------------------------
    |  make-withdraw : proc0       |
    --------------------------------

    看看求值如下表达式会发生什么情况
    (define W1 (make-withdraw 100))
    define的作用是将一个符号和一个值联系起来,并存储于某个环境之中,所以以上语句
    执行步骤如下:
    1、对表达式(make-withdraw 100)求值,求值操作的环境为全局环境E0,组合表达式
    求值应先求值子表达式,所以先求值符号make-withdraw,在E0环境中搜索到其值为一
    过程对象proc0(如前所示),在求值“100”,100为自求值符号,返回值100。
    2、将实参应用于操作符proc0。这一步将执行两个操作,一是创建新环境E1,
    而proc0中的env-pointer : E0,所以E1的外部环境为E0,在E1环境中注
    册符号:initial-amount : 100。

    E1:
    --------------------------------
    |  outter-env : E0             |
    --------------------------------
    |  initial-amount : 100        |
    --------------------------------

    3、在新建环境E1中求值proc0的code:
    ((lambda (balance)
        ((lambda (amount)
            (if (>= balance amount)
                (begin (set! balance (- balance amount)) balance)
                "Insufficient funds")))
    initial-amount)
    首先求值前面的的lambda表达式(lambda (balance)...,lambda表达式会在当前环境中
    注册一个无名的函数对象proc-unnamed0(随意取的),无名函数必须为立即使用或传递
    否则之后将无法调用。再求值符号initial-amount,在E1中搜索得到值为100。

    proc-unnamed0:
    --------------------------------
    |  env-pointer : E1            |
    --------------------------------
    |  parameters : balance        |
    --------------------------------
    |  code :                      |
    |  ((lambda (amount)           |
    |      (begin (set!....        |
    |        ...                   |
    --------------------------------

    4、将实参100应用到proc-unnamed0,与步骤2类似,创建环境E2,因为proc-unnamed0的
    外部环境为E1,所以E2的外部环境设置为E1,在E2环境中注册变量balance : 100。

    E2:
    --------------------------------
    |  outter-env : E1             |
    --------------------------------
    |  balance : 100               |
    --------------------------------
    5、在环境E2中求值proc-unnamed0的code,code为一lambda表达式,直接返回函数对象proc1与
    W1符号链接,且注册到E0环境中。

    proc1:
    --------------------------------
    |  env-pointer : E2            |
    --------------------------------
    |  parameters : amount         |
    --------------------------------
    |  code :                      |
    |  ((begin (set! balance...    |
    |        ...                   |
    --------------------------------

    最后E0如下:
    E0:
    --------------------------------
    |  outter-env : null           |
    --------------------------------
    |  make-withdraw : proc0       |
    --------------------------------
    |  W1 : proc1                  |
    --------------------------------
    proc-unnamed0对象执行完毕后,因为没有被任何符号约束,所以可以直接释放掉。
    所以目前的内存状态为:
    E0 <- E1 <- E2
    proc0 -> E0
    proc1 -> E2

    再来看执行(W1 50)会发生什么?
    1、(W1 50)在全局环境E0中执行,首先求符号W1的值,在E0中搜索得到W1的约束,
    返回值proc1,求值“50”,返回数值50。
    2、将实参50应用到proc1。先创建环境E3,将约束amount : 50注册到E3中,关键时刻到了,
    由于proc1的环境指针为E2,所以E3的外部环境为E2。
    E3:
    --------------------------------
    |  outter-env : E2             |
    --------------------------------
    |  amount : 50                 |
    --------------------------------
    3、在E3中求值proc1,既运行proc1的code,为if表达式,其中的amount在E3中约束,而balance
    在E2中约束。

    (define W2 (make-withdraw 100))与上同理,可见这种方法相比文中例子,多浪费了一个E1环境,
    其中约束了一个无用符号initial-amount。

  • 相关阅读:
    将不同服务器的一个表的数据复制到另一个表里面
    15丨基础篇:Linux内存是怎么工作的?
    13 | 答疑(一):无法模拟出 RES 中断的问题,怎么办?
    12 | 套路篇:CPU 性能优化的几个思路
    11 | 套路篇:如何迅速分析出系统CPU的瓶颈在哪里?
    10 | 案例篇:系统的软中断CPU使用率升高,我该怎么办?
    nginx error.log 提示 [error] 887#887: *58 FastCGI sent in stderr: "PHP message: PHP Warning: mysql_connect(): Headers and client library minor version mismatch. Headers:50556 Library:50637
    PHP查询数据库较慢,nginx 超时 返回 504:Sorry, the page you are looking for is currently unavailable.
    编码 ASCII, GBK, Unicode+utf-8
    python之re正则简单够用
  • 原文地址:https://www.cnblogs.com/effulgent/p/2572094.html
Copyright © 2020-2023  润新知