Pull to refresh
18
Алексей Воропай@OleksiiVoropai

BackEnd разработчик

11
Subscribers
Send message
И да. Если ваша деклартивная версия 3000 тких записей будет грузить секунду, а моя императивная полсекунды, то на прод пойдет моя. Без разговоров. Это даже не обсуждается. А тем паче, если загрузка процессора по PEX у моей ниже будет.

Понимаете, мы решаем задачи бизнеса. А задача бизнеса — это не красивый код. А эффективная работа. На красоту кода им плевать.

Тут я с вами не соглашусь. Скорость разработки и легкость поддержки тоже важна для бизнеса. Часто бывает, что выгоднее потратиться на вычислительные ресурсы, чем увеличивать штат разработчиков.
Спасибо за комментарии! Эта дискуссия была для меня полезной.
В одной из моих задач (как раз сейчас в работе) требуется парсинг XML весьма сложной структуры (вложенные друг в друга массивы, русские тэги, куча необязательных элементов...)

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


Вот это будет отличным примером!
Предположим, что у нас есть документ со списком товаров, которые описываются набором атрибутов. Один из атрибутов — это информация о наличии товара у поставщиков, представляющая собой массив. Элементом массива будет объект, включающий айди поставщика, количество товара и цену. А в некоторых случаях вместо количества — список доступных размеров одежды или обуви, внутри которого уже количество товара:
<products>
<product id="...">
  <name>...</name>
  <description>...</description>
  <providers>
    <provider id="...">
      <price>
        <value>...</value>
        <currency>...</currency>
      </price>
      <amount>...</amount>
    </provider>
    <provider id="...">
      <price>...</price>
      <sizes>
        <size>
          <value>...</value>
          <amount>...</amount>
        </size>
      </sizes>
    </provider>
....

Предположим, что необходимо извлечь данные о количестве товара у поставщиков, сравнить их с данными в БД и синхронизировать изменения.

Для начала опишем структуру документа в вие набора понятий. Предположим, что данные из файла представлены понятием xml_products:

concept newProductProviders (id=p.id, providers=p.providers) from xml_products p;

concept newProductAmount
(productId=pv.id, providerId=pd.id, amount=pv.amount)
from newProductProviders pd, {p.providers} as pv
where defined(pv.amount);

concept newProductSizeAmount
(productId=pv.id, providerId=pd.id, size=s.value, amount=s.amount)
from newProductProviders pd, {p.providers} as pv, {pv.sizes} as s
where defined(pv.sizes);


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

concept existingProductSizeAmount
(id, productId, providerId, size, amount)
by DBTable(connProvider, "product_size_amount");


Теперь можно сравнить данные из документа и БД:

//соединяем оба множества с помощью left join
concept productComparison (new=n, old=o)
from newProductSizeAmount n, optional (existingProductSizeAmount e where e.productId=n.productId and e.providerId=n.providerId and e.size=n.size) o;

//объекты для вставки в БД
concept productSizeAmountToInsert is c.new
with lastUpdated=CUR_DATE()
from productComparison c where not defined(c.old);

//объекты для обновления в БД
concept productSizeAmountToUpdate is c.old
with lastUpdated=CUR_DATE(), size=c.new.size
from productComparison c where defined(c.old);

//объекты для удаления из БД
concept productSizeAmountToDelete is existingProductSizeAmount old
where old.lastUpdated<CUR_DATE();


Это была декларативная часть. А теперь императивная часть
//загрузить данные из XML файла
import xml_products from XML("products_amount.xml", "products");

//синхронизировать их с БД, например, с помощью того же понятия, которое загружало данные
//можно даже понятия передать в качестве аргументов, пусть они сами найдут нужные значения и/или сгененрируют SQL код на основе описаний понятий
existingProductSizeAmount.insert(productSizeAmountToInsert);
existingProductSizeAmount.update(productSizeAmountToUpdate);
existingProductSizeAmount.delete(productSizeAmountToDelete);


Таким должен быть код обработчика сообщения.
Я пока не готов подробно обсуждать эффективные алгоритмы всех этих преобразований. Я планирую позаимствовать их из таких фреймворков для in-memory data processing как Spark или BigQuery. Очевидно, что по эффективности они будут уступать SAX парсерам и ручной склейке данных. Но зато код гораздо короче, понятней и быстрее в разработке и поддержке.
Я тоже неоднократно сталкивался с подобными задачами, но если честно, решение их традиционным императивным способом всегда нагоняло на меня тоску.
В данном конкретном случае гибридный язык, над которым я работаю, будет скорей всего избыточным.
Но если бы приложение загружало бы одни сущности из базы данных, другие из XML документов, третьи из запроса к другому сервису в JSON формате, преобразовывало их в свой внутренний формат, затем фильтровало и склеивало вместе, то в этом случае мой подход помог бы описать всю эту бизнес логику более кратко и понятно.
Это куда проще, чем городить монструозный гибридный язык.

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

