文档章节

【SICP归纳】6 副作用与环境模型

NoMasp
 NoMasp
发布于 2015/09/08 21:48
字数 1405
阅读 3
收藏 0

虽说叫做副作用显得不太好听,但在Lisp中副作用还是非常重要的。而相对于所有状态都必须显式地操作和传递额外参数的方式,如果引进赋值和将状态隐藏在局部变量中,那么就可以用更加模块化的方式来构造系统。

正如你所知道的,不用任何赋值的程序设计称为函数式程序设计。相反,广泛采用赋值的程序设计称为命令式程序设计。在C等命令式程序设计语言中,我们往往都要仔细考虑变量赋值的顺序,尤其是在循环中,但在函数式程序设计中这类问题根本不会出现。

(define x 1)
(define (add-x y) (set! x (1+ x)) (+ x y))
(add-x 3)
5
(add-x 3)
6

在这里我们看到同一个表达式却会导致两种不同的结果,而这一切都取决于时间。

我们常用define来定义一个为定义的变量、函数等等,而不用其来做修改的操作。set!则来完成修改这一工作。经常用到的let实际上是一个过程调用的语法糖衣。用define定义一个符号,也就是在当前环境框架里建立一个约束,并赋予这个符号指定的值。

(let ((var1 e1) (var2 e2))
  e3)=>
((lambda (var1 var2)
        e3)
 e1
 e2)

在前面的代换模型中,我们是这样求组合式的:
1)求值该组合式的各个子表达式
2)将作为最左子表达式(运算符)的值的那个过程应用于相应的实际参数,所谓实际参数也就是其他子表达式(运算对象)的值。
而在环境模型中,第二步就有所差异了:
1)求值该组合式的各个子表达式
2)将运算符子表达式的值应用于运算对象子表达式的值。

在将一个过程应用于一组实际参数时,将会建立起一个新环境,其中包含了将所有形式参数约束与对应的实际参数的框架,该框架的外围环境就是所用的那个过程的环境。

书中这部分可谓归纳的非常好,过程应用的环境模型的两条规则:
1)将一个过程对象应用于一集实际参数,将构造出一个新框架,其中将过程的形式参数约束到调用时的实际参数,而后在构造起的这一新环境的上下文中求值过程体。这个新框架的外围环境就是作为被应用的那个过程对象的一部分的环境。
2)相对于一个给定环境求值一个lambda表达式,将创建起一个过程对象,这个过程对象是一个序对,由该lambda表达式的正文和一个指向环境的指针组成,这一指针指向的就是创建这个过程对象时的环境。

现在我们已经有能力去使用独立的本地状态和对象模型,也会进行一些比较复杂的编程。我们活在物理世界中,也以物理世界的方式去思考,这正是由这些构成了整个世界。为什么物理学家、天文学家等在寻找系外生命时要以地球的指数为参照,比如说温度、大气、土壤、公转和自转等,因为有些事物是共通的。之前看到过一个老外写的书,当时对软件这个专业还没有多少认识,书也全是理论比较晦涩因此没能看多久,不过记得作者的一个比喻非常好。其认为写一个软件就像设计一座建筑,每部分有组织的组合拼凑在一起。

《计算机程序的构造和解释》虽然已经有了三十多年的历史,却依旧格外而不落伍的原因便是其是在讲解如何去构建一座建筑。它会告诉我们建筑的每个部分都有哪些功能和优缺点,这个柱子该放在哪里撑着,两层楼之间该怎样结合等等。而各自语言就像修建这个建筑的各种材料,比如钢铁和木材等。其并没有太注意去讲解语言的语法,一来这是介绍“建筑材料”的书籍需要做的,二来Lisp的语法也不太繁杂。

在我们的脑海中有对这个世界的认识以及一个不断构建中的模型,当我们在编写软件时,这些模型也即体现于计算机中。我们想要做的无非就是让这两者之间进行通信。这就带来了模块化,如果我们真的相信世界就是由这样的小片段所组成,那么我们也同样可以将这种思想应用于我们所构造的模型中,世界上的这些事物也将能够继承这种模块化设计进入我们的程序之中。



