Упражнение 3.8.
Когда в разделе 1.1.3 мы определяли модель вычислений, мы сказали, что первым шагом при вычислении выражения является вычисление его подвыражений. Однако мы нигде не указали порядок, в котором проходит вычисление подвыражений (слева направо или справа налево). Когда мы вводим присваивание, порядок, в котором вычисляются аргументы процедуры, может повлиять на результат. Определите простую процедуру f, так, чтобы вычисление (+ (f 0) (f 1)) возвращало 0, если аргументы + вычисляются слева направо, и 1, если они вычисляются справа налево.
Вопрос может показаться не существенным, но в таком языке как С++ порядок вызова для такого случая не определен и программа (теоретически) может вести себе по разному от выполнения к выполнении. После этого упражнения мы должны сделать вывод что писать программы зависящие от описываемого порядко не хорошо) Приступим к выполнению
Определим функцию, которая при нечетных вызовах (первый, третий и тд раз) возвращает параметр, а при четных (второй, четвертый и тд) возвращает 0. Это можно сделать множеством способов. Вот один из них
(define f
(let ((trigger false))
(λ (a)
(set! trigger (not trigger))
(if trigger a 0))))
Проводим эксперимент
(+ (f 0) (f 1)) ;0
Как видим, аргументы вычисляются слева направо.
Можно обобщить это наблюдение для большего количества аргументов
(define f
(let ((counter 0))
(λ (a)
(set! counter (+ counter 1))
counter)))
(define (foo first . rest)
(cons first rest))
(foo (f 100) (f 100) (f 100) (f 100) (f 100) (f 100) (f 100) (f 100))
где возвращает какой раз ее вызывают
Комментариев нет:
Отправить комментарий