Я надеюсь, что он не будет монструозным. По крайней мере, цель как раз в том, чтобы упростить работу с бизнес-логикой. Чтобы ее можно было выразить более кратко и четко по сравнению с традиционным ООП подходом, в том числе облегчить ее модификацию.
Т.е. Вы хотите сказать, что сможете поднять такой язык, довести его до уровня стандартизации, поддерживать его?

Нет, самостоятельно я конечно сделать этого не смогу. Но могу поделиться своими идеями с IT сообществом.

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

Кроме того, сложные задачи часто не ограничиваются только бизнеслогикой, нужна еще обвязка

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

Ну и насчет популярности — можете назвать другие, кроме ILE от IBM, попытки реализации подобного подхода? Я вот не сталкивался с таким.

Я тоже не сталкивался. Я имел в виду, что ILE технология не является мейнстримом, пока что это скорее нишевое решение для специфических задач. Думаю, что это потому, что писать код одновременно на нескольких языках неудобно, а взаимодействие таких частей кода будет довольно ограниченным, например, только вызовами процедур. Гибридный подход позволяет соединить компоненты гораздо более тесно.
Да, согласен. Сейчас у меня есть реализация proof-of-concept версии вычислителя, которая умеет выполнять запросы к модели. А так же я сделал два модуля к ней. Первый умеет считывать содержимое CSV файлов и использовать его в качестве входных данных для модели. А второй умеет с помощью Selenium считывать содержимое Web-страницы включая фактические цвета, размеры и расположение элементов. И можно построить модель страницы на семантическом уровне так как ее воспринимает человек а не на основе DOM. Получился простейший прототип Robotic Process Automation приложения.

В планах собрать вариант вычислителя, который будет вместо выполнения запроса транслировать модель в код на SQL, Cypher или SPARQL. Также была идея реализовать фреймворк для in-memory вычислений взяв за основу Spark, но на основе объектной логики в дополнение к RDD джоинам и SQL. К сожалению, на все это катастрофически не хватает времени.

За комментарии и ссылки на статьи спасибо!
Отвечу сначала про «фичи». Они могут быть связаны как с новыми возможностями вычислительного ядра (например, автоматическая сборка мусора у JAVA по сравнению с С++) так и с синтаксисом языка (например, Scala и Kotlin имеют то же вычислительное ядро, что и JAVA, именно синтаксис помог завоевать им своих сторонников). Так что синтаксис тоже может быть «килер-фичей», если он делает программирование более простым, удобным или надежным.

