Использование «do» в схеме - PullRequest
5 голосов
/ 08 июля 2010

В чем разница между CODE SNIPPET 1 и CODE SNIPPET 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)).Есть ли различие?Спасибо!

Ответы [ 2 ]

11 голосов
/ 08 июля 2010

Общая структура формы do выглядит следующим образом:

(do ((<variable1> <init1> <step1>)
     ...)
    (<test> <expression> ...)
  <command> ...)

Перефразируя http://www.r6rs.org/final/html/r6rs-lib/r6rs-lib-Z-H-6.html#node_chap_5, каждая итерация начинается с оценки <test>, если она оценивается как истинное значение, <expression>s оцениваются слева направо и последнее значение, если результат формы do.Во втором примере = будет оцениваться как логическое значение true, тогда я буду оцениваться и, наконец, 5 будет возвращаемым значением формы.В первом случае (= i 5) является тестом, а форма do возвращает неопределенное значение.Обычный способ написания цикла будет выглядеть примерно так:

(do ((i 0 (+ i 1)))
    ((= i 5) i)      ; maybe return the last value of the iteration
  (display i))

Вам не нужна явная мутация переменной цикла, поскольку это обрабатывается выражением <step>.

6 голосов
/ 08 июля 2010

В первом случае ((= i 5)) выполняет функцию проверки завершения.Таким образом, цикл do повторяется до тех пор, пока i = 5.

Во втором случае (= i 5) не является тестом.Цикл do просто выполняет первую форму, которая возвращает 5 .

-

(согласно прилагаемым комментариям) скобки являются взаимозаменяемыми в некоторых диалектах схемы.Иногда считается идиоматичным использовать [] для параметров (то есть для родителя do ).

...