Введение
Виртуальная и абстрактная машина как цель для компилятора функционального языка программирования. Машина SECD — весьма влиятельная (см.) виртуальная и абстрактная машина, предназначенная в качестве цели для компиляторов функциональных языков программирования. Буквы SECD обозначают Стек, Окружение, Управление и Дамп — внутренние регистры машины. Регистры Стек, Управление и Дамп указывают на (некоторые реализации) стеков, а Окружение — на (некоторые реализации) ассоциативного массива. Эта машина стала первой, специально разработанной для вычисления выражений лямбда-исчисления. Она была впервые описана Питером Дж. Лэндином в работе "Механическая оценка выражений" в 1964 году. Описание, опубликованное Лэндином, было достаточно абстрактным и оставляло множество вариантов реализации открытыми (например, операционную семантику). Lispkit Lisp был влиятельным компилятором, основанным на машине SECD, и машина SECD использовалась в качестве цели для других систем, таких как Lisp/370. В 1989 году исследователи из Университета Калгари работали над аппаратной реализацией этой машины.
The SECD machine is a highly influential (see: ) virtual machine and abstract machine intended as a target for functional programming language compilers. The letters stand for Stack, Environment, Control, Dump—the internal registers of the machine. The registers Stack, Control, and Dump point to (some realizations of) stacks, and Environment points to (some realization of) an associative array. The machine was the first to be specifically designed to evaluate lambda calculus expressions. It was originally described by Peter J. Landin in "The Mechanical Evaluation of Expressions" in 1964. The description published by Landin was fairly abstract, and left many implementation choices open (like an operational semantics). Lispkit Lisp was an influential compiler based on the SECD machine, and the SECD machine has been used as the target for other systems such as Lisp/370. In 1989 researchers at the University of Calgary worked on a hardware implementation of the machine.
Вклад Лэндина
Д. А. Тернер (2012) отмечает, что язык программирования ALGOL 60 не мог возвращать функции из других функций (что делало функции больше не объектами первого класса). Функция, вложенная в другую функцию, могла обращаться к переменной, находящейся в стеке внешней функции. Если бы вложенная функция возвращалась из внешней функции, она бы ссылалась на переменную в стековом кадре, которого уже не существует. Тернер указывает, что машина Лэндина SECD решает эту проблему (тем самым позволяя функциям возвращать функции), поскольку значение функции теперь представляется замыканием в куче, которое может хранить окружение переменных, которые оно должно использовать, независимо от того, что происходит в стеке.
Неофициальное описание
Когда начинается вычисление выражения, выражение загружается как единственный элемент управления C. Окружение E, стек S и дамп D изначально пусты. Во время вычисления C оно преобразуется в обратную польскую нотацию (RPN), при этом `ap` (для применения) является единственным оператором. Например, выражение F(G X) (один элемент списка) преобразуется в список X:G:ap:F:ap. Вычисление C происходит аналогично другим выражениям RPN. Если первый элемент в C является значением, он помещается в стек S. Точнее, если элемент является идентификатором, в стек будет помещено значение, соответствующее этому идентификатору в текущем окружении E. Если элемент является абстракцией, строится замыкание для сохранения связей его свободных переменных (которые находятся в E), и именно это замыкание помещается в стек. Если элемент – `ap`, из стека извлекаются два значения, и выполняется применение (первое применяется ко второму). Если результатом применения является значение, оно помещается в стек. Однако, если применение абстракции к значению приводит к выражению лямбда-исчисления, которое само по себе может быть применением (а не значением), то оно не может быть помещено в стек. В этом случае текущее содержимое S, E и C помещается в дамп D (который является стеком этих троек), S переинициализируется как пустой, а C переинициализируется результатом применения, при этом E содержит окружение для свободных переменных этого выражения, дополненное связью, полученной в результате применения. Вычисление затем продолжается, как описано выше. Завершение вычисления обозначается тем, что C становится пустым, в этом случае результат находится на стеке S. Затем извлекается последнее сохраненное состояние вычисления из D, и результат завершенного вычисления помещается в содержимое стека, восстановленное из D. Вычисление восстановленного состояния затем продолжается, как описано выше. Если C и D оба пусты, общее вычисление завершено, и результат находится на стеке S.