【SICP读书笔记(一)】正则序展开的特殊情况

scheme解释器有两种实现方式,一种是应用序,先对每个参数求值,再以首过程对所有求得的参数求值。

第二种是正则序,会“完全展开然后归约”(书中原文)

SICP中的练习1.5,让我困惑了一下。原题如下:

Ben Bitdiddle发明了一种检测方法,能够确定解释器究竟采用何种序求值,是采用应用序,还是采用正则序。他定义了下面两个过程:

(define (p) (p))

(define (test x y)
  (if (= x 0)
       0
       y))

而后他求值下面的表达式:

(test 0 (p))

问题:不同的求值序,结果会有不同吗?

我的想法:

应用序就不用说了,求解第二个参数的时候挂掉出不来。

问题是正则序,完全归约的话,也必须要去展开p啊?也一样没办法展开完啊?也会挂掉啊?

奇葩的是,正则序【不会】挂点,会输出0.

那是什么原因?

题目后面有个提示:

(无论采用正则序或者应用序,假定特殊形式的if的求值规则总是一样的。其中谓词部分先行求值,根据其结果确定随后求值的部分)

干,这意思就是,正则序第一次展开后,由于是if,所以就先就第一部分接着正则序展开了。

换言之,(正则(A,B))后,展开由于是(if A B),所以就先进行(if 正则(A) B),而不是先前想象的(if 正则(A) 正则(B))

而应用序由于首先必须对参数求值,没见到if的时候就死了

换言之,这是个死之前能不能见到if的问题

时间: 2024-08-28 06:01:58

【SICP读书笔记(一)】正则序展开的特殊情况的相关文章

SICP读书笔记(一)

第一章 构造过程抽象 计算过程是存在于计算机里的一类抽象事物,它在演化过程中会去操作一些被称为数据的抽象事物.我们通过创建被称为程序的规则模式来指导这类过程的进行.程序由程序设计语言编排而成. 我们将要使用Lisp表达过程性的思想,它是今天还在广泛使用的历史第二悠久的语言,本书将使用Lisp的一个方言,Scheme.我们之所以选择Lisp,是因为它有许多独特的特征,其中最重要的是:计算过程的Lisp描述本身又可以作为Lisp的数据来表示和操作. 1.1 程序设计的基本元素 为了能让我们通过程序语

SICP读书笔记(三)

1.3 用高阶函数做抽象 人们对功能强大的程序语言设计有一个要求,就是能为公共的模式命名,建立抽象,而后在抽象的层次上工作.我们需要构造以过程为参数或返回值的过程. 1.3.1 过程作为参数 我们考虑计算一个函数term从a到b的和的过程: (define(sum term a next b) (if (> a b) 0 (+ (term a) (sum term (next a) b)))) 我们可以利用这个过程求立方和,或者计算定积分等,下面是计算定积分的代码: (define (integ

【SICP读书笔记(四)】练习2.27 --- 表序列reverse的扩展:树结构的deep-reverse

题目要求是,修改练习2.18所做的reverse过程,得到一个deep-reverse过程.它以一个表为参数,返回另一个表作为值,结果表中的元素反转过来,其中的子树也反转. 例如: (define x (list (list 1 2) (list 3 4))) x ((1 2) (3 4)) (reverse x) ((3 4) (1 2)) (deep-reverse x) ((4 3) (2 1)) 方法也挺简单,思路跟reverse过程一样,用一个辅助的过程来完成任务,辅助过程带有一个空表

【SICP读书笔记(三)】练习2.18 --- 表序列的reverse方法

来自练习2.18 请定义出过程reverse,它以一个表为参数,返回的表中所包含的元素与参数表相同,但排列顺序与参数表相反: (reverse (list 1 4 9 16 25)) (25 16 9 4 1) 有几个难点: 0.不能采用(cons (reverse (cdr lst) ) (car lst))的方式.在cons过程中,如果表参数在前,那么出来的就是嵌套表而不是单独的表. 1.不能采用之前实现的append过程,例如(append (reverse (cdr lst)) (car

【SICP读书笔记(二)】使用过程来黏合数据 —— 酷炫吊的消息传递机制

首先,让我们来看几个内建函数 (cons x y),作用是把x和y绑定成一个序对 (car z),作用是提取z序对的第一个元素 (cdr z),作用是提取z序对的第二个元素 容易看出,这个东西有点类似OO语言里的类,car和cdr是get方法,x和y是成员变量. 但是,但是! 函数式的编程方式,居然可以利用过程来实现这三个函数!实在是不可思议 下面具体看看实现的过程 (define (cons x y) (lambda (m) (m x y))) (define (car z) (z (lamb

深入JVM读书笔记(二)——OOM各种情况

Java虚拟机内存有好几个运行时数据区会有OOM的异常,如果能够区分根据报错区分出是哪些区域报出来的异常,会更便于定位问题,解决问题. 1.Java堆溢出 原因:由于不断创建对象实例,当对象数量达到了最大堆的容量限制后产生内存溢出异常. 现象:java.lang.OutOfMemoryError: Java heap space 解决方法: 1)首先确认是内存泄露(Memory Leak)还是内存溢出(Memory Overflow): 2)如果是内存泄漏引起的,查看GC Roots引用链,找出

《Effective C++》读书笔记汇总

我之前边读<Effective C++>边写下每个条款的读书笔记,这一版是C++11之前的版本.这里我将每个条款令我印象深刻的点小结一下. 1.C++包括:Plain C(面向过程).OOP(面向对象).模板(泛型和模板元编程).STL(C++标准库). 2.用inline.enum.const代替#define.#define定义的宏,一旦复杂起来,高手都很难掌控.不要带入C的习惯. 3.灵活使用const前缀.不需要进行改变的数据加上const前缀.指针的const前缀有两种形式,cons

【转】《windows核心编程》读书笔记

这篇笔记是我在读<Windows核心编程>第5版时做的记录和总结(部分章节是第4版的书),没有摘抄原句,包含了很多我个人的思考和对实现的推断,因此不少条款和Windows实际机制可能有出入,但应该是合理的.开头几章由于我追求简洁,往往是很多单独的字句,后面的内容更为连贯. 海量细节. 第1章    错误处理 1.         GetLastError返回的是最后的错误码,即更早的错误码可能被覆盖. 2.         GetLastError可能用于描述成功的原因(CreatEvent)

C#刨根究底:《你必须知道的.NET》读书笔记系列

一.此书到底何方神圣? <你必须知道的.NET>来自于微软MVP-王涛(网名:AnyTao,博客园大牛之一,其博客地址为:http://anytao.cnblogs.com/)的最新技术心得和感悟,将技术问题以生动易懂的语言展开,层层深入,以例说理.全书主要,包括了.NET基础知识及其深度分析,以.NET Framework和CLR研究为核心展开.NET本质论述,涵盖了.NET基本知识几乎所有的重点内容.全书分为5个部分,第1部分讲述.NET与面向对象,从底层实现角度分析了.NET如何实现面向