Nano Hash - криптовалюты, майнинг, программирование

Внутреннее устройство GHC: есть ли реализация системы типов на C?

Я изучаю внутренности GHC и обнаруживаю, что вся система синтаксического анализа и типизации полностью написана на Haskell. Низкоуровневое ядро ​​языка предоставляется RTS. Вопрос в том, что из следующего верно?

  • RTS содержит C-реализацию системы типов и других базовых частей Haskell (я не нашел, RTS в основном GC и многопоточность)
  • Все реализовано в самом Haskell. Но это кажется довольно сложным, потому что для сборки GHC уже требуется GHC.

Не могли бы вы объяснить логику разработки компилятора? Например, Python обеспечивает непрозрачную реализацию всего на C.


  • Типы стираются при компиляции. RTS ничего не знает о типах, она только реализует машину STG (теперь в стиле eval/apply), которая является эффективной техникой для обработки замыканий, переходников и т. д. RTS также реализует GC и некоторые FFI для взаимодействия с уровнем C. 10.05.2017
  • Помимо вышеперечисленного, я думаю, что все в Haskell. Вы не можете скомпилировать GHC без предыдущего GHC, так же как вы не можете скомпилировать GCC без предыдущего GCC. Я предполагаю, что очень ранние версии GHC были загружаемы из C или из какого-либо другого компилятора/интерпретатора Haskell, который, в свою очередь, загружался. 10.05.2017
  • Итак, все (например, вывод типов) реализовано в Haskell. Тогда STG получает низкоуровневое представление вычислений и просто выполняет его без всяких проверок типов, оперируя только значениями? 10.05.2017
  • Да, STG не выполняет проверку типов. Во многих статически типизированных языках программирования типы проверяются только во время компиляции, а затем могут быть отброшены (стерты), чтобы во время выполнения не было накладных расходов из-за типов. В GHC проверка статического типа реализована на Haskell. 10.05.2017
  • Если вы по какой-либо причине действительно хотите увидеть систему типов Haskell, реализованную на языке C, она есть в Hugs98 (см. src/type.c). 10.05.2017
  • Что ж, возможно, можно было бы скомпилировать незарегистрированный GHC и использовать этот незарегистрированный GHC для компиляции GHC в C. Но я не думаю, что это будет красиво. 10.05.2017
  • Другой ресурс, который может оказаться полезным, но не дает прямого ответа на ваш вопрос: GHC имеет массу сложностей по целому ряду причин (исторические, экспериментальные, производительность и т. д.), которые мешают узнать, как это работает. Стивен Дил ведет блог о написании игрушечной реализации основ Haskell, начиная с первых принципов, с целью обучения. http://dev.stephendiehl.com/fun/ 11.05.2017

Ответы:


1

Как отмечали другие в комментариях, GHC почти полностью написан на Haskell (плюс некоторые расширения GHC) и предназначен для компиляции с самим собой. Фактически, единственная программа в мире, которая может скомпилировать компилятор GHC, — это компилятор GHC! В частности, синтаксический анализ и вывод типов реализованы в коде Haskell, и вы нигде не найдете спрятанной реализации C.

Лучшим источником для понимания внутренней структуры компилятора (и того, как он реализован) является Вики для разработчиков GHC и, в частности, ссылку «Комментарий GHC». Если у вас есть достаточно свободного времени, посмотрите серию видеороликов из Портленда. Хакатон GHC 2006 абсолютно захватывающий.

Обратите внимание, что идея написания компилятора на языке, который он компилирует, не является чем-то необычным. Многие компиляторы являются «самостоятельными», что означает, что они написаны на языке, который они компилируют, и предназначены для самостоятельной компиляции. См., например, этот вопрос на другом родственном сайте Stack Exchange: Почему самостоятельные компиляторы считаются обрядом посвящения в новые языки? или просто Google для "самостоятельного компилятора"

Как вы говорите, это «сложно», потому что вам нужен способ запустить процесс. Вот некоторые подходы:

  • Вы можете написать первый компилятор на другом языке, у которого уже есть компилятор (или написать его на ассемблере); затем, когда у вас есть работающий компилятор, вы можете портировать его на тот же язык, который он компилирует. Согласно этому ответу Quora, первый компилятор C был написан таким образом. Он был написан на «NewB», компилятор которого был написан на «B», компиляторе с самостоятельным размещением, который изначально был написан на ассемблере, а затем переписан сам по себе.

  • Если язык достаточно популярен, чтобы иметь другой компилятор, напишите компилятор на его собственном языке и скомпилируйте его поэтапно, сначала с помощью другого компилятора, затем с самим собой (как скомпилировано другим компилятором), затем снова с самим собой (как скомпилировано другим компилятором). сам). Последние два исполняемых файла компилятора можно сравнить как своего рода масштабную проверку правильности компилятора. Компилятор Gnu C может быть скомпилирован таким образом (и это, конечно, был стандартный способ установки из исходного кода, используя для начала [низший!] C-компилятор поставщика).

  • Если интерпретатор, написанный на другом языке, уже существует или его легко написать, интерпретатор может запустить компилятор для компиляции собственного исходного кода, после чего компилируемый компилятор может быть использован для компиляции самого себя. Первый компилятор LISP считается первым компилятор для начальной загрузки таким образом.

Процесс начальной загрузки часто можно упростить, написав компилятор (по крайней мере изначально) на ограниченном ядре языка, даже если сам компилятор способен скомпилировать полный язык. Затем существующий компилятор ниже номинала или упрощенный самозагружающийся компилятор или интерпретатор может запустить процесс.

Согласно записи GHC в Википедии, исходный компилятор GHC был написан в 1989 году на Lazy ML, затем в том же году переписан на Haskell. В наши дни новые версии GHC со всеми их блестящими новыми функциями компилируются на старых версиях GHC.

Ситуация с интерпретатором Python немного отличается. Интерпретатор, конечно, может быть написан на языке, который он интерпретирует, и в мире Лиспа есть много примеров написания интерпретаторов Лиспа на Лиспе (ради развлечения, или при разработке нового диалекта Лиспа, или потому что вы изобретая Лисп), но это не могут быть интерпретаторы на всем пути, так что в конце концов вы d нужен либо компилятор, либо интерпретатор, реализованный на другом языке. В результате большинство интерпретаторов не являются самостоятельными: основные интерпретаторы для Python, Ruby и PHP написаны на C. (Хотя PyPy — это альтернативная реализация интерпретатора Python, написанная на Python, так что...)

10.05.2017
  • GHC можно собрать с помощью флагов, указывающих ему создавать очень неоптимизированные программы на C вместо исполняемых файлов. Вот как это загружается на новых платформах в наши дни. 11.05.2017
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..