Повторение дано в императивной форме. Например, в Common Lisp мы могли бы использовать параллельное присваивание в теле цикла:
(psetf a (+ a b)
b a)
Чтобы уменьшить путаницу, мы должны подумать об этом функционально и дать старое и новоепеременные с разными именами:
a = a '+ b'
b = a '
Это уже не присвоение, а пара равенств;мы оправданы в использовании обычного математического оператора « = » вместо стрелки присваивания.
Линейная рекурсия делает это неявно, потому что избегает присваивания. Значение выражения (+ a b)
передается как параметр a
. Но это новый экземпляр a
в новой области видимости, который использует то же имя, а не присвоение;привязка просто приводит к тому, что эти два значения эквивалентны.
Мы можем увидеть это также с помощью «правила скольжения Фибоначчи»:
1 1 2 3 5 8 13
----------------------------- <-- sliding interface
b' a'
b a
Когда мы вычисляем последовательность,это окно с двумя числами, записи которого мы называем a и b , которое скользит по последовательности. Вы можете прочитать равенства в любой позиции непосредственно из правила скольжения: посмотрите, b = a ' = 5 и a = b' + a ' = 8.
Вас может смутить a , ссылаясь на более высокое положение в последовательности. Возможно, вы думаете об этой маркировке:
1 1 2 3 5 8 13
------------------------
a' b'
a b
Действительно, в соответствии с этим соглашением об именах, теперь у нас есть b = a ' + b' , как вы ожидаете, и a = b '.
Вопрос только в том, какая переменная обозначена как ведущая дальше по последовательности, икоторый является последним.
Соглашение " a ведет" исходит из того, что a предшествует b в алфавите,и поэтому он сначала получает более новые «обновления» из последовательности, которые затем передаются в b .
Это может показаться нелогичным, но такая модель встречается в других местах математики, например свертка функций.