metaclass: (Default)
metaclass ([personal profile] metaclass) wrote2009-11-18 05:11 pm

Опердень и паттерн-матчинг.

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

И есть набор правил, согласно которым эта таблица раскладывается по статьям некоего выходного отчета который ложится на стол Президенту РБ, т.е. к примеру "все проводки с типом операции 126 относятся на статью затрат "Цех забоя и переработки свинины", за исключением проводок со счета 91, который относится на статью затрат "Цех забоя и переработки лошадей"". В таких правилах обычно проверяется где-то 5-10 условий на значения полей записи операции, самих правил может быть порядка сотни штук. И правила могут меняться, например в 2008 году переработка лошадей и свиней делилась на две статьи, а в 2009 министерство статистики решило, что достаточно одной статьи "забой любого скота", но обязательно детализированной по фазам луны.

И вот как бы вы такое решали?

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

PS: Здесь немного объяснено, что имеется в виду под "грехом собственного языка".

[identity profile] kosiakk.livejournal.com 2009-11-18 04:33 pm (UTC)(link)
metaclass, а про metaprogramming не помнишь =)

я бы сделал DSL для удобного написания правил, а потом бы по этим правилам генерил бы, например, SQL-скрипты.

DSL очень удобно делать в Jetbrains MPS, т.к. там шикарнейший редактор и правильная структура.

А за полсотни строк кода можно получить автокомплит нужной части структуры БД (даже с подсказкой-описанием), вытаскивая её по jdbc. Ну или просо руками захардкодить, если она часто не меняется.

А на выходе из правил получать что угодно. Хоть java-код, хоть sql, хоть низкоуровневый DSL для Drools, хоть код для кастомной системы отчётов и уже его выполнять.

[identity profile] metaclass.livejournal.com 2009-11-18 05:03 pm (UTC)(link)
У меня была идея генерить SQL (или там заполнение таблиц правил) из правил на другом языке, но как известно, собственные языки изобретать запрещено, т.е. вернее не запрещено, но это считается грехом, особо присущим русским программистам, которые не могут самореализоваться, не сделав хотя бы парочку собственных языков :))

[identity profile] kosiakk.livejournal.com 2009-11-18 05:36 pm (UTC)(link)
кто запретил?
собственно, вся идеология DSL как раз вокруг этого.

Другой вопрос, что кто-то _уже_ изобрёл хороший язык именно для такой задачи. В таком случае - да, его нужно использовать а не выдумывать свой.

Запрещают изобретать "велосипеды", а не языки.
Это ж не sql и не язык общего назначения будет. DSL изобретать не то что можно, а скорее _приходится_, т.к. без этого вообще никак.

Как правило это т.н. embedded-DSL, которые шифруются под библиотеку, написаны на самом языке и даже самим автором не признаются как языки =) это dsl по факту.

[identity profile] metaclass.livejournal.com 2009-11-18 05:39 pm (UTC)(link)
90% "готовых" языков и библиотек это такой ад, что лучше сразу писать что-нибудь свое, даже в лоб, на обычном языке - будет проще, чем встраивать какой-нибудь BPEL и воевать с ним.