Являются ли детали реализации декларативных языков по своей природе обязательными - PullRequest
5 голосов
/ 08 февраля 2010

Я читаю «Функциональное программирование» Томаса Петричека и Джона Скита и понимаю разницу между декларативным и императивным программированием.

Мне было интересно, как реализованы примитивные операторы и функции, декларативные языки, построенные из императивных операторов и функций.

Приветствия

AWC

Ответы [ 5 ]

6 голосов
/ 08 февраля 2010

Если я правильно понимаю ваш вопрос, я не думаю, что это жесткое и быстрое правило. Например, вы можете использовать функциональный язык, такой как Lisp, для создания интерпретатора для себя. В этом случае детали реализации реализуются функциональным образом (поскольку Lisp является функциональным языком).

Кроме того, если у вас есть язык Turing Complete, вы можете использовать его для реализации синтаксического анализатора / интерпретатора / компилятора для любого другого языка. Существуют обязательные языки Turing-Complete и функциональные / декларативные языки Turing-Complete.

Но весь код в конечном итоге делается для сборки или машинного кода, что по своей сути является императивом. Теоретически, то, что я сказал выше, верно, но, по-видимому, не на практике:).

Как интересный исторический аспект, LISP был полностью теоретической конструкцией; это была математическая запись для компьютерных языков. Она оставалась теоретической, пока функция LISP eval не была реализована в машинном коде Стивом Расселом на IBM 704:

По словам Пола Грэма из «Хакеров и художников», с. 185. Маккарти сказал: «Стив Рассел сказал, смотри, почему бы мне не запрограммировать этот eval ..., и я сказал ему, хо-хо, ты путаешь теорию с практикой , это eval предназначен для чтения, а не для вычислений . Но он пошел вперед и сделал это. То есть он скомпилировал eval из моей статьи в машинный код IBM 704, исправив ошибку, а затем объявил об этом как интерпретатор Lisp что это, безусловно, было. Так что в тот момент Лисп имел по существу ту форму, которую он имеет сегодня ... " (выделено мной)

Итак, еще раз, тонкости между теорией и практикой. :)

3 голосов
/ 08 февраля 2010

Низкоуровневая машина (ЦП, уровень языка ассемблера) является обязательной, поэтому, очевидно, в какой-то момент реализация должна будет принять это во внимание. Тем не менее, Реализация некоторых видов функциональных языков, таких как Haskell , использует несколько неочевидных подходов для создания среды выполнения с достойной производительностью.

Как ни странно, большинство императивных языков проходит этап, когда весь код преобразуется в более декларативный:

Вот пример компиляции Scheme (функционала) непосредственно в код C (обязательно):

2 голосов
/ 09 февраля 2010

Конструируются ли декларативные языки из императивных операторов и функций?

Иногда. Это свойство реализации , а не языка .

В 1980-х годах многие люди компилировали функциональные программы в графы, а затем переписывали их в более простые графы. Это вычисление обычно включало обновление графиков на месте, но в остальном это было примерно так, как вам хотелось бы. Чтобы узнать больше, посмотрите «Сокращение графика» или прочитайте «Четырехтактный двигатель сокращения» Криса Клака и Саймона Пейтона Джонса.

В конце концов авторы компиляторов нашли способы повысить производительность, компилируя функциональные программы непосредственно в машинный код. Если родная машина является типичной товарной машиной, это означает типичные императивные операции. Однако, если вы посмотрите на новаторскую работу профессора Арвинда в MIT, его группа спроектировала и построила машины потока данных , где основные вычислительные операции носят более декларативный характер. Это была отличная работа, но все специализированные архитектуры, которые процветали в 1980-х годах, были вымерли из-за большого добродетельного цикла Microsoft / Intel (больше программного обеспечения -> больше компьютеров -> более дешевые процессоры -> больше компьютеров -> .. .-> $ 300 нетбуков, которые действительно крутые вещи).

2 голосов
/ 08 февраля 2010

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

Может быть возможно построить машину (с определенной архитектурой), которая по своей природе поддерживает эти операции. Фактически LispM был разработан, чтобы помочь запускать программы на Лиспе. Хотя я не знаком с аппаратными характеристиками LispM, он, вероятно, квалифицируется как предоставление некоторых примитивных операций на более декларативном уровне.

0 голосов
/ 06 января 2016

реализация - это то, что скрыто под капотом. это может быть построено с любой парадигмой.

декларативная программа - это просто данные для ее более или менее "универсальной" императивной реализации / vm.

плюсы: указание только данных в каком-то жестко закодированном (и проверенном) формате проще и менее подвержено ошибкам, чем непосредственное указание варианта какого-либо императивного алгоритма. некоторые сложные спецификации просто не могут быть написаны напрямую, только в некоторой форме DSL. best и freq, используемые в структурах данных DSL - это наборы и таблицы. потому что у вас нет зависимостей между элементами / строками. и когда у вас нет зависимостей, у вас есть свобода изменения и простота поддержки. (сравните, например, модули с классами - с модулями, которые вам нравятся, и с классами, у вас проблема хрупкого базового класса) все товары декларативности и DSL немедленно вытекают из преимуществ этих структур данных (таблиц и наборов). еще один плюс - вы можете изменить реализацию декларативного языка vm, если DSL более-менее абстрактен (хорошо спроектирован). сделать параллельную реализацию, например. или перенести его на другой компьютер и т. д. все хорошо определенные модульные изолирующие интерфейсы или протоколы предоставляют вам такую ​​свободу и простоту поддержки.

минусы: ты угадаешь правильно. реализация универсального (и параметризованного DSL) императивного алгоритма / виртуальной машины может быть медленнее и / или потреблять больше памяти, чем конкретная. в некоторых случаях. если такие случаи редки - просто забудь об этом, пусть будет медленно. если это часто встречается - вы всегда можете расширить свой DSL / vm для этого случая. где-то тормозит все остальные случаи, конечно ...

P.S. Рамки - на полпути между DSL и императивом. и как все промежуточные решения ... они сочетают в себе недостатки, а не выгоды. они не такие безопасные и не такие быстрые :) посмотрите на хаскель мастера на все руки - он на полпути между сильным простым ML и гибким метапрограммой Пролог и ... каким монстром он является. Вы можете смотреть на Пролог как на Haskell с булевыми функциями / предикатами. и как просто его гибкость против Haskell ...

...