Каково различие между ФРАГМЕНТОМ КОДА 1 и ФРАГМЕНТОМ КОДА 2?
;CODE SNIPPET 1
(define i 0)
(do ()
((= i 5)) ; Two sets of parentheses
(display i)
(set! i (+ i 1)))
;CODE SNIPPET 2
(define i 0)
(do ()
(= i 5) ; One set of parentheses
(display i)
(set! i (+ i 1)))
Первый фрагмент кода производит 01234 и вторые продукты 5. Что продолжается? Что делает дополнительный набор круглых скобок, делают? Кроме того, я видел [(= i 50)]
используемый вместо ((= i 5))
. Существует ли различие?Спасибо!
В первом случае ((= i 5)) функционирует как проверка завершения. Таким образом, цикл do повторяется до тех пор, пока i = 5.
Во втором случае (= i 5) не является тестом. Цикл do просто выполняет первую форму, которая возвращает 5 .
-
(Согласно приложенным комментариям) скобки взаимозаменяемы в некоторых диалектах схемы. Иногда считается идиоматическим использовать [] для параметров (например, для родительского do ).
Общая структура формы do следующая:
(do ((<variable1> <init1> <step1>)
...)
(<test> <expression> ...)
<command> ...)
Перефразирование http://www.r6rs.org/final/html/r6rs-lib/r6rs-lib- ZH-6.html # node_chap_5 , каждая итерация начинается с вычисления
, если это истинное значение,
s оцениваются слева направо и последнее значение возвращается как результат формы do
. Во втором примере =
будет оцениваться как логическое значение, означающее истину, затем будет оцениваться i и, наконец, 5 - это возвращаемое значение формы. В первом случае (= i 5)
- это тест, а форма do
возвращает неопределенное значение. Обычный способ написания цикла выглядел бы примерно так:
(do ((i 0 (+ i 1)))
((= i 5) i) ; maybe return the last value of the iteration
(display i))
Вам не нужно явное изменение переменной цикла, так как это обрабатывается выражением
.