2012-06-01 2 views
230

Кажется, что шаблон Haskell часто рассматривается сообществом Haskell как неудачное удобство. Это трудно выразить словами то, что я наблюдал в этом отношении, но рассмотреть эти несколько примеровЧто плохого в шаблоне Haskell?

  • Template Haskell, перечисленные в разделе «Гадкий (но необходимо)» в ответ на вопрос Which Haskell (GHC) extensions should users use/avoid?
  • Template Haskell считается временное/уступало решение в Unboxed Vectors of newtype'd values потоке (библиотеки в списке рассылки)
  • Йесода часто критикуют за слишком полагаясь на Template Haskell (см the blog post в ответ на это настроение)

Я видел разные записи в блогах, где люди делают довольно аккуратные вещи с помощью шаблона Haskell, позволяя более красивый синтаксис, который просто невозможен в регулярном Haskell, а также потрясающее сокращение шаблонов. Так почему же Template Haskell выглядит таким образом? Что делает его нежелательным? При каких обстоятельствах следует избегать шаблона Haskell и почему?

+0

Проголосовало за Close: принадлежит программистам.stackexchange.com - Вопросы и ответы для профессиональных программистов, заинтересованных в концептуальных вопросах разработки программного обеспечения –

+53

Я не согласен с голосованием на переезд; Я задаю этот вопрос в том же духе, что и я спросил: «Что плохого в ленивом I/O?» (Http://stackoverflow.com/questions/5892653/whats-so-bad-about-lazy-io), и я ожидайте увидеть ответы одинаково. Я готов переформулировать вопрос, если это поможет. –

+48

@ErikPhilips Почему бы вам не позволить людям, которые часто посещают этот тег, решить, принадлежит ли это здесь? Кажется, что ваше единственное взаимодействие с сообществом Haskell заключается в том, чтобы задать свои вопросы. –

ответ

158

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

  • У вас нет контроля над тем, какой тип Haskell AST генерирует фрагмент кода TH, за которым он появится; вы можете иметь значение типа Exp, но вы не знаете, является ли это выражением, которое представляет [Char] или (a -> (forall b . b -> c)) или что-то еще. TH было бы более надежным, если бы можно было бы выразить, что функция может генерировать выражения определенного типа или только объявления функций или только шаблоны сопоставления данных и т. Д.
  • Вы можете создавать выражения, которые не компилируются. Вы создали выражение, которое ссылается на свободную переменную foo, которая не существует? Жесткая удача, вы увидите, что при использовании своего генератора кода и только при обстоятельствах, которые вызывают генерацию этого конкретного кода. Также очень сложно провести тестирование на единицу.

TH также прямо опасно:

  • код, который работает во время компиляции может сделать произвольную IO, в том числе запуск ракеты или кражи вашей кредитной карты. Вы не хотите просматривать каждый пакет, который вы когда-либо скачивали, в поисках эксплойтов TH.
  • TH может получить доступ к «модулям-частным» функциям и определениям, полностью нарушая инкапсуляцию в некоторых случаях.

Тогда есть некоторые проблемы, которые делают функции TH менее интересно использовать в качестве разработчика библиотеки:

  • код ТН не всегда компонуем. Предположим, что кто-то делает генератор для объективов, и чаще всего этот генератор будет структурирован таким образом, что он может быть вызван непосредственно «конечным пользователем», а не другим кодом TH, например, принимая список конструкторов типов для генерации объективов в качестве параметра. Трудно сгенерировать этот список в коде, в то время как пользователю нужно написать только generateLenses [''Foo, ''Bar].
  • Разработчики даже не знают, что код TH может быть составлен.Знаете ли вы, что можете написать forM_ [''Foo, ''Bar] generateLens? Q - это просто монада, поэтому вы можете использовать на ней все обычные функции. Некоторые люди этого не знают, и из-за этого они создают несколько перегруженных версий, по существу, с теми же функциями с одинаковой функциональностью, и эти функции приводят к определенному эффекту вздутия. Кроме того, большинство людей пишут свои генераторы в монаде Q, даже если им это не нужно, это похоже на запись bla :: IO Int; bla = return 3; вы предоставляете функцию более «окружения», чем она требуется, и клиенты этой функции должны обеспечивать эту среду как результат этого.

Наконец, есть некоторые вещи, которые делают функции TH менее интересно использовать в качестве конечного пользователя:

  • непрозрачности. Когда функция TH имеет тип Q Dec, она может генерировать абсолютно что-либо на верхнем уровне модуля, и вы абсолютно не контролируете то, что будет сгенерировано.
  • Монолитизм. Вы не можете контролировать, какая функция TH генерируется, если разработчик не позволяет это; если вы найдете функцию, которая генерирует интерфейс базы данных и интерфейс сериализации JSON, вы не можете сказать «Нет, мне нужен интерфейс базы данных, спасибо, я откажу свой собственный интерфейс JSON»
  • Время работы. Код TH занимает относительно много времени для запуска. Код интерпретируется заново каждый раз, когда файл скомпилирован, и часто для исполняемого кода TH требуется тонна пакетов, которые необходимо загрузить. Это значительно замедляет время компиляции.
+4

Добавьте к этому факт, что шаблон-haskell исторически был очень плохо документирован. (Хотя я только что посмотрел снова, и кажется, что сейчас, по крайней мере, немного лучше.) Кроме того, чтобы понять шаблон-haskell, вам по существу нужно понять грамматику языка Haskell, которая накладывает определенную сложность (это не схема). Эти две вещи способствовали тому, что я намеренно не потрудился понять TH, когда был новичком Хаскелла. – mightybyte

+11

Не забывайте, что использование шаблона Haskell suddently означает порядок заявлений! TH просто не интегрирован так сильно, как можно было бы надеяться, учитывая гладкий блеск Haskell (будь то 1.4, '98, 2010 или даже Glasgow). –

+12

Вы можете рассуждать о Haskell без особых трудностей, нет никакой гарантии о шаблоне Haskell. – augustss

27

Я хотел бы обратиться к нескольким пунктам, которые поднимает dflemstr.

Я не считаю факт, что вы не можете проверить тип TH, чтобы это беспокоиться. Зачем? Потому что, даже если есть ошибка, все равно будет время компиляции. Я не уверен, что это усиливает мои аргументы, но это по духу аналогично ошибкам, которые вы получаете при использовании шаблонов на C++. Я думаю, что эти ошибки более понятны, чем ошибки C++, хотя вы получите довольно печатную версию сгенерированного кода.

Если выражение TH/квазициклер делает то, что настолько продвинуто, что хитрые углы могут скрыть, то, возможно, это не рекомендуется?

Я очень сильно нарушаю это правило с квазициклирами, с которыми я работал в последнее время (используя haskell-src-exts/meta) - https://github.com/mgsloan/quasi-extras/tree/master/examples. Я знаю, что это приводит к некоторым ошибкам, таким как невозможность сплайсинга в обобщенных списках. Тем не менее, я думаю, что есть хороший шанс, что некоторые идеи в http://hackage.haskell.org/trac/ghc/blog/Template%20Haskell%20Proposal попадут в компилятор. До тех пор библиотеки для разбора Haskell на деревьях TH являются почти идеальным приближением.

Что касается скорости/зависимостей компиляции, мы можем использовать пакет «нуль» для встраивания сгенерированного кода. Это, по крайней мере, хорошо для пользователей данной библиотеки, но мы не можем сделать намного лучше для редактирования библиотеки. Может ли TH-зависимости раздуваться сгенерированными двоичными файлами? Я думал, что это исключено из всего, на что не ссылается скомпилированный код.

Пространственное ограничение/разделение шагов компиляции модуля Haskell действительно сосать.

RE Непрозрачность: это то же самое для любой функции библиотеки, которую вы вызываете. У вас нет контроля над тем, что сделает Data.List.groupBy. У вас просто есть разумная «гарантия»/соглашение о том, что номера версий сообщают вам что-то о совместимости. Это может быть и другое изменение.

Здесь вы можете использовать нулевое значение - вы уже управляете сгенерированными файлами - так что вы всегда будете знать, когда изменилась форма сгенерированного кода. Глядя на diffs, возможно, это немного грубо, но для больших объемов сгенерированного кода это одно место, где удобнее будет интерфейс разработчика.

RE Монолитизм: вы можете, конечно, выполнить обработку выражения TH, используя свой собственный код времени компиляции. Кодирование кода не должно быть очень сильным для типа/имени декларации верхнего уровня. Черт, вы могли бы представить себе функцию, которая делает это в целом. Для модификации/де-монолитизации квазиквадраторов вы можете сопоставлять совпадение на «QuasiQuoter» и извлекать использованные преобразования или создавать новый с точки зрения старого.

+1

Относительно ** Непрозрачность/Монолитизм: ** Вы можете, конечно, пройти через '[Dec]' и удалить ненужные вещи, но предположим, что функция считывает файл внешнего определения при создании интерфейса JSON. Просто потому, что вы не используете этот 'Dec', он не заставит генератора прекратить поиск файла определения, что приведет к сбою компиляции. По этой причине было бы неплохо иметь более ограничительную версию монадии 'Q', которая позволила бы вам генерировать новые имена (и такие вещи), но не разрешать' IO', чтобы, как вы говорите, можно было фильтровать его результаты/делают другие композиции. – dflemstr

+1

Согласен, должна быть версия Q/цитата, отличная от IO! Это также поможет решить проблему - http://stackoverflow.com/questions/7107308/why-doesnt-safe-haskell-support-template-haskell. После того, как вы убедитесь, что код времени компиляции не делает ничего небезопасного, кажется, что вы можете просто запустить средство проверки безопасности в полученном коде и убедиться, что он не ссылается на личные вещи. – mgsloan

+1

Вы когда-нибудь писали о своем контраргументе? Все еще ждет обещанная вами ссылка. Для тех, кто ищет старое содержимое этого ответа: http://stackoverflow.com/revisions/10859441/1, а также для тех, кто может просматривать удаленный контент: http://stackoverflow.com/revisions/10913718/6 –

47

Это единственное мое мнение.

  • Это некрасиво в использовании. $(fooBar ''Asdf) просто не выглядит красиво. Поверхностно, конечно, но это способствует.

  • Это даже уродливее писать. Иногда цитаты работают, но в то же время вы должны выполнять ручную трансплантацию АСТ и сантехнику. API большой и громоздкий, всегда есть много случаев, о которых вам не безразлично, но все равно нужно отправлять, а случаи, о которых вы заботитесь, как правило, присутствуют в нескольких похожих, но не идентичных формах (данные против newtype, record - стиль против обычных конструкторов и т. д.). Это скучно и повторяемо, чтобы писать и усложнять, чтобы не быть механическим. reform proposal обращается к некоторым из них (более широко применяются котировки).

  • Сценическое ограничение - это ад. Невозможность сплайсинга функций, определенных в том же модуле, - это меньшая его часть: другим следствием является то, что если у вас есть сращивание на верхнем уровне, все после него в модуле будет вне видимости чего-либо перед ним. Другие языки с этим свойством (C, C++) делают его работоспособным, позволяя вам пересылать объявления, но Haskell этого не делает. Если вам нужны циклические ссылки между объявлениями сплайсинга или их зависимостями и иждивенцами, вы обычно просто ввернуты.

  • Это недисциплинированный. Я имею в виду, что большую часть времени, когда вы выражаете абстракцию, для этой абстракции есть какой-то принцип или понятие. Для многих абстракций принцип, лежащий в их основе, может быть выражен в их типах. Для классов типов вы часто можете формулировать законы, которые должны соблюдаться, и клиенты могут предполагать. Если вы используете GHC new generics feature, чтобы абстрагировать форму объявления экземпляра по любому типу данных (в пределах границ), вы можете сказать «для типов сумм, он работает, как это, для типов продуктов, он работает так». Шаблон Haskell, с другой стороны, это просто макросы. Это не абстракция на уровне идей, а абстракция на уровне АСТ, которая лучше, но лишь скромно, чем абстракция на уровне обычного текста. *

  • Это связывает вас с GHC. Теоретически другой компилятор мог бы его реализовать, но на практике я сомневаюсь, что это когда-нибудь произойдет. (Это противоречит разным типам системных расширений, которые, хотя они могут быть реализованы только GHC на данный момент, я легко мог представить, что их приняли другие компиляторы по дороге и в конечном итоге стандартизированы.)

  • API isn ' t стабильный. Когда новые функции языка добавляются в GHC, а пакет template-haskell обновляется для их поддержки, это часто включает в себя обратные несовместимые изменения типов данных TH. Если вы хотите, чтобы ваш код TH был совместим с более чем одной версией GHC, вам нужно быть очень осторожным и, возможно, использовать CPP.

  • Существует общий принцип, согласно которому вы должны использовать правильный инструмент для задания и наименьший из них, который будет достаточным, и в этой аналогии шаблон Haskell равен something like this. Если есть способ сделать это, это не Template Haskell, это обычно предпочтительнее.

Преимущество Template Haskell является то, что вы можете сделать что-то с тем, что вы не могли бы сделать по-другому, и это большой один. В большинстве случаев вещи, для которых используется TH, в противном случае могут быть выполнены только в том случае, если они были реализованы непосредственно как функции компилятора. TH чрезвычайно полезно иметь и то, и другое, потому что он позволяет вам делать это, и потому, что он позволяет вам прототипировать потенциальные расширения компилятора гораздо более легким и многоразовым способом (см., Например, различные пакеты объективов).

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

* Хотя я часто чувствую, что CPP имеет лучшее соотношение мощности к весу для тех проблем, которые он может решить.

EDIT 23-04-14: То, что я часто пытаюсь понять в приведенном выше, и только недавно получил точно, заключается в том, что существует важное различие между абстракцией и дедупликацией. Правильная абстракция часто приводит к дедупликации как побочному эффекту, а дублирование часто является признаком неадекватной абстракции, но это не значит, что это ценно. Надлежащая абстракция - это то, что делает код правильным, понятным и поддерживаемым. Дедупликация только делает ее короче. Шаблон Haskell, как и макросы в целом, является инструментом для дедупликации.

13

Этот ответ в ответ на вопросы, воспитанных illissius, точка за точкой:

  • Это некрасиво использовать. $ (fooBar '' Asdf) просто не выглядит красиво. Поверхностно, конечно, но это способствует.

Я согласен. Мне кажется, что $() выбрано так, чтобы выглядеть как часть языка - используя знакомый поддон Haskell. Тем не менее, это именно то, что вы/не хотите/не хотите в символах, используемых для сращивания макросов. Они определенно сливаются в слишком много, и этот косметический аспект очень важен. Мне нравится внешний вид {{}} для сращиваний, потому что они довольно визуально различны.

  • Это даже уродливее, чтобы писать. Иногда цитаты работают, но в то же время вы должны выполнять ручную трансплантацию АСТ и сантехнику. [API] [1] большой и громоздкий, всегда есть много случаев, о которых вам неинтересно, но их еще нужно отправить, а случаи, о которых вы заботитесь, обычно присутствуют в нескольких похожих, но не идентичных формах (данные vs newtype, стиль записи и обычные конструкторы и т. д.). Это скучно и повторяемо, чтобы писать и усложнять, чтобы не быть механическим. [Предложение по реформированию] [2] затрагивает некоторые из этих вопросов (более широко применимые котировки).

Я также согласен с этим, однако, так как некоторые из комментариев в «Новые направления TH» наблюдать, отсутствие хорошего из-из-коробки AST цитируйте не является критическим недостатком.В этом пакете WIP я пытаюсь решить эти проблемы в библиотечной форме: https://github.com/mgsloan/quasi-extras. До сих пор я разрешаю сращивание в нескольких местах, чем обычно, и может сопоставлять образцы по AST.

  • Сценическое ограничение - это ад. Невозможность сплайсинга функций, определенных в том же модуле, - это меньшая его часть: другим следствием является то, что если у вас есть сращивание на верхнем уровне, все после него в модуле будет вне видимости чего-либо перед ним. Другие языки с этим свойством (C, C++) делают его работоспособным, позволяя вам пересылать объявления, но Haskell этого не делает. Если вам нужны циклические ссылки между объявлениями сплайсинга или их зависимостями и иждивенцами, вы обычно просто ввернуты.

Я столкнулся с вопросом циклических определений TH будучи невозможно до ... Это очень раздражает. Существует решение, но оно уродливо - обертывание вещей, связанных с циклической зависимостью в выражении TH, которое объединяет все сгенерированные объявления. Один из этих генераторов объявлений может быть просто квазициклером, который принимает код Haskell.

  • Это беспринципный. Я имею в виду, что большую часть времени, когда вы выражаете абстракцию, для этой абстракции есть какой-то принцип или понятие. Для многих абстракций принцип, лежащий в их основе, может быть выражен в их типах. Когда вы определяете класс типа, вы часто можете формулировать законы, которые должны подчиняться, и клиенты могут принять их. Если вы используете функцию [new generics feature] GHC [3], чтобы абстрагировать форму объявления экземпляра по любому типу данных (в пределах границ), вы можете сказать «для типов сумм, он работает, как это, для типов продуктов, он работает так ». Но Template Haskell - это просто немые макросы. Это не абстракция на уровне идей, а абстракция на уровне АСТ, которая лучше, но лишь скромно, чем абстракция на уровне обычного текста.

Это только беспринципный, если вы беспринципных вещи с ним. Единственное отличие заключается в том, что при компиляторе реализованы механизмы абстракции, у вас больше уверенности в том, что абстракция не является протекающей. Возможно, демократизация языкового дизайна звучит немного страшно! Создатели библиотек TH должны хорошо документировать и четко определять смысл и результаты инструментов, которые они предоставляют. Хорошим примером принципиального TH является производный пакет: http://hackage.haskell.org/package/derive - он использует DSL, такой, что пример многих дериваций/указывает/фактический вывод.

  • Это связывает вас с GHC. Теоретически другой компилятор мог бы его реализовать, но на практике я сомневаюсь, что это когда-нибудь произойдет. (Это в отличии от различных систем типа расширений, которые, хотя они могут быть реализованы только GHC на данный момент, я мог бы легко себе представить, принимаемые другими компиляторами вниз по дороге и в конце концов стандартизированы.)

Это довольно хороший момент - TH API довольно большой и неуклюжий. Повторное внедрение кажется, что это может быть жестким. Тем не менее, существует всего лишь несколько способов разрезать проблему представления Haskell AST. Я предполагаю, что копирование TH ADT и запись конвертера во внутреннее представление AST обеспечили бы вам много пути. Это было бы эквивалентно (не несущественному) усилию создания haskell-src-meta. Его также можно было бы просто переделать, напечатав TH AST и используя внутренний синтаксический анализатор компилятора.

Хотя я мог ошибаться, я не вижу, чтобы TH был настолько сложным из расширения компилятора, с точки зрения реализации.Это на самом деле одно из преимуществ «поддержания его простоты» и не имеющего фундаментального уровня как теоретически привлекательной, статически проверяемой системы шаблонов.

  • API нестабилен. Когда новые функции языка добавляются в GHC, а пакет template-haskell обновляется для их поддержки, это часто включает в себя обратные несовместимые изменения типов данных TH. Если вы хотите, чтобы ваш код TH был совместим с более чем одной версией GHC, вам нужно быть очень осторожным и, возможно, использовать CPP.

Это также хороший момент, но несколько драматизированный. Несмотря на то, что в последнее время были добавлены API, они не подвергались экстенсивно обрыву. Кроме того, я думаю, что с вышеизложенным выше, упомянутым мной ранее, API, который действительно должен использоваться, может быть значительно сокращен. Если никакая конструкция/соответствие не нуждается в различных функциях и вместо этого выражаются как литералы, тогда большая часть API исчезает. Более того, код, который вы пишете, будет легче переноситься в представления AST для языков, подобных Haskell.


Таким образом, я считаю, что TH является мощным, полузапускаемым инструментом. Меньшая ненависть может привести к более оживленной экосистеме библиотек, поощряя внедрение более языковых прототипов. Было замечено, что TH является мощным инструментом, который может позволить вам/делать/почти что угодно. Анархия! По моему мнению, эта сила может позволить вам преодолеть большинство своих ограничений и построить системы, способные к совершенно принципиальным подходам метапрограммирования. Стоит использовать уродливые хаки для имитации «правильной» реализации, так как таким образом дизайн «правильной» реализации постепенно станет ясным.

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

Каков типичный ответ Haskell на шаблонный код? Абстракция. Какие наши любимые абстракции? Функции и модели.

Typeclasses позволяет определить набор методов, которые затем могут использоваться во всех функциях, общих для этого класса. Однако, кроме этого, единственный способ, которым классы помогают избежать шаблона, - это предлагать «определения по умолчанию». Теперь вот пример беспринципной функции!

  • Минимальные наборы сложения не подлежат декларированию/компилятору. Это может привести к непреднамеренным определениям, которые дают дно из-за взаимной рекурсии.

  • Несмотря на большое удобство и мощность, это может привести к тому, что вы не можете указать значения по умолчанию для суперкласса из-за сиротских экземпляров http://lukepalmer.wordpress.com/2009/01/25/a-world-without-orphans/ Это позволит нам исправить числовую иерархию изящно!

  • Переход на TH-подобные возможности для значений по умолчанию метода привел к http://www.haskell.org/haskellwiki/GHC.Generics. Хотя это классный материал, мой единственный опыт отладки кода с использованием этих дженериков был практически невозможным из-за размера индуцированного типа и ADT, такого сложного, как AST. https://github.com/mgsloan/th-extra/commit/d7784d95d396eb3abdb409a24360beb03731c88c

    Другими словами, это продолжалось после функций, предоставляемых TH, но ему пришлось поднять весь домен языка, язык конструкции, в системное представление типа. Хотя я вижу, что это хорошо работает для вашей общей проблемы, для сложных, кажется, склонно уступать кучу символов, гораздо более ужасающих, чем TH-хакерство.

    TH дает вам вычисление выходного кода на уровне значений, тогда как generics заставляет вас поднять часть соответствия шаблону/рекурсии кода в систему типов. Хотя это и ограничивает пользователя несколькими довольно полезными способами, я не думаю, что это стоит того.

Я думаю, что отказ от TH и сюсюкать-как метапрограммированием привел к предпочтению к вещам, как метод дефолт вместо более гибкого, макро-расширение, как декларации экземпляров. Дисциплина избегать вещей, которые могут привести к непредсказуемым результатам, разумна, однако мы не должны игнорировать, что система Haskell, способная к типу, позволяет более надежное метапрограммирование, чем во многих других средах (путем проверки сгенерированного кода).

+4

Этот ответ не выдерживает само по себе очень хорошо: вы делаете кучу ссылок на другой ответ, который мне нужно найти и найти, прежде чем я смогу правильно читать ваши. –

+0

Это правда. Я попытался дать понять, о чем говорили, несмотря на это. Возможно, я отредактирую на строчки иллисиса. – mgsloan

+0

Я должен сказать, что, возможно, «беспринципный» - это более сильное слово, чем я должен был использовать, с некоторыми коннотациями, которые я не собирался, - это, конечно, не бессовестно! Эта точка с пулями была той, с которой я столкнулся, потому что у меня есть это чувство или неоформленная идея в голове, и я не могу выразить ее словами, а «беспринципный» был одним из тех слов, которые я понял, где-то поблизости. «Дисциплинированный», вероятно, ближе. Не имея четкой и сукцитной формулировки, я пошел вместо некоторых примеров. Если кто-то может объяснить мне более ясно, что я, вероятно, имел в виду, я был бы признателен! – glaebhoerl

7

Одна довольно прагматичная проблема с Template Haskell заключается в том, что она работает только тогда, когда доступен интерпретатор байт-кода GHC, что не относится ко всем архитектурам. Поэтому, если ваша программа использует Template Haskell или полагается на библиотеки, которые ее используют, она не будет работать на компьютерах с процессорами ARM, MIPS, S390 или PowerPC.

Это на практике применимо: git-annex - это инструмент, написанный на Haskell, который имеет смысл запускать на машинах, которые беспокоятся о хранении, такие машины часто имеют не-i386-CPU. Лично я запускаю git-приложение на NSLU 2 (32 МБ ОЗУ, 266 МГц, вы знаете, что Haskell отлично работает на таком оборудовании?) Если он будет использовать Template Haskell, это невозможно.

(Ситуация с GHC на ARM улучшается в наши дни, и я думаю, что 7.4.2 даже работает, но точка все еще стоит).

+0

... TH отлично работает без интерпретатора. – muhmuhten

+1

«Шаблон Haskell полагается на встроенный компилятор и интерпретатор байт-кода GHC для запуска выражений сплайсинга». - http://www.haskell.org/ghc/docs/7.6.2/html/users_guide/template-haskell.html –

+1

ах, я что - нет, TH не будет работать без интерпретатора байт-кода, но это отличается от (хотя и актуальным) ghci. Я бы не удивился, если бы была идеальная связь между доступностью ghci и доступностью интерпретатора байт-кода, учитывая, что ghci действительно зависит от интерпретатора байт-кода, но проблема в том, что отсутствует интерпретатор байт-кода, а не отсутствие ghci в частности. – muhmuhten

5

Почему это плохо? Для меня это сводится к следующему:

Если вам нужно произвести столько повторяющийся код, который вы найдете сами пытаются использовать TH для автоматического создания его, вы делаете это неправильно!

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

Иногда, конечно, это необходимо. Но иногда вы можете избежать необходимости в TH, просто будучи немного более умным с вашими проектами.

(Другое дело, что TH довольно низкий уровень Там нет грандиозного проекта высокого уровня;. Много внутренних деталей реализации GHC, подвергаются и что делает API подвержено изменениям ....)

+0

Я не думаю, что это означает, что ваш язык или приложение вам не удалось, особенно если мы рассмотрим QuasiQuotes. Всегда есть компромиссы, когда дело доходит до синтаксиса. В некотором синтаксисе лучше описывается определенный домен, поэтому вы хотите иногда переключаться на другой синтаксис. QuasiQuotes позволяет вам элегантно переключаться между синтаксисами. Это очень мощный и используется Yesod и другими приложениями. Возможность писать код генерации HTML с использованием синтаксиса, который похож на HTML, является удивительной особенностью. – CoolCodeBro

+0

@CoolCodeBro Да, квазицитирование довольно приятное, и я полагаю, что он немного ортогонален TH. (Очевидно, что это реализовано поверх TH.) Я думал больше об использовании TH для генерации экземпляров класса или создания функций из нескольких явлений или что-то в этом роде. – MathematicalOrchid

Смежные вопросы