3.1 幅值和局部状态

计算机程序的构造和解释(笔记)

chap3 模块化、对象和状态

章节说明
  • 松耦合思想:将程序的变化尽量在比较小的局部范围内

  • 两种策略:

    • 面向过程设计: 处理的是系统的信息流

    • 面向对象设计: 将系统看成一批对象,对象的行为可能随着时间的进展而变化

    • 面向对象设计必须抛弃代换模型(见chap1.1),使用环境模型
    • 如果有变发的话,流模式可以通过延时求值来松懈求值的顺序)(个人认为这里涉及设计模式的运行时依赖和编译时依赖,新手不是很懂(* ̄▽ ̄)y)
    3.1 幅值和局部状态

    这里说的是全局变量,幅值等。和C/C++不一样,Scheme中因为没有幅值= ,赋值反而变得另类有意思

    3.1.1 局部状态变量

对于一个取金额的过程

(withdraw 25)
75
(withdraw 25)
50
(withdraw 60)
"Insufficient funds"
(withdraw 15)
35
  • 全局环境变量

    可以自由地被任何过程检查或修改


 (define balance 100)  ;balance 为全局环境变量

 (define (withdraw amount)
    (if (>= balance amount)
        (begin (set! balance (- balance amount))
              balance)
        "Insufficient funds"))

其中:

在Scheme中,赋值是使用set!

语法为:

(set! ⟨name⟩ ⟨new-value⟩)
; <name> 为一个符号, <new-value>为任何表达式
; set 后面的!为一个命名习惯,意为改变变量值;类似谓词中的 ? 提醒

而对于

(begin ⟨exp1⟩ ⟨exp2⟩....⟨expk⟩)

则表示顺序求值,最后一个 <expk >表示返回的值

  • 局部环境变量

在这里应该将balance 改为局部变量比较好,因为金额只有这个过程才可以修改

(define new-withdraw
  (let ((balance 100))   ; banlance为局部变量
    (lambda (amount)
      (if (>= balance amount)
        (begin (set! balance (- balance amount)) balance)
        "Insufficient funds"))))

当然,这种效果,这里书上也提到了是 * 封装 *

3.1.2 引进赋值带来的好处

这里例子说的是一个随机数产生的过程,用的是蒙特卡罗方法

例子是为了说明一个现象:从一个复杂计算过程中一部分的观点看,其他部分都像是在随着时间的不断变化,它们因长期自己随时间变化的内部状态。

3.1.3 引进赋值带来的代价

我理解这里说的是类似做高中数学题的时候,方程化简和求解的区别吧

先说两个重要的基本概念

  • * 函数式程序设计 *:不用任何赋值的程序设计,如LISP

  • * 命令式程序设计*:广泛采用赋值的程序设计,如C/C++

这里书上说的主要是赋值会破坏“同一的东西可以相互替代的”-引用透明 的性质吧。

再说下其他的性质:

  • 同一: 两个事物可以相互替代,在代换模型中适应

  • 变化: 同一的另一面,适用于环境模型

命令式程序设计的缺陷:

也就是过程设计的程序的通病咯,注意逻辑的顺序性;

具体一点就是:带有赋值的程序将迫使人们去考虑赋值的相对顺序,以保证每个语句所用的是被修改变浓的正确版本。

PS: 这一点在并发会出现的问题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值