• SICP学习笔记(1.1.4~1.1.5)


                                                                      SICP学习笔记(1.1.4~1.1.5)
                                                                                         周银辉

    书接上一回, 这里是我在学习1.1.4~1.1.5时的一些笔记

    1, 标准过程与复合过程


    以 Scheme为例, 作为一门语言, 其内置了一些原始过程(或称之为标准的过程)与Scheme环境中, 比如, + 实际上与某个内置过程关联(绑定)了起来, 该过程接收两个参数并完成求和运算, 而字符"+"则是给该过程取的一个"名字". 同样,  abs与某个内置过程关联起来了, 其完成求绝对值的操作.
    如果我们将多个标准过程组合起来构成某一个相对复杂的运算过程,这个过程就成为复合过程, 同样, 我们会将某个名字与该复合过程关联起来.
    在" 名字"和"过程"的关联中, 首先名字对于一个组合过程来说并不是必须的,正如lambda表达式 ( 我不指c#的lambda表达式, c#的lambda表达式和匿名方法是一回事情, 注意了,"匿名"不是"无名", 只是对我们编程人员不可见而已,感觉是在玩“语法糖衣”,关于这个问题,我保留意见,我也不太了解C#的lambda, 不过关于λ演算,看这里  ).
    其次, "名字"和"过程"之间的关联关系也可以被重写的, 某些语言可能只允许你重写部分, 而Scheme是这样说的 : "程序可以使用最高层定义绑定任意变量,随后也可以用赋值操作(参见4.1.6)改变任何一个这样的绑定。这些操作不会改变Scheme 内置过程的行为。改变任何没有通过定义引入的最高层绑定,其结果对于内置过程的影响是未定义的"

    2, 求值与代换模型

    如果让我们对数字“5”进行求值的话,我们能轻松回答出来,其值就是其所代表的值5.

    如果让我们对变量 a 进行求值的话,那么比较简单,其值为某个与之相关联的值(也许它在内存的某个地方)。 这里的的“关联”也就是SICP中常说的”绑定“,实际上是“环境"帮我们做的。"环境"维护着一个由"键值对"组成的表结构,其"键"实际上就是我们的变量名,"值"为与该变量名相关联的某种类型的"对象". 最最基本的能够实现这种绑定的操作是我们的(Define A B) , 它将A和B(或B的地址)作为一个键值对放到某个表结构中.

    如果让我们对运算符"+"进行求值呢? 注意到上面在说"标准过程"和"复合过程"时, 已经提到, 实际上它也是与某个过程关联起来的, 它是个过程名, 很简单地, 如果我们将"+"理解成一个变量名, 参考上面所说的对变量a的求值, 一切就变得简单起来.  那么"+"所对应的值是什么呢? 是完成加法操作的指令序列. 所以对"+"这样的运算符也是可以求值的.(这些语句是我的个人理解, 没有多大把握 : 我们知道 λ 运算可以定义几乎任何东西, 比如"加法运算"可以表示成 λ m. λ n. λ f. λ x. m f (n f x) , "数字0"可以表示成0 = λ f. λ x. x 等等, 那么有了Defined和 λ 运算是否就可以支撑起整个Scheme或与之类似的语言呢?)

    如果让我们对 (+ a 5 ) 进行求值的话,(先不考虑应用序与正则序的问题) 首先应该是对各个子表达式依次求值,对+求值得到一个指令序列,我们用{Add}来表示, 然后对对a求值,我们假设为3,然后对5求值, 很简单, 5, 于是乎,得到了这样一个表达式({Add} 3  5)(至于如何求该表达式的值,待会再探讨)。 我们刚刚假设a为一个简单的变量,其值为3, 如果我们现在假设a为一个过程名,它与某个过程pro相关联,假设pro为(+ 1 2 )。如果我们的解释器先将pro的值计算出来, 然后用计算出来的值去替代表达式中的a, 那么我们的表达式将变成({Add}  3 5),这样的求值顺序就是SICP中所说的“应用序”,相反,如果 不计算pro而直接将pro的表达式内联到原表达式中,即用(+ 1 2)替换a,那么我们的表达式将变成({Add} (+ 1 2) 5),而(+ 1 2)将在最后整个表达式被完全展开后计算,这样的求值顺序就是"正则序"。 在应用序和正则序中我们都用到了的"替换", 也就是我们所说的"代换模型"

    关于如何求值({Add} 3 5)将在3.2.1中介绍,不过大体规则是这样的:
    如果要对表达式A求值,那么就需要
    1)对其各个子表达式a求值,我们假设对子表达a的求值过程写作Eval(a)
    2)将运算符子表达式的值b应用于运算对象只表达式的值, 写作 Apply (b)
    递归应用Eval(a)与 Apply (b)直到表达式化为“最简”(这里的最简对应普通开发人员而言,即由一些基本过程,基本数据,谓词等等组成。对解释器而言,可能还有更细的划分)
    在(+ 3 5)中,对"+"的求值结果是{Add},对 3与5的求值结果就是他们本身,所以将{Add}对应的指令应用于3  5,便计算出结果了。

    注:这是一篇读书笔记,所以其中的内容仅属个人理解而不代表SICP的观点,并随着理解的深入其中的内容可能会被修改
  • 相关阅读:
    【ST】lab01——Junit and Eclemma
    【SPM】hw1——个人房间装修
    【ST】hw2——find the error in the follow case
    【ST】Describe an error from my past projects
    ST homework4 --- 图覆盖
    ST lab1——Junit和覆盖测试的初探
    ST work12——failure,fault,error
    ST work1——印象最深的一个bug DJI 激活时报 SDK_ACTIVE_SDK_VERSION_ERROR
    C# note 06——delegate 和 event
    C# note 05——异常处理
  • 原文地址:https://www.cnblogs.com/zhouyinhui/p/1562180.html
Copyright © 2020-2023  润新知