感谢访问,希望对您有所帮助。 欢迎关注或收藏、评论或点赞。


为使本文得到斧正和提问,转载请注明出处:
http://blog.csdn.net/nomasp


版权声明:本文为 NoMasp柯于旺 原创文章,未经许可严禁转载!欢迎访问我的博客:http://blog.csdn.net/nomasp

本文转载自:http://blog.csdn.net/nomasp/article/details/44699249

NoMasp
粉丝 7
博文 334
码字总数 0
作品 0
镇江
程序员
私信 提问
nomasp 博客导读:Lisp/Emacs、Algorithm、Android

版权声明:转载请联系本人,感谢配合!本站地址:http://blog.csdn.net/nomasp https://blog.csdn.net/NoMasp/article/details/44966625 Profile Introduction to Blog 您能看到这篇博客导读...

nomasp
2015/09/17
0
0
C语言 side effect和sequence point

C 语言中副作用(side effect):是指对数据对象或者文件的修改。例如,语句 var = 99; 的副作用是把 var 的值修改成 99。对表达式求值也可能产生副作用,例如,对表达式求se = 100; 求值所产...

rgds
2015/08/11
64
0
单元测试的重要性

单元测试,或者更大一些的自动化测试,对提高软件质量是有很大帮助的。通过一系列预先设计的规则,就可以覆盖大量的测试点。尤其是对重构一类的任务,确保修改前后系统行为不变很重要,而修改...

白一客
2017/06/16
203
1
Ruby的函数式编程:Part 1

Ruby是一种有趣的语言,因为它支持使用多重的范式。其中之一是“函数式范式”。 函数式语言的特点 使用函数式的语言风格意味着您可以使用几个主要的特征(以下这几条翻译的不太准确,请参考百...

jerrytao
2013/01/23
2.5K
3
webpack4 sideEffects实战轻松搞懂

sideEffects 译作副作用 函数副作用是指函数在正常工作任务之外对外部环境所施加的影响。具体地说,函数副作用是指函数被调用,完成了函数既定的计算任务,但同时因为访问了外部数据,尤其是...

高大师
05/20
0
0

没有更多内容

加载失败,请刷新页面

加载更多

OpenStack 简介和几种安装方式总结

OpenStack :是一个由NASA和Rackspace合作研发并发起的,以Apache许可证授权的自由软件和开放源代码项目。项目目标是提供实施简单、可大规模扩展、丰富、标准统一的云计算管理平台。OpenSta...

小海bug
昨天
6
0
DDD(五)

1、引言 之前学习了解了DDD中实体这一概念,那么接下来需要了解的就是值对象、唯一标识。值对象,值就是数字1、2、3,字符串“1”,“2”,“3”,值时对象的特征,对象是一个事物的具体描述...

MrYuZixian
昨天
6
0
数据库中间件MyCat

什么是MyCat? 查看官网的介绍是这样说的 一个彻底开源的,面向企业应用开发的大数据库集群 支持事务、ACID、可以替代MySQL的加强版数据库 一个可以视为MySQL集群的企业级数据库,用来替代昂贵...

沉浮_
昨天
6
0
解决Mac下VSCode打开zsh乱码

1.乱码问题 iTerm2终端使用Zsh,并且配置Zsh主题,该主题主题需要安装字体来支持箭头效果,在iTerm2中设置这个字体,但是VSCode里这个箭头还是显示乱码。 iTerm2展示如下: VSCode展示如下: 2...

HelloDeveloper
昨天
7
0
常用物流快递单号查询接口种类及对接方法

目前快递查询接口有两种方式可以对接,一是和顺丰、圆通、中通、天天、韵达、德邦这些快递公司一一对接接口,二是和快递鸟这样第三方集成接口一次性对接多家常用快递。第一种耗费时间长,但是...

程序的小猿
昨天
10
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部