Я использую известную книгу Как разрабатывать программы. Точнее, первое издание (у меня есть физическое).
В 6-й главе есть несколько упражнений с Структурами. В одном из них нужно имитировать светофоры и использовать эффекты (мутации) для их изменения.
Я имею в виду упражнение упражнение 6.2. 5 о функции next
, которая должна дать вам следующий цвет светофора.
Лист ответов, представленный в книге:
(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
и не пропускает ни одного символа (например, «красный»).
Это отличие меня заинтриговало, поскольку в книге упор делается на то, чтобы научить вас разрабатывать код. Меня заинтриговал тот факт, что в исходном решении используется и (для объединения последующих эффектов), что кажется ненужным, кроме использования одиноких «красного», «желтого» или «зеленого» в конце каждого условное заявление.
Я не понимаю цели этого последнего утверждения символа или оператора and.
Есть ли какая-то стилистическая или концептуальная причина для такого подхода, который кажется более многословным и менее ясным?
Я читаю эту книгу именно для того, чтобы улучшить свой способ написания кода.
and
для последовательности побочных эффектов является недостатком, который во втором издании исправлен путем перехода на более функциональный и более гибкий пакет обучения вселенной. Это гораздо более чистый дизайн, и я рекомендую хотя бы взглянуть на второе издание, чтобы увидеть, как это сделано там. - person Ryan Culpepper   schedule 31.03.2021