Как Clojure подходит к разделению интересов?

Как Clojure подходит к разделению интересов? Поскольку код - это данные, функции можно передавать в качестве параметров и использовать в качестве возвращаемых...

И, поскольку существует этот принцип "Лучше 1000 функций, которые работают на 1 структуре данных, чем 100 функций на 100 структурах данных" (или что-то в этом роде).

Я имею в виду, упаковать все карту, дать ему ключевое слово в качестве ключа, и что это? функции, скаляры, коллекции, все...

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

Как правильно (идиоматически) идти в Clojure, чтобы избежать WTF других программистов _

Ответ 1

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

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

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

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

Кроме того, поддержка Clojure для ленивых структур данных позволяет фактически (промежуточным) структурам данных быть (концептуально) бесконечной по размеру, что делает возможным эту развязку в большинстве сценариев. См. Следующий документ для получения информации о том, почему бесконечная структура данных настолько ценна в этой ситуации: http://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf

Этот подход "трубопровода" может обрабатывать 90% ваших потребностей для разделения проблем. Для остальных 10% вы можете использовать макросы Clojure, которые на высоком уровне можно рассматривать как очень мощный инструмент для аспектно-ориентированного программирования.

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