Я описал особенности синтаксиса и способы моделирования данных. За этим синтаксисом спрятано вычислительное ядро, способное логически выводить сущности обектов из описания модели. В его основе лежит фреймовая (объектная) логика и SLD резолюция. Я планирую описать это ядро в будущих публикациях. Это ядро может быть реализовано разными способами:
— встроено в полном объеме в новый язык программирования;
— встроено с некоторыми ограничениями в один из существующих языков на основе JVM;
— можно попробовать создать на его основе фреймворк по типу GraphQL, что, правда, еще немного органичит его возможности;
— можно создать DSL на его основе и сделать его основой для приложения бизнес-аналитики, автоматизированного тестирования или RPA;
— с некоторыми ограничениями и модификациями его можно использовать в качестве движка запросов для мультимодельной СУБД или для какой-нибудь облачной платформы, интегрирующей данные из разных источников.
Это те варианты, которые я считаю возможными. Но я еще не выбрал, на каком из них стоит сконцентрироваться.
Сейчас я описываю не столько синтаксис, сколько общие идеи и механику языка. Но поскольку этих идей оказалось очень много и они получились очень масштабными, то реализовывать их можно в разном порядке и объеме. У меня еще нет окончательного видения, как будет этот язык реализован, возможны разные варианты.
«Киллер-фич» будет несколько.
Во-первых, с моей точки зрения, возможностей языка SQL в некторых случаях недостаточно. Например, в области бизнес аналитики запросы могут большой размер и сложную вложенную структуру. Я хочу заменить монолитный запрос набором маленьких, описывающих структуру понятий бизнес логики, которые можно компоновать и повторно использовать. Есть некоторые диалекты SQL, умеющие работать с JSON, но для этого его объектную структуру они преобразовуют в плоскую табличную форму. Я хочу объектную струкутуру сделать в модели основной. Язык SQL имеет ограниченные возможности для создания рекурсивных запросов. Я хочу отказаться от этого ограничения и разширить область применения языка моделирования и на графовые базы данных. Другими словами я хочу заменить язык запросов языком моделирования. Об этом я планирую написать в следующей статье.
В во-вторых, я хочу протащить свой язык моделирования на уровень приложения и сделать определения понятий элементом первого уровня гибридного языка. Чтобы с его помощью можно было описать модель предметной области и сделать ее «каркасом» или «скелетом» приложения. Я думаю, что объектная форма языка моделирования должна помочь в решении проблемы объектно-реляционного импеданса. Также он будет удобен при работе со сложными иерархическими стурктурами данных, XML, HTML документами и т.п.
Я считаю, что декларативный логический стиль программирования недооценен и мог бы быть полезен при разработке приложений, богатых бизнес-логикой и ориентированных на данные. На стороне БД такой стиль реализован в виде SQL. Элементы такого стиля начинают проникать и на уровень приложения, например в виде LINQ или GraphQL. Я хочу объединить возможности LINQ и GraphQL, построить объединенное решение на базе формальной логики, использовать его для описания структуры понятий бизнес-логики и сделать их элементами первого класса в гибридном языке.
Механическое объединение нескольких языков не позволит этого сделать. Оно усложнит код, его понимание, разработку, отладку. Оно может быть полезен в некоторых задачах, например, при поддержке legacy кода, но так и не смогло завоевать популярности.
Еще нужно учесть, что вся подготовка ничего не гарантирует. Интервью это лотерея с не такими уж большими шансами. Попалась знакомая задача — есть шанс показать хороший результат. Если попалась незнакомая, то 40 минут явно мало для того, чтобы изобрести решение, отладить его и обсудить оптимизации.
Ну почему же, я очень открыт к компромиссам и вижу несколько потенциальных вариантов реализации языка. Вариант с JVM очень интересен. О возможных вариантах применения языка на практике и его реализации я планирую написать отдельную статью.
А JS я выбрал только в качестве proof of concept, чтобы проверить свои идеи по интеграции логической и имеперативной компонент на практике. Просто потому, что это один из самых простых и быстрых вариантов в реализации.
Возможно такая ситуация и возникнет. Но на данном этапе мне сложно представить, какую форму она примет, и какие инструменты в язык стоило бы добавить, чтобы было удобно их выявлять.
В нашей дискуссии смешались два вопроса: выразительность логики в общем и конкретно мой язык. Если говорить о логике в целом, то выразительность безусловно важна. Но в каждой области ее применения будут свои компромисы между выразительностью, decidability и эффективностью алгоритмов вывода.
Конкретно мой язык направлен не на доказательство теорем или построение сложных логических теорий. Он преднаначен для интеграции разнородных данных, имеющих вложенную объектную структуру. Поэтому он должен быть удобен скорее для трансформации объектов, связанных логическими отношениями. А удобство доказательств от противного в нем не будет иметь большого значения.
Безусловно, четырехзначная логика будет более выразительной.
Но я специально хочу ее ограничить. На практике такие противоречивые наборы правил будут встречаться очень редко. И лучше заставить разработчиков избегать противоречий и преформулировать правила вручную, чем постоянно иметь дело с четырехзначной логикой. Это упростит рассуждения, разработку, отладку, обучение, реализацию языка.
Да, это было бы хорошо. Пока что я могу рассказать, какия я хотел бы видеть язык программирования. И где он мог бы быть полезен. А после этого можно будет попробовать организовать его реализацию. В одиночку от начала до конца сделать это нереально.
Про бесполых существ в этих формулах ничего не говорится. Если вообще нет фактов, о том, какого пола Х, то в Stable Model Semantic делается вывод, что возможны оба варианта, Х может быть как мужчиной, так и женщиной. Бесполых существ надо вводить в формулы отдельно:
male(X) ← person(X) AND NOT female(X) AND NOT neutral(X)
female(X) ← person(X) AND NOT male(X) AND NOT neutral(X)
neutral(X) ← person(X) AND NOT male(X) AND NOT female(X)
А что вы имеете в виду под платфомой для языка программирования? Реализацию? Компиляторы, отладчики, IDE и прочую инфраструктуру?
Да, согласен. Особенно для одно и двумерных отношений. Но для большего количества аргументов надо что-то придумывать: R(X, Y, Z) =>?

Information

Rating
Does not participate
Registered
Activity