Введение

Реализация языка программирования на основе Scheme.

Chicken (стилизованный как CHICKEN) — это язык программирования, а точнее компилятор и интерпретатор, реализующий диалект языка Scheme и компилирующий исходный код Scheme в стандартный C. Он в основном соответствует стандарту R5RS и предлагает множество расширений к этому стандарту. Поддержка более нового стандарта R7RS осуществляется через библиотеку расширений. Chicken является свободным программным обеспечением с открытым исходным кодом, распространяемым по лицензии BSD. Он реализован преимущественно на Scheme, с некоторыми частями на C для повышения производительности или упрощения встраивания в программы на C.

Сосредоточься

Основные цели Chicken очевидны из её слогана: «Практичная и портативная система Scheme». Главный акцент Chicken сделан на практическом применении Scheme для разработки реального программного обеспечения. Scheme хорошо известен своим использованием в учебных курсах по информатике и в экспериментах с языками программирования, но он редко используется в бизнесе и промышленности. Сообщество Chicken создало обширный набор библиотек для решения широкого спектра задач. Вики Chicken (программное обеспечение, на котором она работает, также написано на Chicken) содержит список программ, разработанных на Chicken. Другая цель Chicken – обеспечить переносимость. Благодаря компиляции в промежуточное представление, в данном случае – переносимый C (как это делают Gambit и Bigloo), программы, написанные на Chicken, могут быть скомпилированы для популярных операционных систем, таких как Linux, macOS, другие Unix-подобные системы, Windows, Haiku, а также для мобильных платформ iOS и Android. Chicken также имеет встроенную поддержку кросс-компиляции программ и расширений, что позволяет использовать его на различных платформах встраиваемых систем.

Дизайн

Как и многие компиляторы Scheme, Chicken использует стандарт C в качестве промежуточного представления. Программа Scheme транслируется в C компилятором Chicken, а затем C-компилятор транслирует программу на C в машинный код для целевой компьютерной архитектуры, создавая исполняемую программу. Широкая доступность C делает его полезным для этой цели. Дизайн Chicken был вдохновлен статьей Генри Бейкера 1994 года, в которой была представлена инновационная стратегия компиляции Scheme в C. Программа Scheme компилируется в функции C. Эти функции C никогда не достигают оператора `return`; вместо этого они вызывают новое продолжение по завершении. Эти продолжения являются функциями C и передаются как дополнительные аргументы другим функциям C. Они вычисляются компилятором. На данный момент это суть стиля передачи продолжений. Новая идея Бейкера заключается в использовании стека вызовов C для кучи Scheme. Таким образом, можно использовать обычные операции со стеком C, такие как автоматическое создание переменных, выделение массивов переменного размера и так далее. Когда стек заполняется (то есть указатель стека достигает вершины стека), может быть инициирован сбор мусора. Используется копирующий сборщик мусора, первоначально разработанный C. Дж. Чейни, который копирует все живые продолжения и другие живые объекты в кучу. Несмотря на это, код на C не копирует фреймы стека C, а только объекты Scheme, поэтому он не требует знания реализации C. В целом, куча Scheme состоит из стека C в качестве питомника вместе с двумя кучами, необходимыми для генерационного сборщика мусора. Этот подход обеспечивает скорость стека C для многих операций и позволяет использовать продолжения как простые вызовы функций C. Более того, решение Бейкера гарантирует асимптотическое поведение хвостовой рекурсии, как того требует стандарт языка Scheme. Реализация в компиляторе Chicken Scheme даже асимптотически безопасна по памяти.

Ограничения и отклонения от стандарта

Система Chicken Scheme в основном соответствует стандарту R5RS, имея несколько существенных ограничений и отклонений. Совместимость с R7RS предоставляется в виде библиотеки расширений.

Дополнительное программное обеспечение

