计算机程序的构造与解释作业:练习1.1到1.5

本文介绍了使用Java实现的Scheme解释器Kawa,并探讨了计算机程序构造中的基本逻辑。通过实例解析1.3节内容,展示了如何在三个数中找到最小值并进行相应计算,为理解函数式编程语言的思维提供了帮助。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.1,我用的是kawa,这是用java实现的一个scheme的解释器,kawa(在window下直接双击打开就可以运行)

#|kawa:1|# 10
10
#|kawa:2|# (+ 5 3 4)
12
#|kawa:3|# (- 9 1)
8
#|kawa:4|# (/ 6 2)
3
#|kawa:5|# (+ (* 2 4) (- 4 6))
6
#|kawa:6|# (define a 3)
#|kawa:7|# (define b (+ a 1))
#|kawa:8|# (+ a b (* a b))
19
#|kawa:9|# (= a b)
#f
#|kawa:10|# ((if (and (> b a) (< b (* a b)))
#|(---:11|# b a)
#|(---:12|# 
#|(---:13|# ((if (and (> b a) (< b (* a b)))
#|(---:14|# b a)
#|(---:15|# (if (and (> b a) (< b (* a b)))
#|(---:16|# 
#|(---:18|# (if (and (> b a) (< b (* a b))) b a)
#|(---:19|# (if (and (> b a) (< b (* a b))) b a)
#|(---:20|# a
#|(---:21|# b
#|(---:22|# a
#|(---:23|# )
#|(---:24|# ))
/dev/stdin:24:3: An unexpected close paren was read.
#|kawa:25|# a
3
#|kawa:26|# b
4
#|kawa:27|# (if (and (> b a) (< b (* a b))) b a)
4
#|kawa:28|# (cond ((= a 4) 6)
#|(---:29|# ((= b 4) (+ 6 7 a))
#|(---:30|# (else 25))
16
#|kawa:39|# (+ 2 (if (> b a) b a))
6
#|kawa:40|# (* (cond ((> a b) a)
#|(---:41|# ((< a b) b)
#|(---:42|# (else -1))
#|(---:43|# (+ a 1))
16



1.2 最简单的可以看到分号看做一个中点,把这个表达式变换成
(/ (5+4+(2-(3-(6+4/5)))) 3(6-2)(2-7))

接下来就每次把这个表达式分成两份
(/ (+ (5+4) (2-(3-(6+4/5))))
	(* 3 (6-2) (2-7)))

next:
(/ (+ (+ 5 4) (- 2 (3-(6+4/5))))
	(* 3 (- 6 2) (- 2 7)))

next:
(/ (+ (+ 5 4) (- 2 (- 3 (+ 6 (/ 4 5)))))
	(* 3 (- 6 2) (- 2 7)))

执行后的值是:
#|kawa:44|# (/ (+ (+ 5 4) (- 2 (- 3 (+ 6 (/ 4 5)))))
#|(---:45|# 	(* 3 (- 6 2) (- 2 7)))
-37/150
#|kawa:46|# 


1.3 这个过程的逻辑就是:在三个数中,随便拿出来一个数x。那么,这个数只有两种结果:是最小的那一个或者是最大的两个数里面的一个。如果他是最小的那一个,那么就把其他的两个数求和;如果不是,那么就取出剩下的两个数里面的大者求和。

(define (max-of-two x y) (if (< x y) y x))
(define (sum-of-bigger-two x y z)
	(if (< x y) (+ y (max-of-two x z)) (+ x (max-of-two y z))))
结果
#|kawa:49|# (define (max-of-two x y) (if (< x y) y x))
#|kawa:50|#(max-of-two 10 10)
10
#|kawa:51|#(max-of-two 10 1)
10
#|kawa:52|# (max-of-two 1 10)
10
#|kawa:53|# (define (sum-of-bigger-two x y z)
#|(---:54|# 	(if (< x y) (+ y (max-of-two x z)) (+ x (sum-of-bigger-two y z))))
/dev/stdin:54:42: call to 'sum-of-bigger-two' has too few arguments (2; must be 3)
#|kawa:55|# (define (sum-of-bigger-two x y z)
#|(---:56|# 	(if (< x y) (+ y (max-of-two x z)) (+ x (sum-of-two y z))))
/dev/stdin:56:42: warning - no declaration seen for sum-of-two
#|kawa:57|# (define (sum-of-bigger-two x y z)
#|(---:58|# 	(if (< x y) (+ y (max-of-two x z)) (+ x (max-of-two y z))))
#|kawa:59|# (sum-of-bigger-two 10 12 1)
22
#|kawa:61|# (sum-of-bigger-two 10 10 1)
20

1.5

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

使用表达式(test 0 (p))

如果使用的是应用序求值,那么就是说一个值会在过程被调用之前计算。如果是这样,那么在调用的时候要先计算过程p的值,但是p是一个未定的值,因此会出现异常。
看下面,在kawa中果然如此:
#|kawa:73|# (define (p) (p))
#|kawa:74|# (define (test x y)
#|(---:75|# 	(if (= x 0)
#|(---:76|# 		0
#|(---:77|# 		y))
#|kawa:78|#(test 0 10)
0
#|kawa:79|# (test 1 10)
10
#|kawa:80|# (test 0 (p))
....(嘿嘿,直接卡死)
另一方面,如果使用的是正则序求值,那么直到过程真正被使用的时候才会出现异常。但是在这个测试过程中,根据if的执行的规则:如果x=0,那么会直接返回0;根本不会用到y,也就不会出现异常。


另外要提一下,我接触的所有的编程语言中,貌似用的都是应用序求值。






评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值