Я очень долго думал над этим вопросом, но действительно не смог найти ответа в Google, а также на аналогичный вопрос в Stackoverflow. Если есть дубликат, прошу прощения за это.
Многие люди, кажется, говорят, что написание компиляторов и других языковых инструментов на функциональных языках, таких как OCaml и Haskell, намного эффективнее и проще, чем написание их на императивных языках.
Это правда? И если да, то почему так эффективно и легко писать их на функциональных языках, а не на императивном языке, таком как C? Кроме того - разве языковой инструмент на функциональном языке не медленнее, чем на каком-то низкоуровневом языке, таком как C?
Ответы:
Часто компилятор много работает с деревьями. Исходный код анализируется в синтаксическом дереве. Затем это дерево может быть преобразовано в другое дерево с аннотациями типов для проверки типов. Теперь вы можете преобразовать это дерево в дерево, содержащее только элементы ядра языка (преобразование синтаксических нотаций, подобных сахару, в несахарную форму). Теперь вы можете выполнять различные оптимизации, которые в основном представляют собой преобразования дерева. После этого вы, вероятно, создадите дерево в некоторой нормальной форме, а затем выполните итерацию по этому дереву, чтобы создать целевой (сборочный) код.
Функциональный язык имеет такие функции, как сопоставление с образцом и хорошую поддержку эффективной рекурсии, что упрощает работу с деревьями, поэтому они обычно считаются хорошими языками для написания компиляторов.
источник
Многие задачи компилятора - это сопоставление с образцом в древовидной структуре.
И OCaml, и Haskell обладают мощными и краткими возможностями сопоставления с образцом.
В императивные языки сложнее добавить сопоставление с образцом, поскольку любое значение, которое оценивается или извлекается для сопоставления с образцом, должно быть без побочных эффектов.
источник
Один важный фактор, который следует учитывать, заключается в том, что большая часть любого проекта компилятора - это когда вы можете самостоятельно разместить компилятор и «съесть свою собачью еду». По этой причине, когда вы смотрите на такие языки, как OCaml, где они разработаны для языковых исследований, они, как правило, имеют отличные возможности для решения проблем типа компилятора.
В моей последней работе в стиле компилятора мы использовали OCaml именно по этой причине при манипулировании кодом C, это был просто лучший инструмент для этой задачи. Если бы люди из INRIA создали OCaml с другими приоритетами, он бы не подошел.
Тем не менее, функциональные языки - лучший инструмент для решения любой проблемы, поэтому логически следует, что они являются лучшим инструментом для решения этой конкретной проблемы. QED.
/ me: ползет назад к своим Java-задачам чуть менее радостно ...
источник
По сути, компилятор - это преобразование одного набора кода в другой - от источника к IR, от IR к оптимизированному IR, от IR к ассемблеру и т. Д. Это именно то, для чего предназначены функциональные языки - чистая функция просто превращение одного в другое. Императивные функции не обладают этим качеством. Хотя вы можете написать такой код на императивном языке, функциональные языки специализируются на этом.
источник
Смотрите также
Шаблон проектирования F #
FP группирует вещи «по операции», тогда как OO группирует вещи «по типу», и «по операции» более естественно для компилятора / интерпретатора.
источник
Одна из возможностей состоит в том, что компилятору приходится очень тщательно разбираться с множеством угловых случаев. Правильный код часто упрощается за счет использования шаблонов проектирования, которые структурируют реализацию таким образом, чтобы они соответствовали правилам, которые она реализует. Часто это заканчивается декларативным (сопоставление с образцом, «где»), а не императивным (последовательность, «когда») дизайном, и, таким образом, его легче реализовать на декларативном языке (а большинство из них являются функциональными).
источник
Похоже, все упустили еще одну важную причину. Достаточно легко написать встроенный предметно-ориентированный язык (EDSL) для парсеров, которые в обычном коде очень похожи на (E) BNF. Комбинаторы синтаксического анализатора, такие как Parsec, довольно легко написать на функциональных языках, используя функции высшего порядка и композицию функций. Не только проще, но и очень элегантно.
По сути, вы представляете самые простые общие синтаксические анализаторы как просто функции, и у вас есть специальные операции (обычно функции более высокого порядка), которые позволяют вам составлять эти примитивные синтаксические анализаторы в более сложные, более конкретные синтаксические анализаторы для вашей грамматики.
Конечно, это не единственный способ создать более ранние фреймворки.
источник