Program Structure 笔记2 (求值模型)

Program Structure 笔记2 (求值模型)

  (作者:colinboy  Email:cybbh@163.com) 2008.4.30  V2

(内容难免出现错误或一些专业词汇使用不当,只是个人笔记,能理解总体内容就好)

 

计算机程序设计非常简单,很多10岁小孩都能设计程序,但这仅仅限于程序规模非常小的时候,这门课程不是讲授如何使用一门特定的语言,也不是说服你相信scheme是最好的程序设计语言.

 

计算机抽象层次结构

------------------------------

  应用程序

------------------------------

  高级程序设计语言 (scheme)

------------------------------

  低级程序设计语言 (C)

------------------------------

  机器语言 (binary bits)

------------------------------

  电路单元 ()

------------------------------

  晶体管

------------------------------

 

define (argue s)

  (if (empty? s)

      '()

      (sentence (opposite (first s))

         (argue (bf s)))))

 

(define (opposite w)

  (cond ((equal? w 'like) 'hate)

        ((equal? w 'hate) 'like)

        ((equal? w 'wonderful) 'terrible)

        ((equal? w 'terrible) 'wonderful)

        ((equal? w 'great) 'awful)

        ((equal? w 'awful) 'great)

        ((equal? w 'terrific) 'yucky)

        ((equal? w 'yucky) 'terrific)

        (else w) ))

 

在上面程序中,存在一个递归调用(recursive call),argue函数中, argue又调用argue来完成操作.

 

(cond )操作是一种特殊形式(special form),其他的特殊形式还有(if ) (define ),它们不根据一般性的求值规则去计算每个参数的值.

 

形式(form)的意思可以等同与表达式(expression)

所以"特殊形式"是一种"特殊的表达式"!!!

 

2种求值规则: 应用序(applicative order) 和 正则序(normal order)

 

应用序的规则为:

1.计算每个实际参数表达式.

2.根据计算出来的实际表达式的值,调用函数.

 

正则序的规则为:

1.根据实际参数表达式调用函数,而不计算表达式.

2.如果函数为一个scheme原始内置函数(例如 + -),那么就先计算每个实际参数表达式的值,根据计算出来的值进行调用.

 

例如以下函数:

(define (g x) (* 3 x))   --> 定义函数g

(define (f a b) (+ (g a) b))  -->定义函数f

 

如果我们执行(f (+ 2 3) (- 15 6))

应用序的计算过程如下:

1.      计算(+ 2 3)(- 15 6),返回值分别为5,9

2.      根据计算的表达式值59调用(f 5 9)

3.      (f 5 9)  -->  (+ (g 5) 9)

4.      计算(g 5)  --->  (* 3 5)  -->  15

5.      计算 (+ 15 9)  -->  24

6.      运算结果为24

 

正则序的计算过程如下:

1.      根据表达式调用f,转换为(+ (g (+ 2 3)) (- 15 6))

2.      上式中+为原始内置函数,所以需要计算每个表达式的值,计算(g (+ 2 3),g不为原始类型,所以(g 5)转换为(* 3 5)  -->  15

3.      计算(- 15 6) -->  9

4.      计算(+ 15 9) --> 24

5.      运算结果为24

 

根据以上结果,发现不论是使用应用序求值还是用正则序求值,对于上述(f (+ 2 3) (- 15 6))运算结果都是一样的. 但是对于任何函数调用,结果都会一样吗??

 

什么是函数式程序设计?

函数是一个过程(procedure),每次我们使用相同的实际参数调用此函数的时候,它总会返回相同的值.

 

函数式程序设计应该避免依赖2种求值规则!

 

如果我们定义一个过程(random x),他会随机返回一个从0 x之间的值.

(random 10)  -->  5

(random 10)  -->  3

(random 10)  -->  8

 

每次我们使用相同的参数调用random,它可能会返回不同的结果,那么random是一个函数么??  ,在函数式程序设计中当然不是!!! 那么如果我们在程序中使用了random过程,我们的程序设计将会依赖求值规则,这将不是函数式程序设计.

 

例如下面的函数:

(define (zero x) (- x x))

 

如果我们执行(zero (random 10))

 

使用应用序求值规则结果为0

但是使用正则序求值规则结果可能不为0,为什么呢??原因如下:

 

应用序求值过程:

1.      计算表达式(random 10),假设返回5.

2.      根据表达式值调用zero函数, (zero 5),

3.      计算(zero 5)  -->  (- 5 5)  -->  0

 

正则序求值过程:

1.      根据表达式调用zero.

2.      转换为(- (random 10) (random 10)),假设第一个random返回9,第二个random返回6,那么结果为3.

 

如果我们使用函数式程序设计,那么我们不需要关心程序的执行顺序以及所使用的求值规则.

如果不遵守函数式程序设计规则,那么我们需要小心,因为很可能会出现上面例子中的情况.

 

 

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值