svv

Out of the Tar Pit, FRP

Sep 19, 2009 02:18

(про программирование)
Недавно в рассылке clojure один человек задал вопрос, как лучше моделировать data associations. Мол, так пробовал, эдак пробовал - всё неудобно, научите меня, гуру, как это по-правильному, по-функциональному. На что функциональные гуру ему ответили: о-о, брат, это ты ему столкнулся с так называемой real world problem ;-)
Потом, впрочем, дали ссылку на интересную статью «Out of the Tar Pit», про functional relational programming (see also http://lambda-the-ultimate.org/node/1446), с несколько неожиданным вниманием к реляционности (привет, Vietnam of computer science). Статья длинная, поэтому я её на всякий случай законспектировал.
Начинается всё про борьбу со сложностью в ПО. Основные проблемы: state и control. Автор рассматривает три подхода: объектно-ориентированное, функциональное и логическое программирование, у них получаются разные implications для этих двух проблем, со своими понятными проблемами (OO инкапсулирует state, control произвольно размазывается, ФП отвергает state, ЛП отвергает control, но в реальности приходится идти на компромисс (прологовский cut) и т.д.).
Далее он разделяет сложность на essential (inherently присутствующую в решаемой проблеме, как она видна для пользователя) и accidental (которая возникает из-за ограничений используемой среды или из-за всяких там оптимизаций). E.g., если мы делаем кеширование, получается акцидентный state, а если императивно оптимизируем какую-то выборку или преобразование, где формально достаточно декларативного выражения, то это акцидентный control. Теоретически всё может работать без таких акцидентных артефактов, просто это, возможно, будет слишком медленно работать.
Большая часть сложности, если посмотреть внимательно - не содержательная (essential), а акцидентная. Полностью от акцидентной сложности избавиться невозможно даже в идеальной среде, но можно использовать тактику separate/avoid.
Первый план архитектуры, которую он предлагает, такой (картинка на стр. 35). Делим систему на три части: (1) accidental logic/state, (2) essential logic («business logic», if you will), (3) essential state. Зависимости: (1) → (3), (2) → (3). Т.е. изменение (3) потребует изменения и (1) и (2), а изменение (1) других изменений не влечёт.
Потом автор рассказывает, какая замечательная штука реляционная модель - тамошняя структура допускает любые access paths (в отличие от XML или OO), для малипуняций есть реляционная алгебра, туда можно легко добавлять ограничения, обеспечивающие integrity и она даёт абстракцию от физического хранения.
И предлагается второй план архитектуры (стр. 43).
  1. В основе, как и раньше, лежит essential state - реляционная структура (не в смысле SQL/база, это может быть прямо в памяти, но работа с состоянием осуществляется в рамках реляционной модели). Там живёт исключительно тот essential для пользователя state, ничего производного.
  2. Essential logic состоит из двух частей: pure functions и реляционная логика. К последней относятся определения derived relations (т.е. «views», а base relations живут в essential state) и integrity constraints. Никакая оптимизация здесь недопустима, с одной стороны, потому что это суть подхода separate/avoid [complexity] (она будет в другой части системы), а с другой - потому что на этом уровне абстракции мы ничего не знаем о том, как и где что будет храниться, поэтому и оптимизировать ничего не можем.
  3. Accidental logic/state - это декларативные «hints», при помощи которых инфраструктура, на которой вся эта система работает, будет обеспечивать настройку их работы. Например, можно потребовать кешировать или индексировать какую-то функцию (они pure), или индексировать какие-то данные, или добавить императивности в помощь вычислению логического выражения. Здесь же будет описано отображение state на физическое хранилище, если это нужно.
  4. Последний компонент - это feeders/observers для взаимодействия со внешними системами. Feeders умеют модифицировать essential state, а observers отслеживать изменения в essential и derived state.
В конце даже приводится небольшой пример системы и того, что идёт в какие из четырёх частей.
Всё это называется Functional Relational Programming. Автор признаёт, что это все теоретизирование, на практике не испытано (хотя они и написали инфраструктуру в полторы тыщи строк на Scheme) (впрочем, статья 2006 года) (правда, с тех пор никаких новостей), но зато все базовые идеи известные и проверенные временем.
Previous post Next post
Up