LINUX.ORG.RU

Не могу понять одну хрень с if в упражнении из SICP

 ,


0

1

Вот недавно была тема про if в упражнении с тестом порядка вычисления интерпретатора. На этот вопрос я бы ответил, мол, if - особая форма, если из предиката следует одна из «логических ветвей» (пардон за мой французский), то будет вычисляться именно она, другие «ветви» вычисляться не будут. Я пришёл к такому выводу после упражнения 1.6, про то, что если мы определим свой собственный new-if как простую комбинацию, то у нас может получиться, что программа циклится из-за того, что наш new-if пытается вычислить все «ветви».

ОК, пускай.

Вот например у меня DrRacket. Пишу в нём код упражнения 1.5

(define (p) (p))
(define (test x y)
(if (= x 0)
    0
    y))

(test 0 (p))

Программа зациклится из-за того, что интерпретатор использует аппликативный порядок вычисления, то есть делает все вычисления при подстановке сразу, натыкается на (p) и циклится... Но стоп! Это ведь противоречит тому, что if - особая форма, если попали в одну «ветвь», то другую вычислять не нужно.

Можете объяснить?



Последнее исправление: mentalmenza (всего исправлений: 2)

Противоречия нет. До if дела не доходит просто.

(if (= 0 0)
    0
    (p))

В этом случае будет так, как ты сказал, так как особая форма.

aptyp ★★★★
()

Параметры передаются в функцию, при этом они вычисляются слева направо. Только после этого вычисляется значение формы if. Т.е. в теле функции test параметры функции уже должны быть вычислены. Но т.к. p зацикливается, до вычисления if дело просто не доходит.

theNamelessOne ★★★★★
()

До if-а дело не доходит, интерпретатор перед применением процедуры test вычисляет все её аргументы (это и есть аппликативный порядок) и зацикливается он именно тут, пытаясь вычислить (p).

Begemoth ★★★★★
()
Ответ на: комментарий от theNamelessOne

Но т.к. p зацикливается, до вычисления if дело просто не доходит.

Если быть точным, то даже вызова функции test не происходит.

theNamelessOne ★★★★★
()

Всё стало ясно, всем большое спасибо)

mentalmenza
() автор топика

Сначала ты говоришь об аппликативном порядке, а потом делаешь вывод, соответствующий нормальному порядку. В отличие от if, test — не особая форма, а самая обыкновенная функция.

buddhist ★★★★★
()
Ответ на: комментарий от buddhist

Сначала ты говоришь об аппликативном порядке, а потом делаешь вывод, соответствующий нормальному порядку.

Не понял. Нормальный порядок вычисления - когда вычисление значения комбинации не требуется до момента использования, т.е. максимально откладывается. Если бы у нас был нормальный порядок вычисления, то есть в случае выше приведённого кода, в функцию test приходят два параметра - 0 (и есть ноль) и (p). Значение (p) в if вычислять не нужно, так как x = 0 и мы попадаем в «ветвь» 0. Следовательно с нормальным порядком вычисления интерпретатор выдаст 0. А в случае аппликативного порядка «делает все вычисления при подстановке сразу, натыкается на (p) [имелось в виду в момент вызова функции] и циклится». Что не так?

В отличие от if, test — не особая форма, а самая обыкновенная функция.

Я раньше не знал, что значение параметра в случае если это комбинация будет вычисляться в момент вызова функции, если ты об этом.

mentalmenza
() автор топика
Ответ на: комментарий от mentalmenza

Что не так?

Но в ОП-то ты рассуждал так, будто у нас при вызове test будет нормальный порядок, то есть, будто test - это макрос.

buddhist ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.