我正在使用著名的书籍《程序设计方法》。更具体地说,是第一版(我有实体书)。
在第6章中,有一些关于结构的练习题。其中一道题目需要模拟交通信号灯,并使用效果(变异)来改变它们。
我指的是关于函数next
的Exercise 6.2.5 练习,该函数应该给出下一个交通灯的颜色。
该书提供的答案是:
(start 50 160)
(draw-solid-disk (make-posn 25 30) 20 'red)
(draw-circle (make-posn 25 80) 20 'yellow)
(draw-circle (make-posn 25 130) 20 'green)
; -------------------------------------------------------------------------
;; clear-bulb : symbol -> true
;; to clear one of the traffic bulbs
(define (clear-bulb color)
(cond
[(symbol=? color 'red)
(and (clear-solid-disk (make-posn 25 30) 20)
(draw-circle (make-posn 25 30) 20 'red))]
[(symbol=? color 'yellow)
(and (clear-solid-disk (make-posn 25 80) 20)
(draw-circle (make-posn 25 80) 20 'yellow))]
[(symbol=? color 'green)
(and (clear-solid-disk (make-posn 25 130) 20)
(draw-circle (make-posn 25 130) 20 'green))]))
;; tests
(clear-bulb 'red)
; -------------------------------------------------------------------------
;; draw-bulb : symbol -> true
;; to draw a bulb on the traffic light
(define (draw-bulb color)
(cond
[(symbol=? color 'red)
(draw-solid-disk (make-posn 25 30) 20 'red)]
[(symbol=? color 'yellow)
(draw-solid-disk (make-posn 25 80) 20 'yellow)]
[(symbol=? color 'green)
(draw-solid-disk (make-posn 25 130) 20 'green)]))
;; tests
(draw-bulb 'green)
; -------------------------------------------------------------------------
;; switch : symbol symbol -> true
;; to switch the traffic light from one color to the next
(define (switch from to)
(and (clear-bulb from)
(draw-bulb to)))
;; tests
(switch 'green 'yellow)
(switch 'yellow 'red)
; -------------------------------------------------------------------------
;; next : symbol -> symbol
;; to switch a traffic light's current color and to return the next one
(define (next current-color)
(cond
[(and (symbol=? current-color 'red) (switch 'red 'green))
'green]
[(and (symbol=? current-color 'yellow) (switch 'yellow 'red))
'red]
[(and (symbol=? current-color 'green) (switch 'green 'yellow))
'yellow]))
(next 'red)
(next 'green)
(next 'yellow)
(next 'red)
在下一个函数中,我做了类似的事情,并在提供的测试中实现了相同的结果。
(define (next current-color)
(cond
[(symbol=? current-color 'red) (switch 'red 'green)]
[(symbol=? current-color 'yellow) (switch 'yellow 'red)]
[(symbol=? current-color 'green) (switch 'green 'yellow)]))
与书中的答案不同,我的代码没有使用
and
,也没有让一个松散的单个符号(例如'red)。
这种差异引起了我的兴趣,因为这本书在强调如何设计代码方面非常重要。令我感到困惑的是,原始解决方案使用了and(组合连续效果),似乎除了在每个条件语句结尾使用“孤独”的'red,'yellow或'green之外,没有必要。我不明白最后一个符号语句或and的目的。
是否有一些风格上或概念上的原因,采用这种看起来更冗长、不够清晰的方法?
我正在阅读这本书,以改善我编写代码的方式。
and
来序列化副作用的方式是一个缺陷,第二版通过改用更加函数式和灵活的 "universe" teachpack 来修复了这个问题。这是一个更加清晰的设计,我建议至少查看第二版,看看它是如何实现的。 - Ryan Culpepper