Racket — это многопарадигмальный язык программирования общего назначения и многоплатформенный дистрибутив, включающий язык Racket, компилятор , большую стандартную библиотеку, IDE , инструменты разработки и набор дополнительных языков, включая Typed Racket (родственный язык Racket). со статической проверкой типов), Swindle, FrTime, Lazy Racket, R5RS и R6RS Scheme , Scribble, Datalog, Racklog, Algol 60 и несколько языков обучения.
Язык Racket — это современный диалект Lisp и потомок Scheme . Он разработан как платформа для разработки и реализации языков программирования . [9] В дополнение к основному языку Racket, Racket также используется для обозначения семейства языков программирования [10] и набора инструментов, поддерживающих разработку на Racket и с его помощью. [11] Рэкет также используется для написания сценариев , обучения информатике и исследований.
Платформа Racket обеспечивает реализацию языка Racket (включая систему времени выполнения , [12] библиотеки и компилятор , поддерживающий несколько режимов компиляции: машинный код, машинно-независимый, интерпретируемый и JIT) вместе с интегрированной средой разработки DrRacket (IDE). написано на языке Racket. [13] Racket используется в информационно-пропагандистской программе ProgramByDesign , целью которой является превращение информатики в «незаменимую часть учебной программы по гуманитарным наукам ». [14] [15]
Базовый язык Racket известен своей обширной системой макросов , которая позволяет создавать встроенные и предметно-ориентированные языки , языковые конструкции, такие как классы или модули , а также отдельные диалекты Racket с различной семантикой . [16] [17] [18] [19]
Платформа представляет собой бесплатное программное обеспечение с открытым исходным кодом, распространяемое по лицензиям Apache 2.0 и MIT . [20] Расширения и пакеты, написанные сообществом, можно загружать в каталог пакетов Racket .
Маттиас Феллейзен основал PLT Inc. в середине 1990-х годов сначала как исследовательскую группу, а вскоре как проект, посвященный производству педагогических материалов для начинающих программистов (лекции, упражнения/проекты, программное обеспечение). В январе 1995 года группа решила разработать среду педагогического программирования на основе Scheme . Мэтью Флэтт собрал MrEd, оригинальную виртуальную машину для Racket, из libscheme, [21] wxWidgets и нескольких других бесплатных систем. [22] В последующие годы команда, в которую входили Флатт, Робби Финдлер , Шрирам Кришнамурти , Кормак Фланаган и многие другие, создала DrScheme, среду программирования для начинающих программистов Scheme и исследовательскую среду для мягкой печати . [13] Основной язык разработки, поддерживаемый DrScheme, назывался PLT Scheme.
Параллельно команда начала проводить семинары для учителей старших классов, обучая их разработке программ и функциональному программированию. Полевые испытания с участием этих учителей и их учеников дали важные подсказки для направления развития.
В последующие годы PLT добавила в DrScheme языки обучения, алгебраический степпер, [23] прозрачный цикл чтения-оценки-печати , принтер на основе конструктора и многие другие инновации, создав среду разработки педагогических программ прикладного качества. К 2001 году основная группа (Феллейзен, Финдлер, Флатт, Кришнамурти) также написала и опубликовала свой первый учебник « Как разрабатывать программы» , основанный на их философии преподавания.
В «Манифесте Рэкета» [9] подробно описаны принципы, лежащие в основе разработки Рэкета, представлена структура оценки процесса проектирования и подробно описаны возможности для будущих улучшений.
В первом поколении версий схемы PLT появились возможности для программирования в целом с использованием как модулей , так и классов . В версии 42 представлены модули — первоклассная модульная система — в дополнение к классам для крупномасштабной разработки. [24] В этих версиях система классов приобрела новые функции (например, интерфейсы в стиле Java ), но также потеряла некоторые функции (например, множественное наследование ). [16] Язык развивался на протяжении ряда последовательных версий и приобрел значительную популярность в версии 53, что привело к обширной работе и следующей версии 100, которая была бы эквивалентна выпуску «1.0» в текущих популярных системах версий.
Следующая основная версия называлась Версия 200, в которой была представлена новая система модулей по умолчанию, взаимодействующая с макросами. [24] В частности, система модулей обеспечивает разделение вычислений во время выполнения и времени компиляции для поддержки «башни языков». [25] В отличие от юнитов, эти модули не являются первоклассными объектами .
Версия 300 представила поддержку Unicode , поддержку сторонних библиотек и усовершенствования системы классов. [24] Позже в серии 300 была улучшена производительность среды выполнения языка за счет добавления JIT-компилятора и переключения на сборку мусора по умолчанию .
К следующему основному выпуску проект перешел на более традиционную нумерацию версий на основе последовательности . В версии 4.0 введено #lang
сокращение для указания языка, на котором написан модуль. Кроме того, в этой версии представлены неизменяемые пары и списки, поддержка мелкозернистого параллелизма и статически типизированный диалект. [26]
7 июня 2010 года схема PLT была переименована в Racket. [27] Переименование совпало с выпуском версии 5.0. Впоследствии серверная часть графического пользовательского интерфейса (GUI) была переписана на Racket с C++ в версии 5.1 с использованием собственных наборов инструментов пользовательского интерфейса на всех платформах. [22] Версия 5.2 включала инструмент фоновой проверки синтаксиса , новую библиотеку построения графиков, библиотеку базы данных и новый расширенный REPL. [28] Версия 5.3 включала новую функцию подмодуля для опционально загружаемых модулей, [29] новые инструменты оптимизации , библиотеку JSON и другие функции. [30] Версия 5.3.1 представила значительные улучшения в DrRacket: фоновая проверка синтаксиса была включена по умолчанию и добавлен новый инструмент предварительного просмотра документации. [31]
В версии 6.0 Racket выпустила систему управления пакетами второго поколения. В рамках этой разработки основной репозиторий DrRacket и Racket был реорганизован и разделен на большой набор небольших пакетов, что позволило установить минимальный рэкет и установить только те пакеты, которые необходимы. [32]
Версия 7 Racket была выпущена с новым расширителем макросов, написанным на Racket, в рамках подготовки к переходу на систему времени выполнения Chez Scheme и поддержке нескольких систем времени выполнения. [33] [34] 19 ноября 2019 года была выпущена Racket 7.5. Лицензия Racket 7.5 была менее строгой. Сейчас они используют либо лицензию Apache 2.0, либо лицензию MIT. [35] [36]
13 февраля 2021 года вышла Racket 8.0. Racket 8.0 знаменует собой первый выпуск, в котором Racket с системой времени выполнения Chez Scheme , известной как Racket CS, является реализацией по умолчанию. Racket CS быстрее, проще в обслуживании и разработке, обратно совместим с существующими программами Racket и имеет лучшую параллельную сборку мусора. [37]
Основной язык Racket включает макросы , модули , лексические замыкания , хвостовые вызовы , продолжения с разделителями , [38] параметры (жидкие переменные), программные контракты , [39] зеленые потоки и потоки ОС , [40] [41] [42] и многое другое. В язык также входят примитивы, такие как пространства событий и хранители, которые контролируют управление ресурсами и позволяют языку действовать как операционная система для загрузки и управления другими программами. [12] Дальнейшие расширения языка создаются с помощью мощной системы макросов, которая вместе с системой модулей и пользовательскими анализаторами может контролировать все аспекты языка. [43] Большинство языковых конструкций в Racket реализованы в виде макросов базового языка. К ним относятся система классов миксинов , [16] система компонентов (или модулей), столь же выразительная, как непрозрачное приписывание в системе модулей ML , [17] и сопоставление шаблонов .
Кроме того, в языке реализована первая контрактная система для языка программирования более высокого порядка . [44] Контрактная система Racket основана на работе Design by Contract для Eiffel и расширяет ее для работы со значениями более высокого порядка, такими как первоклассные функции , объекты, ссылочные ячейки и т. д. Например, можно гарантировать, что объект, который проверяется контрактом, будет выполнять проверки контракта при вызове его методов.
Racket включает в себя как байт-код , так и JIT (JIT)-компиляторы. Компилятор байт-кода создает внутренний формат байт-кода, запускаемый виртуальной машиной Racket , а JIT-компилятор преобразует байт-код в машинный код во время выполнения.
С 2004 года язык также поставляется с PLaneT, менеджером пакетов, интегрированным в систему модулей, что позволяет прозрачно импортировать и использовать сторонние библиотеки . Кроме того, PLaneT имеет встроенную политику управления версиями , предотвращающую ад зависимостей . [45]
В конце 2014 года большая часть кода Racket была перенесена в новую систему упаковки, отдельную от основной базы кода. Эта новая система упаковки обслуживается клиентской программой raco . Новая система пакетов предоставляет меньше возможностей, чем PLaneT; Сообщение Джея Маккарти в блоге Racket объясняет причину изменения и способы дублирования старой системы. [46]
Особенностями, которые наиболее явно отличают Racket от других языков семейства Lisp, являются встроенные функции расширения языка , которые поддерживают создание новых языков, специфичных для предметной области и языков общего назначения . Функции расширения Racket встроены в систему модулей, чтобы обеспечить контекстно-зависимый и модульный контроль над синтаксисом. [18] Например, #%app
синтаксическую форму можно переопределить, чтобы изменить семантику применения функции . Аналогично, #%module-begin
форма допускает произвольный статический анализ всего модуля. [18] Поскольку любой модуль можно использовать в качестве языка через #lang
нотацию, это фактически означает, что практически любой аспект языка можно запрограммировать и контролировать.
Возможности расширения на уровне модуля сочетаются с системой гигиенических макросов, подобной Scheme , которая предоставляет больше возможностей, чем система манипулирования s-выражениями Lisp , [47] [48] гигиенические макросы расширения синтаксиса Scheme 84 или правила синтаксиса R5RS . . Действительно, справедливо будет сказать, что система макросов представляет собой тщательно настроенный интерфейс прикладного программирования (API) для расширений компилятора . Используя этот API-интерфейс компилятора, программисты могут добавлять функции и целые предметно-ориентированные языки таким образом, чтобы они были полностью неотличимы от встроенных языковых конструкций.
Макросистема в Racket использовалась для создания целых языковых диалектов . Сюда входит Typed Racket, который представляет собой диалект Racket с постепенной типизацией, который облегчает переход от нетипизированного кода к типизированному, [49] Lazy Racket — диалект с отложенным вычислением , [50] и Hackett, который сочетает в себе Haskell и Racket. [51] Язык педагогического программирования Pyret изначально был реализован в Racket. [52] [53]
Другие диалекты включают FrTime ( функциональное реактивное программирование ), Scribble (язык документации), [54] Slideshow ( язык презентаций ), [55] и несколько языков для обучения. [56] [57]
Базовый дистрибутив Racket предоставляет библиотеки, помогающие в разработке языков программирования. [18] Такие языки не ограничиваются синтаксисом, основанным на s-выражениях . В дополнение к обычным расширениям синтаксиса на основе таблиц чтения, директива #lang
позволяет вызывать произвольные анализаторы, которые можно реализовать с помощью библиотеки инструментов анализатора. [58] Пример такого языка см. в разделе Рэкетное логическое программирование .
Языковая платформа предоставляет автономную IDE [13] под названием DrRacket, веб-сервер на основе продолжения , [59] графический интерфейс пользователя , [22] и другие инструменты. Как жизнеспособный инструмент сценариев с такими библиотеками, как распространенные языки сценариев , его можно использовать для написания сценариев оболочки Unix. Он может анализировать аргументы командной строки и запускать внешние инструменты.
DrRacket (ранее DrScheme) широко используется на вводных курсах информатики, на которых преподают Scheme или Racket, и славится своей простотой и привлекательностью для начинающих программистов. Изначально IDE была создана для использования с TeachScheme! проект (теперь ProgramByDesign ), информационно-просветительская работа Северо-Восточного университета и ряда дочерних университетов с целью привлечения старшеклассников к курсам информатики на уровне колледжа.
Редактор обеспечивает подсветку синтаксических ошибок и ошибок времени выполнения, сопоставление скобок, отладчик и алгебраический шаговый процессор. Его функции, удобные для студентов, включают поддержку нескольких «языковых уровней» (начальный студент, средний студент и т. д.). Он также имеет встроенную поддержку библиотек и сложные инструменты анализа для опытных программистов. Кроме того, модульно-ориентированное программирование поддерживается браузером модулей, контурным представлением, интегрированными измерениями тестирования и покрытия , а также поддержкой рефакторинга . Он обеспечивает интегрированный контекстно-зависимый доступ к обширной справочной системе с гиперссылками под названием «Служба поддержки».
DrRacket доступен для Windows , macOS , Unix и Linux с системой X Window , и программы ведут себя одинаково на всех этих платформах.
Вот тривиальная программа hello world :
#языковая ракетка "Привет, Мир!"
Запуск этой программы дает вывод:
Вот немного менее тривиальная программа:
#lang Racket ( требуется 2htdp/image ) ( let sierpinski ([ n 8 ]) ( if ( ноль? n ) ( треугольник 2 ' сплошной ' красный ) ( let ( [ t ( sierpinski ( - n 1 ))]) ( заморозить ( выше t ( рядом с t t )) ))))
Эта программа, взятая с сайта Racket, рисует треугольник Серпинского , вложенный на глубину 8.
С помощью #lang
директивы исходный файл можно написать на разных диалектах Racket. Вот пример программы факториала в Typed Racket, статически типизированном диалекте Racket:
#lang напечатано/рэкет( : факт ( Целое -> Целое )) ( определить ( факт n ) ( if ( ноль? n ) 1 ( * n ( факт ( - n 1 )))))
В настоящее время Racket имеет две реализации. Оба поддерживают Linux, Windows и MacOS на различных архитектурах и поддерживаются начиная с версии 8.8 (2023 г.). Реализация по умолчанию использует инкрементальный компилятор и среду выполнения Chez Scheme . Альтернативная реализация генерирует независимый от платформы байт-код и использует JIT-компиляцию для создания машинного кода по мере его загрузки. [60]
Кроме того, существуют экспериментальные реализации:
Помимо теории языков программирования , Racket был разработан как язык общего назначения для производственных систем. Таким образом, дистрибутив Racket включает в себя обширную библиотеку, охватывающую системное и сетевое программирование, веб-разработку, [59] унифицированный интерфейс к базовой операционной системе, динамический интерфейс внешних функций , [63] несколько разновидностей регулярных выражений , генераторы лексеров/парсеров. , [58] логическое программирование и полная структура графического пользовательского интерфейса .
Racket имеет несколько функций, полезных для коммерческого языка, в том числе возможность компилировать автономные исполняемые файлы под Windows, macOS и Unix, профилировщик и отладчик , включенные в интегрированную среду разработки (IDE), а также среду модульного тестирования .
Racket использовался для коммерческих проектов и веб-приложений. Ярким примером является веб-сайт Hacker News , работающий на платформе Arc , разработанной в Racket. Naughty Dog использовала его в качестве языка сценариев в нескольких видеоиграх. [64]
Racket используется для обучения студентов алгебре посредством игрового дизайна в программе Bootstrap . [65]
Стандартное расширение файла программы Racket — «.rkt».
Расширения «.ss», «.scm» и «.sch» также исторически популярны.