Введение

Диалект Лиспа

Scheme — это диалект семейства языков программирования Lisp. Scheme был создан в 1970-х годах в Лаборатории компьютерных наук и искусственного интеллекта MIT (MIT AI Lab) и опубликован его разработчиками Гаем Л. Стилом и Джеральдом Джей Суссманом в серии меморандумов, ныне известных как Lambda Papers. Он стал первым диалектом Lisp, выбравшим лексическую область видимости, и первым, потребовавшим от реализаций выполнения оптимизации хвостовой рекурсии, что обеспечило более надежную поддержку функционального программирования и связанных с ним техник, таких как рекурсивные алгоритмы. Он также был одним из первых языков программирования, поддерживающих продолжения первого класса. Scheme оказал значительное влияние на работу, которая привела к разработке Common Lisp. Язык Scheme стандартизирован в официальном стандарте Института инженеров электротехники и электроники (IEEE) и в фактическом стандарте под названием «Пересмотренный отчет об алгоритмическом языке Scheme» (RnRS). Широко используемым стандартом является R5RS (1998). Самый последний ратифицированный стандарт Scheme — «R7RS small» (2013). Более развернутый и модульный R6RS был ратифицирован в 2007 году. Оба они происходят от R5RS; хронология ниже отражает хронологический порядок ратификации.

Происхождение

Схема возникла в 1970-х годах как попытка осмыслить модель акторов Карла Хьюитта, для чего Стил и Сассман создали "миниатюрный интерпретатор Lisp" на основе Maclisp, а затем "добавили механизмы для создания акторов и обмена сообщениями". Изначально Scheme назывался "Schemer", следуя традиции других языков, произошедших от Lisp, таких как Planner или Conniver. Современное название возникло из-за использования авторами операционной системы ITS, которая ограничивала имена файлов двумя частями, каждая из которых не должна была превышать шесть символов. В настоящее время "Schemer" обычно используется для обозначения программиста на Scheme.

R6RS

На семинаре Scheme 2003 года начался новый процесс стандартизации языка с целью создания стандарта R6RS к 2006 году. Этот процесс отошел от прежнего подхода RnRS, основанного на единогласии. R6RS включает в себя стандартную модульную систему, позволяющую разделить основное ядро языка и библиотеки. Было выпущено несколько проектов спецификации R6RS, финальной версией стала R5.97RS. Успешное голосование привело к ратификации нового стандарта, объявленной 28 августа 2007 года. Существует переносимая эталонная реализация предлагаемых библиотек с неявной фазировкой для R6RS, называемая psyntax, которая корректно загружается и самозапускается на различных устаревших реализациях Scheme. Одной из особенностей R6RS является дескриптор типа записи (RTD). При создании и использовании RTD представление типа записи может отображать структуру памяти. Он также вычисляет битовую маску поля объекта и битовые маски полей изменяемых объектов Scheme, а также помогает сборщику мусора определить, что делать с полями, не просматривая весь список полей, хранящийся в RTD. RTD позволяет пользователям расширять базовый RTD для создания новой системы записей. R6RS вводит множество значительных изменений в язык. Исходный код теперь специфицирован в Unicode, и большая часть символов Unicode теперь может использоваться в символах и идентификаторах Scheme, а также внесены другие незначительные изменения в лексические правила. Данные о символах также теперь специфицированы в Unicode. Многие стандартные процедуры были перемещены в новые стандартные библиотеки, которые сами по себе значительно расширяют стандарт, содержат процедуры и синтаксические формы, которые ранее не входили в стандарт. Введена новая модульная система, а также стандартизированы механизмы обработки исключений. Правила синтаксиса заменены более выразительным средством синтаксической абстракции (syntax case), которое позволяет использовать все возможности Scheme во время расширения макросов. Соответствующие реализации теперь должны поддерживать полную числовую башню Scheme, а семантика чисел была расширена, в основном в направлении поддержки стандарта IEEE 754 для представления чисел с плавающей точкой.

R7RS

Стандарт R6RS вызвал споры, поскольку некоторые считают его отходом от минималистической философии. В августе 2009 года Руководящий комитет Scheme, осуществляющий надзор за процессом стандартизации, объявил о намерении рекомендовать разделение Scheme на два языка: большой, современный язык программирования для программистов, и небольшую версию – подмножество большого языка, сохраняющую минимализм, высоко ценимый преподавателями и разработчиками-энтузиастами. Для работы над этими двумя новыми версиями Scheme были созданы две рабочие группы. На сайте Scheme Reports Process можно найти ссылки на уставы рабочих групп, публичные обсуждения и систему отслеживания проблем. Девятой черновой версии R7RS (малого языка) была опубликована 15 апреля 2013 года. Голосование по ратификации этой версии завершилось 20 мая 2013 года, а окончательный отчёт стал доступен 6 августа 2013 года, описывая "малый" язык, разработанный в рамках этой работы: поэтому его нельзя рассматривать изолированно как преемника R6RS. Такая простота объясняется использованием лямбда-исчисления для вывода большей части синтаксиса языка из более примитивных форм. Например, из 23 синтаксических конструкций, основанных на s-выражениях, определённых в стандарте R5RS Scheme, 14 классифицируются как производные или библиотечные формы, которые могут быть записаны в виде макросов, использующих более фундаментальные формы, главным образом лямбда. Как указано в R5RS (§3.1): "Наиболее фундаментальной конструкцией для связывания переменных является лямбда-выражение, поскольку все остальные конструкции для связывания переменных можно объяснить в терминах лямбда-выражений". В нём была принята концепция лексического замыкания (на странице 21), которая была описана в AI Memo в 1970 году Джоэлем Мозесом, который приписывал эту идею Питеру Дж. Лэндину.

Ламбда-расчет

Математическая нотация Алонсо Черча, лямбда-исчисление, вдохновила Lisp на использование "lambda" в качестве ключевого слова для определения процедуры, а также повлияла на развитие методов функционального программирования, связанных с использованием функций высшего порядка в Lisp. Однако ранние реализации Lisp не являлись адекватным выражением лямбда-исчисления из-за особенностей обработки свободных переменных. Лямбда-исчисление выполняет следующие функции: во-первых, служит основой для мощной математической логики; во-вторых, позволяет снизить требования к программистам учитывать детали реализации, поскольку его можно использовать для моделирования машинного выполнения; и, наконец, лямбда-исчисление породило значительную метатеорию. Введение лексической области видимости решило эту проблему, установив соответствие между некоторыми формами лямбда-нотации и их практической реализацией в рабочем языке программирования. Сассман и Стил показали, что новый язык можно использовать для элегантного вывода всей императивной и декларативной семантики других языков программирования, включая ALGOL и Fortran, а также динамической области видимости других реализаций Lisp, используя лямбда-выражения не просто как экземпляры процедур, а как "структуры управления и модификаторы окружения". Они представили стиль передачи продолжения вместе со своим первым описанием Scheme в первой из работ Lambda Papers, а в последующих работах продемонстрировали всю мощь этого практического применения лямбда-исчисления.

Стандарты внедрения

В этом подразделе документируются проектные решения, принятые на протяжении многих лет, которые сформировали уникальные особенности Scheme, но не являются прямым следствием изначального замысла.

Переопределение стандартных процедур

В Scheme процедуры привязываются к переменным. В стандарте R5RS было формально предписано, что программы могут изменять привязки переменных встроенных процедур, фактически переопределяя их. (R5RS "Изменения языка")