为什么《如何设计程序》一书在他们的回答中选择了这种方法 sheet?

Why does the book How to Design Programs chose this approach on their answer sheet?

我正在使用名著如何设计程序。更具体地说,第一版(我有实体版)。

在第六章中,有一些结构的习题。其中之一,你需要模拟红绿灯并使用效果(突变)来改变它们。

我指的是 exercise 关于函数 next 的练习 6.2.5,它假设为您提供交通灯的下一种颜色.

书上提供的答案sheet是:

(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 的目的。

是否有某种风格上或概念上的原因使这种方法看起来更冗长且不太清晰?

我读这本书正是为了提高我编写代码的方式。

Racket是Scheme的一种,是expression-oriented language。这意味着复合表达式中的最后一个表达式是整个表达式的 value.

这包括一个引号。它的值,符号,就是返回值。

函数调用(next current-color)切换交通灯的颜色和returns指示交通灯新颜色的符号:

;; next : symbol -> symbol

您的代码切换颜色 returns true(根据 switch 的规范):

;; switch : symbol symbol -> true
;; your-next : symbol -> true

这改变了函数 next 的使用方式。通过本书的设计我们可以写

....
   (let loop ( ... )
       .....
       (let ((current-color (next current-color)))
           ......
           ))
....

在您的设计中,这种自然的循环代码风格是不可能的。

A general 备注:这些规范称为类型,我们让类型指导我们在代码中使用函数。它们帮助我们了解什么进什么出,所以我们可以 连接匹配的电线, 可以这么说。