Компилятор Glasgow Haskell - Glasgow Haskell Compiler
Автор (ы) оригинала | Кевин Хаммонд |
---|---|
Разработчики) | Команда Glasgow Haskell |
Первый выпуск | Декабрь 1992 г. |
Стабильный выпуск | |
Репозиторий | |
Написано в | Haskell и C |
Операционная система | Linux , OS X 10.7 Lion и новее, iOS , Windows 2000 и новее, FreeBSD , Solaris 10 и новее |
Платформа | x86 , x86-64 , ARM |
Доступно в | английский |
Тип | Компилятор |
Лицензия | Новая лицензия BSD |
Веб-сайт | www |
Glasgow Haskell Compiler ( GHC ) является открытым исходным кодом машинного кода компилятором для функционального программирования языка Haskell . Он обеспечивает кроссплатформенную среду для написания и тестирования кода Haskell и поддерживает многочисленные расширения, библиотеки и оптимизации, которые упрощают процесс генерации и выполнения кода. GHC - наиболее часто используемый компилятор Haskell. Ведущие разработчики - Саймон Пейтон Джонс и Саймон Марлоу .
История
Первоначально GHC был запущен в 1989 году как прототип, написанный на LML (Lazy ML) Кевином Хаммондом из Университета Глазго . Позже в том же году прототип был полностью переписан на Haskell, за исключением его парсера , Корделией Холл, Уиллом Партейном и Саймоном Пейтоном Джонсом. Его первая бета-версия была выпущена 1 апреля 1991 года, а в последующих выпусках был добавлен анализатор строгости, а также языковые расширения, такие как монадический ввод-вывод , изменяемые массивы, распакованные типы данных, модели параллельного и параллельного программирования (такие как программная транзакционная память и параллелизм данных ). и профилировщик .
Пейтон Джонс, а также Марлоу позже перешли в Microsoft Research в Кембридже, Англия , где они продолжали нести основную ответственность за разработку GHC. GHC также содержит код от более чем трехсот других участников. С 2009 года взносы третьих сторон в GHC финансируются Industrial Haskell Group.
Архитектура
Сам GHC написан на Haskell , но система времени выполнения для Haskell, необходимая для запуска программ, написана на C и C-- .
GHC, передний конец -incorporating в лексическом анализаторе , анализатор и программе проверка -is предназначены для сохранения как можно больше информации о языке источника , как это возможно только после вывода типа завершения, к цели обеспечения четких сообщений об ошибках пользователей. После проверки типа, код Haskell является обессахаренная в типизированной промежуточный язык , известный как «Core» (на базе системы F , расширенной с let
и case
выражений). Ядро было расширено для поддержки обобщенных алгебраических типов данных в системе типов , и в настоящее время базируется на расширение системы F , известное как System F C .
В традициях компиляции, ориентированной на типы, упрощатель GHC, или «средний конец», где выполняется большая часть оптимизаций, реализованных в GHC, структурирован как серия преобразований исходного кода в код ядра. Анализ и преобразования, выполняемые на этом этапе компиляции, включают анализ спроса (обобщение анализа строгости ), применение определенных пользователем правил перезаписи (включая набор правил, включенных в стандартные библиотеки GHC, которые выполняют слияние складывания и сборки ), развертывание (называемое " встраивание "в более традиционных составителях), пусть плавающий , анализ , который определяет , какие аргументы функции могут быть распакованными, сконструированным анализ результатов продукта , специализации из перегруженных функций, а также набор простых локальных преобразований , такие как постоянное складывания и бета - редукция .
Внутренняя часть компилятора преобразует код ядра во внутреннее представление C-- через промежуточный язык STG (сокращение от «Spineless Tagless G-machine»). Затем код C-- может идти по одному из трех путей: он либо печатается как код C для компиляции с помощью GCC , либо преобразуется непосредственно в машинный код (традиционная фаза « генерации кода »), либо преобразуется в LLVM IR для компиляции с помощью LLVM. . Во всех трех случаях результирующий собственный код, наконец, связывается с системой времени выполнения GHC для создания исполняемого файла.
Язык
GHC соответствует языковым стандартам Haskell 98 и Haskell 2010 . Он также поддерживает множество дополнительных расширений стандарта Haskell: например, библиотеку программной транзакционной памяти (STM), которая позволяет выполнять транзакции составной памяти .
Расширения Haskell
Было предложено несколько расширений Haskell. Эти расширения предоставляют функции, не описанные в спецификации языка, или переопределяют существующие конструкции. Таким образом, каждое расширение может поддерживаться не всеми реализациями Haskell. Постоянно прилагаются усилия для описания расширений и выбора тех, которые будут включены в будущие версии спецификации языка.
Расширения, поддерживаемые компилятором Glasgow Haskell, включают:
- Распакованные типы и операции. Они представляют примитивные типы данных базового оборудования без косвенного указания указателя на кучу или возможности отложенной оценки. Код с большим количеством цифр может быть значительно быстрее при кодировании с использованием этих типов.
- Возможность указать строгую оценку для поля значения, привязки шаблона или типа данных.
- Более удобный синтаксис для работы с модулями, шаблонами, списками , операторами, записями и кортежами.
- Синтаксический сахар для вычислений со стрелками и рекурсивно определенными монадическими значениями. Оба эти понятия распространяются монадическим делать -notation представленного в стандартном Haskell.
- Значительно более мощная система типов и классов типов, описанная ниже.
- Template Haskell , система метапрограммирования во время компиляции . Программист может писать выражения, которые создают код Haskell в форме абстрактного синтаксического дерева . Эти выражения проверяются по типу и оцениваются во время компиляции; сгенерированный код затем включается, как если бы он был написан непосредственно программистом. Вместе с возможностью размышлять над определениями это обеспечивает мощный инструмент для дальнейших расширений языка.
- Квази-цитирование, которое позволяет пользователю определять новый конкретный синтаксис для выражений и шаблонов. Квази-цитирование полезно, когда метапрограмма, написанная на Haskell, манипулирует кодом, написанным на языке, отличном от Haskell.
- Универсальные классы типов, которые определяют функции исключительно в терминах алгебраической структуры типов, с которыми они работают.
- Параллельное вычисление выражений с использованием нескольких ядер ЦП. Это не требует явного создания потоков. Распределение работы происходит неявно, на основе аннотаций, предоставленных программистом.
- Прагмы компилятора для направления оптимизаций, таких как встроенное расширение и специализация функций для определенных типов.
- Настраиваемые правила перезаписи. Программист может предоставить правила, описывающие, как заменить одно выражение эквивалентным, но более эффективно вычисляемым выражением. Они используются в основных библиотеках структур данных для повышения производительности всего кода на уровне приложения.
- Запишите синтаксис точки. Предоставляет синтаксический сахар для доступа к полям (потенциально вложенной) записи, которая аналогична синтаксису многих других языков программирования.
Расширения системы типов
Выразительная система статических типов - одна из основных определяющих особенностей Haskell. Соответственно, большая часть работы по расширению языка была направлена на типы и классы типов .
Glasgow Haskell Compiler поддерживает расширенную систему типов на основе теоретической системы F C . Основные расширения к системе типов включают:
- Произвольный и непредикативный полиморфизм . По сути, полиморфная функция или конструктор типа данных может потребовать, чтобы один из его аргументов сам был полиморфным.
- Обобщенные алгебраические типы данных . Каждый конструктор полиморфного типа данных может кодировать информацию в результирующий тип. Функция, которая соответствует шаблону для этого типа, может использовать информацию о типе конструктора для выполнения более конкретных операций с данными.
- Экзистенциальные типы . Их можно использовать для «связывания» некоторых данных вместе с операциями над этими данными таким образом, чтобы операции можно было использовать, не раскрывая конкретный тип базовых данных. Такое значение очень похоже на объект в объектно-ориентированных языках программирования .
- Типы данных, которые фактически не содержат никаких значений. Они могут быть полезны для представления данных в метапрограммировании на уровне типов .
- Семейства типов : определяемые пользователем функции от типов к типам. В то время как параметрический полиморфизм обеспечивает одинаковую структуру для каждого экземпляра типа, семейства типов предоставляют специальный полиморфизм с реализациями, которые могут различаться между экземплярами. Сценарии использования включают оптимизацию контейнеров с учетом содержимого и метапрограммирование на уровне типов.
- Параметры неявной функции, имеющие динамическую область видимости . Они представлены в типах почти так же, как ограничения классов типов.
- Линейные типы (GHC 9.0)
Расширения, относящиеся к классам типов, включают:
- Класс типа может быть параметризован более чем для одного типа. Таким образом, класс типов может описывать не только набор типов, но и n- мерное отношение типов.
- Функциональные зависимости , которые ограничивают части этого отношения математической функцией типов. То есть ограничение указывает, что какой-то параметр класса типа полностью определяется после того, как фиксируется какой-то другой набор параметров. Это направляет процесс вывода типов в ситуациях, когда в противном случае возникла бы двусмысленность.
- Значительно смягчены правила относительно допустимой формы экземпляров классов типов. Когда они включены полностью, система классов типов становится полным по Тьюрингу языком для логического программирования во время компиляции.
- Семейства типов, как описано выше, также могут быть связаны с классом типов.
- Автоматическая генерация экземпляров классов определенного типа расширена несколькими способами. Поддерживаются новые классы типов для универсального программирования и общие шаблоны рекурсии. Кроме того, когда новый тип объявлен как изоморфный существующему типу, любой экземпляр класса типа, объявленный для базового типа, может быть преобразован в новый тип «бесплатно».
Портативность
Версии GHC доступны для нескольких платформ , включая Windows и большинство разновидностей Unix (таких как Linux , FreeBSD , OpenBSD и macOS ). GHC также был перенесен на несколько различных архитектур процессоров .