В Chicken существует большое программное хранилище дополнительных библиотек и программ, называемых "яйцами". Эта система очень похожа на RubyGems. Изначально эти "яйца" разрабатывались в одном центральном репозитории Subversion, где создание тега автоматически приводило к появлению новой версии расширения для загрузки. В настоящее время "яйца" могут разрабатываться где угодно и с использованием любой системы контроля версий, при этом сохраняя возможность полуавтоматического управления выпуском при использовании большинства популярных площадок для хостинга кода. Этот метод выпуска не зависит от конкретной VCS, то есть пользователю не требуется устанавливать эти системы контроля версий. Разработчик может свободно размещать код где угодно по своему выбору и даже отказаться от публичного контроля версий, распространяя только обычные tar-архивы. Для всех выпущенных "яиц" последняя версия автоматически тестируется в рамках процесса непрерывной интеграции. Существует эталонный тестовый сервер, на котором основная система и все "яйца" ежедневно тестируются с самой последней разрабатываемой версией (для выявления регрессионных ошибок) и с самой последней стабильной версией (чтобы гарантировать работоспособность для пользователей стабильной системы). Кроме того, любой желающий может предоставить дополнительные ресурсы для тестирования на различном оборудовании, операционных системах или основных версиях системы.

Особенности

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

Интерфейс внешних функций

Компиляция Chicken в C позволяет внедрять произвольный код на C в скомпилированный результат, что упрощает интеграцию с C-библиотеками. Его интерфейс для взаимодействия с кодом на других языках поддерживает преобразование между большинством встроенных типов C и соответствующими объектами Scheme. Также существуют расширения для взаимодействия с Python, Lua и Java через Java Native Interface (JNI) или посредством моста.

Перекрестная компиляция

Относительно легко перекрестно компилировать код Scheme для другой платформы (например, для встраиваемых систем на устройстве). Чтобы обеспечить кросс-компиляцию кода Scheme, Chicken использует модель раздельной компиляции: скомпилированный модуль состоит из двух общих библиотек. Одна библиотека содержит фактический код, который будет использоваться во время выполнения (скомпилированный для целевой платформы), а другая – модуль импорта, который используется для загрузки кода, выполняющегося во время компиляции (на хост-платформе), например, код процедурных макросов. Компилятор Chicken также легко поддается кросс-компиляции. После преобразования в C можно просто использовать C-компилятор, настроенный для сборки под другую платформу.

Модули и макросы

С версии 4 Chicken имеет встроенную систему модулей и поддержку гигиенических макросов низкого уровня посредством макросов явного переименования (до версии 4 это было доступно через дополнительную библиотеку). Также поддерживаются макросы стандартных синтаксических правил и неявные макросы переименования, которые, по сути, являются обратной версией макросов явного переименования. Этот механизм жертвует производительностью ради удобства. Каждый идентификатор, явно не объявленный как антигигиенический, будет автоматически переименован для предотвращения захвата имени. Затраты на производительность возникают из-за того, что неявное переименование требует от расширителя макросов повторного прохода по выражениям дважды. Эти затраты оплачиваются во время расширения, поэтому автор макроса должен учитывать, допустимо ли увеличение времени компиляции.

Удаленный дебьюгер

С версии 4.11 Chicken поставляется с отладчиком под названием Feathers. При компиляции кода Scheme с необходимой опцией отладки, в определенные точки кода внедряются события отладки. Они реализованы в виде вызовов функции на C, что создает относительно небольшую нагрузку, когда отладка не активна. Во время отладки отладчик пытается установить TCP-соединение с серверным процессом Feathers, возможно, на другом компьютере. Процесс останавливается, и пользователь может установить точки останова и запустить программу. Когда точка останова достигнута, клиентский процесс (процесс, который отлаживается) входит в командный цикл, позволяющий запрашивать информацию о клиенте, читать значения переменных или изменять их.

Ограниченный статический анализ типа

Курица поддерживает локальный анализ потока данных. Это позволяет компилятору выявлять ошибки типов переменных на этапе компиляции и выполнять специализацию типов. Благодаря этой специализации становится возможным исключить ряд проверок безопасности для определения типа во время выполнения, если тип может быть выведен на этапе компиляции. Это приводит к повышению производительности во время выполнения. Этот анализатор не поддерживает межмодульный анализ потока данных, поэтому его можно использовать только для оптимизации кода, входящего в состав одной единицы компиляции (или модуля).

История

CHICKEN Scheme был первоначально разработан Феликсом Винкельманном на Cygwin/gcc, а затем на Visual C++ 5.0 под Windows 98.