2015-11-16 3 views
0

я определяю новую версию if:Какая разница между двумя выражениями в схеме?

(define (new-if predicate then-clause else-clause) 
    (cond (predicate then-clause) 
    (else else-clause))) 

Затем я использую его в следующем виде:

(define (sqrt-iter guess x) 
    (new-if (good-enough? guess x) 
    guess 
    (sqrt-iter (improve guess x) 
      x))) 

Я понимаю, что с else-clause передается new-if в sqrt-iter процедуре всегда оценивается, sqrt-iter никогда не перестает делать рекурсивные призывы к себе.

Но я не понимаю, почему мы не останавливаемся, когда good-enough? возвращается true =>guess

+1

Потому что 'sqrt-iter' никогда не перестает делать рекурсивные вызовы самому себе? –

+0

Но когда мы оцениваем, что 'good-enough?' Возвращает 'true', почему мы не останавливаемся? – Anatoly

+0

В схеме 'if' является специальной формой, что означает, что она не оценивает все ее аргументы. Нормальные формы оценивают все аргументы перед выполнением процедуры. Другие специальные формы: 'define'' cond'' или 'и' and'. Прежде чем интерпретатор вызовет 'new-if', он попытается оценить все его аргументы, одним из которых является рекурсивный вызов. Отсюда бесконечный цикл. – WorBlux

ответ

5

Ваш new-if процедура. Аргументы процедуры оцениваются перед передачей в процедуру. Поэтому ваш рекурсивный вызов sqrt-iter будет полностью оценен до вызова new-if. Как прокомментировал Роберт Харви, это приводит к бесконечной рекурсии.

Ваш new-if должен быть макросом для правильной работы. Что-то вроде:

(define-syntax new-if 
    (syntax-rules() 
    ((_ predicate then-clause else-clause) 
    (cond (predicate then-clause) 
      (else else-clause))))) 
Смежные вопросы