Chicken (стилизовано как CHICKEN ) — язык программирования , в частности компилятор и интерпретатор , реализующий диалект языка программирования Scheme , и компилирующий исходный код Scheme в стандартный C. Он в основном совместим с R5RS и предлагает множество расширений к стандарту. Более новый стандарт R7RS поддерживается через библиотеку расширений . [2] Chicken — это бесплатное программное обеспечение с открытым исходным кодом, доступное по лицензии BSD . Он реализован в основном на Scheme, с некоторыми частями на C для производительности или для упрощения встраивания в программы на C.
Цель Chicken легко ясна из его слогана: « Практичная и портативная система Scheme ».
Основное внимание Chicken уделяется практическому применению Scheme для написания реального программного обеспечения. Scheme хорошо известен своим использованием в учебных программах по информатике и экспериментах с языками программирования, но он мало используется в бизнесе и промышленности. [3] Сообщество Chicken создало большой набор библиотек для выполнения различных задач. Chicken wiki (программное обеспечение, на котором он работает, также является программой Chicken) также содержит список программного обеспечения, написанного на Chicken. [4]
Другая цель Chicken — быть переносимым . Благодаря компиляции в промежуточное представление , в данном случае переносимого C (как это делают Gambit и Bigloo ), программы, написанные на Chicken, могут быть скомпилированы для распространенных популярных операционных систем, таких как Linux , macOS , других Unix-подобных систем, Windows , Haiku и мобильных платформ iOS и Android . [5] Он также имеет встроенную поддержку кросс-компиляции программ и расширений, [6] что позволяет использовать его на различных встраиваемых системных платформах.
Как и многие компиляторы Scheme, Chicken использует стандартный C в качестве промежуточного представления . Программа Scheme транслируется в C компилятором Chicken, а затем компилятор C транслирует программу C в машинный код для целевой архитектуры компьютера , создавая исполняемую программу. Универсальная доступность C делает его полезным для этой цели.
Дизайн Chicken был вдохновлен статьей 1994 года [7] Генри Бейкера , в которой была изложена инновационная стратегия компиляции Scheme в C. Программа Scheme компилируется в функции C. Эти функции C никогда не достигают оператора return ; вместо этого они вызывают новое продолжение по завершении. Эти продолжения являются функциями C и передаются в качестве дополнительных аргументов другим функциям C. Они вычисляются компилятором.
Пока что это суть стиля продолжения-передачи . Новая идея Бейкера заключается в использовании стека вызовов C для кучи Scheme. Следовательно, можно использовать обычные операции стека C, такие как автоматическое создание переменных, выделение массива переменного размера и т. д. Когда стек заполняется (то есть указатель стека достигает вершины стека), может быть инициирована сборка мусора . Используемая конструкция представляет собой копирующий сборщик мусора , первоначально разработанный CJ Cheney, который копирует все живые продолжения и другие живые объекты в кучу. [8] Несмотря на это, код C не копирует кадры стека C, а только объекты Scheme, поэтому он не требует знания реализации C.
В целом, куча Scheme состоит из стека C в качестве питомника вместе с двумя кучами, требуемыми сборщиком мусора поколений. Этот подход обеспечивает скорость стека C для многих операций и позволяет использовать продолжения как простые вызовы функций C. Кроме того, решение Бейкера гарантирует асимптотическое хвостовое рекурсивное поведение, как того требует стандарт языка Scheme. Реализация в компиляторе Chicken Scheme даже асимптотически безопасна для пространства .
Chicken Scheme в основном совместим с R5RS, с несколькими заметными ограничениями и отклонениями. [9] Совместимость с R7RS предоставляется в виде библиотеки расширений. [2]
Основная система имеет базовую поддержку символов UTF-8 , однако процедуры индексации и обработки строк не поддерживают UTF-8. Существует библиотека расширений, которая добавляет поддержку полной поддержки UTF-8. [10]
Chicken имеет большой репозиторий программного обеспечения с дополнительными библиотеками и программами, называемыми eggs . [11] Эта система очень похожа на RubyGems . [12]
Первоначально эти яйца разрабатывались в одном центральном репозитории svn, [13] в котором создание тега автоматически приводило к тому, что новая версия расширения становилась доступной для загрузки. В настоящее время яйца могут разрабатываться где угодно и под любой системой контроля версий , при этом сохраняя полуавтоматическое управление релизами при использовании большинства популярных сайтов хостинга кода. [14] Этот метод выпуска является VCS-агностическим в том смысле, что пользователю не нужно устанавливать эти VCS. Разработчик может размещать их где угодно по своему выбору и даже может отказаться от публичного контроля версий и распространять только простые tarballs.
Для всех выпущенных яиц последняя версия тестируется автоматически как часть процесса непрерывной интеграции . Существует канонический тестовый сервер , [15] где основная система и все яйца ежедневно тестируются на последней версии разработки (для выявления регрессивных ошибок) и последней стабильной версии (для обеспечения работоспособности всех пользователей стабильной системы). Кроме того, любой желающий может добровольно предоставить дополнительные возможности тестирования на разных: оборудовании, операционных системах или основных выпусках.
Chicken поддерживает большую часть стандартной схемы R5RS , но также добавляет несколько нестандартных функций, которые доступны не во всех реализациях схемы.
Компиляция Chicken в C позволяет вставлять пользовательский код C в скомпилированный результат, что упрощает интеграцию с библиотеками C. Его интерфейс внешних функций поддерживает преобразование между большинством встроенных типов C и соответствующими объектами Scheme.
Также существуют библиотеки расширений для взаимодействия с Python , [16] Lua , [17] и Java через Java Native Interface (JNI) [18] или мост. [19]
Относительно просто выполнить кросс-компиляцию кода Scheme для другой платформы (например, для встроенного использования на устройстве).
Чтобы сделать возможной кросс-компиляцию для кода Scheme, Chicken использует модель раздельной компиляции: скомпилированный модуль состоит из двух общих библиотек . Одна библиотека содержит фактический код, который будет использоваться во время выполнения (скомпилированный для целевой платформы), а другая — это импортируемый модуль , который будет использоваться для загрузки кода, который выполняется во время компиляции (на хост-платформе), например, процедурного макрокода.
Компилятор Chicken также может быть легко кросс-компилирован. После того, как перевод на C будет выполнен, можно просто использовать компилятор C, настроенный на сборку для другой платформы.
Начиная с версии 4, Chicken имеет встроенную модульную систему и поддержку низкоуровневых гигиенических макросов посредством явных макросов переименования [20] (до версии 4 это было доступно через дополнительную библиотеку). Также поддерживаются стандартные макросы синтаксических правил и неявные макросы переименования [21] , которые по сути являются обратной версией явного переименования.
Этот механизм жертвует производительностью ради удобства. Каждый идентификатор, явно не введенный как негигиеничный, будет автоматически переименован, чтобы избежать захвата имени. Стоимость производительности возникает из-за того, что неявное переименование требует от макрорасширителя повторного обхода выражений еще два раза. Эта стоимость оплачивается во время расширения, поэтому автор макроса должен рассмотреть, приемлемо ли более длительное время компиляции.
Начиная с версии 4.11 Chicken поставляется с отладчиком Feathers . [22] Когда код Scheme компилируется с необходимой опцией отладки, события отладки внедряются в определенные точки кода. Они реализуются как вызовы функции C, что является относительно низконакладным, если на самом деле не отлаживать код. При отладке он попытается установить TCP-соединение с процессом сервера Feathers, возможно, на другой машине. Процесс останавливается, пользователь может установить точки останова и запустить программу. Затем, когда достигается точка останова, клиент (отлаживаемый процесс) входит в командный цикл, который позволяет опрашивать клиента, считывать переменные или изменять их.
Chicken поддерживает локальный анализ потока. Это позволяет компилятору отлавливать ошибки типа переменной во время компиляции и выполнять специализацию типа. Эта специализация позволяет удалить несколько проверок безопасности для обнаружения типа во время выполнения, когда тип может быть выведен во время компиляции. Это приводит к улучшению производительности во время выполнения.
Этот анализатор не позволяет проводить анализ потока между модулями, поэтому его можно использовать только для оптимизации кода, являющегося частью одного компилируемого блока (или модуля).
CHICKEN Scheme изначально был разработан Феликсом Винкельманном на Cygwin /gcc, а затем на Visual C++ 5.0 на Windows 98. [ 1] Он придумал название "CHICKEN" произвольно, как "первое, что пришло мне в голову в тот день", думая о пластиковой игрушке Фезерса Макгроу на своем столе. По мере того, как проект развивался, он решил не менять название из суеверия. [23]