Подтвердить что ты не робот

В clojure, когда мы должны использовать монаду вместо макроса и наоборот?

Есть слишком много учебников на монадах, которые говорят... "Послушайте, вот случай, когда мы можем использовать монаду" или "Это то, для чего монада". То, что я хочу знать, это то, что некоторые из шагов, которые люди используют, чтобы прийти к выводу, что они могут сказать себе: "Джи Виз! Похоже, мы можем использовать монаду здесь!"

Итак, когда кто-то говорит мне... "(blah) не имеет ничего общего с монадой...", это действительно не помогает мне ответить на мой вопрос:

  • Как мне определить, какие шаблоны в программах могут быть выражены с помощью монад?
  • Как я могу написать свою собственную индивидуальную монаду, когда я определил потенциал для их использования?

Я начал очень длинный вопрос здесь о монадах, если кому-то интересно помочь - Карта и Сократить Монаду для Clojure... Как насчет Монастыря Юкш?.

Вернуться к этому вопросу:

Когда мы должны использовать монаду вместо макроса и наоборот?

  • Я читал статьи и смотрел презентации, которые говорят... "Монады используются для абстракции DSL".... но большинство библиотек DSL1 (w121) (например, hiccup и korma) используют defmacro, и он работает Великий.

И зачем нам нужны монады в clojure, если у нас есть макросы?

4b9b3361

Ответ 1

Я использую Clojure уже два года, и единственный раз, когда я когда-либо использовал монады, было упражнением, чтобы показать, что это можно сделать. Я никогда не нуждался в них для "реального" кода.

Монады гораздо чаще встречаются в Haskell, потому что:

  • Это идиоматический способ обработки вычислений с учетом состояния. В Clojure вы обычно обрабатываете состояние с управляемыми ссылками, поэтому монады не нужны почти столько же в Clojure.
  • Аналогично для IO: Clojure позволяет выполнять IO напрямую, не объявляя его в вашем типе, поэтому вам не нужна монашка IO.

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

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

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

P.S. Если вы искренне заинтересованы в монадах для Clojure, вот два видео, которые я лично нашел неплохо:

Ответ 2

Монады и макросы не имеют ничего общего. Они используются для решения различных задач. В Clojure библиотека monad широко использует макросы для реализации синтаксического "пользовательского интерфейса" для монадов. Вы можете использовать монады для функциональной реализации некоторой библиотеки, а затем добавить слой макросов для внешнего интерфейса.

Что касается "когда можно использовать монады в Clojure", я вижу два варианта использования:

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

2) Чтобы реализовать композиционный метод, который можно сформулировать как монаду, чтобы  прибыль от существующей инфраструктуры монады.

Clojure имеет две встроенные монады, "пусть" (идентичная монада) и "для" (последовательность монада). Всякий раз, когда вы хотите, чтобы вы могли подключить один из них к вашему коду позже, вы должны использовать вместо него "domonad". И всякий раз, когда вы хотите, чтобы у вас было что-то подобное, но не совсем то же самое, вам следует подумать о написании своей собственной монады.

Это, к сожалению, довольно абстрактно. В настоящее время не так много опубликованных и полированных примеров кода, которые используют монад в Clojure. Поскольку больше Кложурийцев знакомятся с монадами и другими экспертами монады (обычно из Хаскелла), используйте Clojure, это, вероятно, изменится. Например, я видел (но не имею) монодичный синтаксический анализ, сделанный в Clojure.

Ответ 3

@khinsen и @mikera так хорошо ответили на вопрос, что вряд ли будут делать какие-либо дополнительные комментарии, но я думаю, что они пропустили один пункт (или я не мог найти его в своих комментариях).

В Clojure макросы являются частью языка. Используйте их или нет, но они есть. На самом деле, у вас часто не будет выбора, кроме как использовать их, поскольку они делают ваши приложения более идиоматичными (что является особенностью профессионального использования любого языка). Они позволяют предварительно обрабатывать структуры данных, составляющие приложение. Они сродни конструкциям других языков в том смысле, в каком они включены независимо от ваших потребностей.

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

Что касается вашего вопроса, макросы работают до того, как монад когда-нибудь запустится. Макросы работают на этапе компиляции - они меняют структуры данных на другие структуры данных. Монады - это шаблон проектирования для составления вычислений. Это различие. В Clojure монады записываются с использованием макросов (чтобы облегчить их использование), и поэтому люди склонны говорить, что вы можете делать с монадами, которых вы легко могли бы достичь с помощью макросов. Это правда, поскольку оно выходит из дизайна монадов в Clojure, но то же самое можно сказать и о самих макросах. Вам больше не нужно писать новые, а первое правило в клубе макросов - вообще не писать их, но все же они являются часть языка, и вы должны быть хорошо осведомлены о своих приложениях.

См. Как программисты Clojure используют макросы? для более подробного обсуждения макросов.