Racket — это многопарадигмальный язык программирования общего назначения . Язык Racket — это современный диалект Lisp и потомок Scheme . Он разработан как платформа для проектирования и реализации языков программирования. [9] В дополнение к основному языку Racket, Racket также используется для обозначения семейства языков программирования [10] и набора инструментов, поддерживающих разработку на Racket и с его помощью. [11] Racket также используется для написания скриптов , обучения информатике и проведения исследований.
Платформа Racket обеспечивает реализацию языка Racket (включая систему выполнения , [12] библиотеки и компилятор, поддерживающий несколько режимов компиляции: машинный код, машинно-независимый, интерпретируемый и JIT) вместе с интегрированной средой разработки (IDE) DrRacket, написанной на 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 добавила языки обучения, алгебраический степпер, [23] прозрачный цикл чтения-оценки-печати , принтер на основе конструктора и многие другие инновации в DrScheme, создав среду разработки педагогических программ прикладного качества. К 2001 году основная команда (Феллейзен, Финдлер, Флэтт, Кришнамурти) также написала и опубликовала свой первый учебник « Как разрабатывать программы» , основанный на их философии обучения.
Манифест Racket [9] подробно описывает принципы, лежащие в основе разработки Racket, представляет структуру оценки, лежащую в основе процесса проектирования, и детализирует возможности для будущих улучшений.
Первое поколение ревизий схемы PLT представило возможности для программирования в целом с использованием как модулей , так и классов . Версия 42 представила модули — первоклассную модульную систему — для дополнения классов для крупномасштабной разработки. [24] Система классов приобрела возможности (например, интерфейсы в стиле Java ), а также потеряла несколько возможностей (например, множественное наследование ) на протяжении этих версий. [16] Язык развивался на протяжении ряда последовательных версий и приобрел эпохальную популярность в версии 53, что привело к обширной работе и следующей версии 100, которая будет эквивалентна выпуску «1.0» в текущих популярных системах версий.
Следующая крупная ревизия была названа версией 200, в которой была введена новая система модулей по умолчанию, которая взаимодействует с макросами. [24] В частности, система модулей гарантирует, что вычисления во время выполнения и во время компиляции разделены для поддержки «башни языков». [25] В отличие от модулей, эти модули не являются объектами первого класса .
В версии 300 появилась поддержка Unicode , поддержка иностранных библиотек и усовершенствования в системе классов. [24] Позднее в серии 300 была улучшена производительность среды выполнения языка за счет добавления JIT-компилятора и перехода на сборку мусора по умолчанию на основе поколений .
К следующему крупному релизу проект перешел на более традиционную нумерацию версий на основе последовательности . Версия 4.0 представила #lang
сокращение для указания языка, на котором написан модуль. Кроме того, пересмотр представил неизменяемые пары и списки, поддержку мелкозернистого параллелизма и статически типизированный диалект. [26]
7 июня 2010 года PLT Scheme был переименован в 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 был реорганизован и разделен на большой набор небольших пакетов, что позволило установить минимальный 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 реализованы как макросы в базовом языке. К ним относятся система классов mixin , [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-выражений . В дополнение к обычным расширениям синтаксиса на основе readtable, директива #lang
позволяет вызывать произвольные парсеры, которые могут быть реализованы с помощью библиотеки инструментов парсера. [58] См. пример такого языка в разделе Программирование логики Racket .
Языковая платформа предоставляет самостоятельную IDE [13] под названием DrRacket, веб-сервер на основе продолжения , [59] графический пользовательский интерфейс , [22] и другие инструменты. Как жизнеспособный скриптовый инструмент с библиотеками, такими как распространенные скриптовые языки , он может использоваться для скриптования оболочки Unix. Он может анализировать аргументы командной строки и выполнять внешние инструменты.
DrRacket (ранее DrScheme) широко используется среди вводных курсов по информатике, которые обучают Scheme или Racket, и хвалится за свою простоту и привлекательность для начинающих программистов. IDE изначально была создана для использования с проектом TeachScheme! (теперь ProgramByDesign ), пропагандистской инициативой Северо-Восточного университета и ряда аффилированных университетов по привлечению учащихся старших классов к курсам информатике на уровне колледжа.
Редактор обеспечивает подсветку синтаксических и временных ошибок, сопоставление скобок, отладчик и алгебраический степпер. Его удобные для студентов функции включают поддержку нескольких «языковых уровней» (Beginning Student, Intermediate Student и т. д.). Он также имеет встроенную поддержку библиотек и сложные инструменты анализа для продвинутых программистов. Кроме того, модульно-ориентированное программирование поддерживается с помощью браузера модулей, контурного представления, встроенного тестирования и измерения покрытия , а также поддержки рефакторинга . Он обеспечивает интегрированный, контекстно-зависимый доступ к обширной гиперссылочной справочной системе под названием «Help Desk».
DrRacket доступен для Windows , macOS , Unix и Linux с X Window System , и программы ведут себя одинаково на всех этих платформах.
Вот тривиальная программа «Hello, World!» :
#lang рэкет "Привет, мир!"
Запуск этой программы даст следующий результат:
Вот немного менее тривиальная программа:
#lang racket ( требуется 2htdp/image ) ( пусть серпинский ([ n 8 ]) ( если ( ноль? n ) ( треугольник 2 ' сплошной ' красный ) ( пусть ([ t ( серпинский ( - n 1 ))]) ( заморозить ( над t ( рядом с t t ))))))
Эта программа, взятая с сайта Racket, рисует треугольник Серпинского , вложенный на глубину 8.
Используя #lang
директиву, исходный файл может быть написан на разных диалектах Racket. Вот пример факториальной программы на Typed Racket, статически типизированном диалекте Racket:
#язык типизирован/ракетка( : факт ( Целое число -> Целое число )) ( определить ( факт n ) ( если ( ноль? n ) 1 ( * n ( факт ( - n 1 )))))
В настоящее время Racket имеет две реализации. Обе поддерживают Linux, Windows и MacOS на различных архитектурах и поддерживаются с версии 8.8 (2023). Реализация по умолчанию использует инкрементальный компилятор и среду выполнения Chez Scheme . Альтернативная реализация генерирует платформенно-независимый байт-код и использует компиляцию Just-in-time для генерации машинного кода по мере его загрузки. [60]
Кроме того, существуют экспериментальные реализации:
Помимо наличия основы в теории языков программирования , Racket был разработан как язык общего назначения для производственных систем. Таким образом, дистрибутив Racket включает обширную библиотеку, которая охватывает системное и сетевое программирование, веб-разработку, [59] единый интерфейс к базовой операционной системе, динамический интерфейс внешних функций , [63] несколько разновидностей регулярных выражений , генераторы лексеров/парсеров, [58] логическое программирование и полную структуру GUI .
Racket обладает рядом функций, полезных для коммерческого языка, среди которых возможность компилировать автономные исполняемые файлы под Windows, macOS и Unix, профилировщик и отладчик, включенные в интегрированную среду разработки (IDE), а также фреймворк модульного тестирования .
Racket использовался для коммерческих проектов и веб-приложений. Ярким примером является веб-сайт Hacker News , работающий на Arc , разработанном на Racket. Naughty Dog использовала его в качестве языка сценариев в нескольких видеоиграх. [64]
Racket используется для обучения студентов алгебре посредством игрового дизайна в программе Bootstrap . [65]
Стандартное расширение файла для файла программы Racket — ".rkt". Расширения ".ss", ".scm" и ".sch" также исторически популярны.