when
- это один вооруженный ifs с неявным begin
. Следующие примеры одинаковы:
(if (any odd? lst)
(begin
(set! some-binding #t)
(display "Found an odd element")))
(when (any odd? lst)
(set! some-binding #t)
(display "Found an odd element"))
И вы можете использовать unless
вместо not
в предикате:
(if (not (any odd? lst))
(set! some-binding #f))
(unless (any odd? lst)
(set! some-binding #f))
Питер Норвиг написал хорошую книгу о стиле Лиспа и в ней он обращается к этому:
Будьте точны, как это требуется в абстракциях данных, но не более.
- если для выражения с двумя ветвями
- когда, за исключением оператора с одной веткой
- и, или только для логических значений
- cond для многоотраслевого оператора или выражения
Так что, хотя вы можете написать всю свою логику, используя if
, это будет не самый простой код для чтения. Другие могут использовать термин принцип наименьшего удивления . Несмотря на то, что книга предназначена для Common Lisp, большая ее часть может быть использована и в Scheme. Это хорошее чтение, если вы хотите профессионально программировать любой диалект lisp.
Для when
и unless
это гораздо лучше применимо к Scheme, так как вы не представляете, что реализация может вернуть в случае, если предикат оценивается как #f
, тогда как в CL вы можете злоупотреблять when
, поскольку он предназначен вернуть nil
в таких случаях.
В своем коде вы пытаетесь что-то вернуть и позволяете реализации выбирать, что должно произойти, когда предикат завершается ошибкой, и это вызывает #<void>
. Когда возвращение имеет значение, вы всегда должны использовать два вооруженных if
:
(if test-expression
then-expression
else-expression)
Обратите внимание, что ключевое слово else
отсутствует.