В дополнение к превосходному принятому ответу, я хотел бы дать больше объяснения, почему rap
требуется.
Среда (E
в SECD
) хранит все постоянные объекты (функции, константы, переменные и т. Д.). E
- это, по сути, стек списков. Вещи в E
загружаются в стек S
и затем выполняются или используются командами в C
. Все в E
имеет идентификатор, чтобы на него можно было ссылаться позже. Этот идентификатор обычно является кортежем (x,y)
, где x
представляет местоположение списка в стеке, а y
представляет позицию в этом списке.
При типичном вызове функции новый список помещается на E
, и теперь любые локальные переменные могут иметь идентификаторы, например (|E|, y)
, где |E|
обозначает размер E
. Однако это очень проблематично для рекурсивных функций, поскольку размер стека увеличивается с каждым вызовом функции, поэтому нет возможности назначить локальным переменным идентификаторы, которые можно использовать.
Чтобы решить эту проблему, rap
выполняет большинство действий ap
, но вместо того, чтобы помещать новый список в стек среды, он заменяет все, что находится в начале E
, на новый список среды. ,