LINUX.ORG.RU

lsFusion 4

 


0

2

Вышел новый релиз одной из очень немногих бесплатных открытых высокоуровневых (уровня ERP) платформ разработки информационных систем lsFusion. Основной акцент в новой четвертой версии был сделан на логику представлений — пользовательский интерфейс и все что с ним связано.

Так, в четвертой версии появились:

  • Новые представления списков объектов:
    • Группировочные (аналитические) представления, в которых пользователь сам может группировать данные и вычислять различные агрегирующие функции для этих групп. Для представления результата в свою очередь поддерживаются:
      • Сводные таблицы, с возможностью упорядочивания, клиентской фильтрации, выгрузки в Excel.
      • Графики и диаграммы (столбчатые, круговые, точечные, плоскостные и т.д.)
    • Карта и календарь.
    • Кастомизируемые представления, при помощи которых разработчик может подключать любые javascript библиотеки для отображения данных.
  • Темная тема и вообще практически полностью новый дизайн
  • OAuth-аутентификация и саморегистрация
  • Обратная интернационализация
  • Переходы по ссылке
  • Групповые изменения данных «одним запросом»
  • Вычисляемые заголовки контейнеров и форм
  • Полноэкранный режим в веб
  • Ручное обновление представлений списков объектов
  • Выполнение HTTP-запросов на клиенте
  • Расширение форм в контексте вызова
  • Существенная оптимизация работы с DOM

>>> Подробности



Проверено: Shaman007 ()
Последнее исправление: atsym (всего исправлений: 2)

Ответ на: комментарий от amm

Потому что люди любят buzzwords. Всегда можно сказать, что у нас везде ООП, и продолжать писать программы на if’ах. :)

Тем не менее в огромном количестве продуктов (например IDEA) все на ООП (причем иногда больше чем надо).

Видимо, вы работаете с какими-то другими бизнес-приложениями и бизнес-программистами.

Ну мы например лидер на рынке комплексной автоматизации розничных сетей в Беларуси, больше половины из них сидят на lsFusion (хотя в других областях у нас тоже много проектов). И каждая более менее крупная сеть генерирует по 4-5 задач (и весьма сложных, а не добавьте мне поле на форму) В ДЕНЬ (фантазия у них огого). Так что это вы видимо, работаете с какими-то другими бизнес-приложениями (без обид если что).

Они все играют совершенно в разных нишах.

Они изначально играли в одних нишах, пока не приходила технология лучше подходящая под данную задачу и забирала часть своей ниши (за счет лучшей декларативности и выразительности, а значит скорости и простоты разработки)

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

Так а что вам не понятно. Это ОБЫЧНЫЕ МАТЕМАТИЧЕСКИЕ функции.

f(x,y) = g(h(x), y) + x;

То что учат в 9 классе (даже нотация та же 1 в 1). Аналогия абсолютно прямая.

Группировка обычный map / reduce (ну или SELECT … GROUP BY, или интеграл по y)

f(x) = GROUP SUM g(y) IF h(z(y)) = x; // для всех y, у которых h(z(y)) = x, считаем сумму по g.

В чем собственно вопрос? Может вы просто не хотите понять? :) в SQL с JOIN’ами, которые здесь получатся (чтобы считать h) это было бы куда более мозговыносяще.

Странно, вся индустрия сидит на РСУБД, а в университетах базовые понятия не учат.

В университете физкультуры? Или экономики? А функции в 9 классе общеобразовательной (!) школы учат.

NitroJunkie
() автор топика
Последнее исправление: NitroJunkie (всего исправлений: 2)
Ответ на: комментарий от NitroJunkie

Это считай ничего нет.

Ну, нет так нет. :)

Там TO по умолчанию кладет в предопределенное свойство (переменную) exportFile. Но это мы уже немного в дебри залезли.

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

Вызов exportFile() что делает? Как данные из первого запроса попадают во внешний?

Для dapper пример с промежуточными данными в программе будет выглядеть так:

public class Program
{	
	public static void Main()
	{
		using var conn = new SqlConnection(FiddleHelper.GetConnectionStringSqlServerNorthwind());
		
		var customers = conn.Query<Customer>(
			"select CustomerID, CompanyName from Customers where CustomerID like @CustomerID",
			param: new { CustomerID = "M%" }
		).AsList();
		
		var orders = conn.Query<Order>(
			"select * from Orders where CustomerID in @CustomerID",
			param: new { CustomerID = customers.Select(x => x.CustomerID) }
		);
		
		FiddleHelper.WriteTable(orders);
	}

	public class Customer
	{
		public string CustomerID { get; set; }
		public string CompanyName { get; set; }
	}
	
	public class Order
	{
		public int OrderID { get; set; }
		public string CustomerID { get; set; }
		public string ShipName { get; set; }
		public string ShipAddress { get; set; }
	}
}

Здесь база одна, но запросы могут быть и к разным базам. При желании можно записать в одну строку. :)

Полностью согласен. Причем застрявший именно потому как парадигма так и осталась на уровне непонятной реляционной алгебры, а не доросла до функциональной как в lsFusion (заодно добавив логику представлений)

Какое отношение PL/SQL имеет к реляционной алгебре? Это просто процедурное расширение Oracle RDBMS.

Можно, тем не менее они его прямо в язык добавили. Зачем по вашему, если можно было библиотекой обойтись?

Это был как раз тот случай, когда было не обойтись. Для C#, как языка, появление linq стало большим шагом вперед. Вы же говорили о включении в язык поддержки TCP, что для меня выглядит как минимум странно.

amm
()
Ответ на: комментарий от NitroJunkie

Тем не менее в огромном количестве продуктов (например IDEA) все на ООП (причем иногда больше чем надо).

Какое отношение IDEA имеет к бизнес-коду? Только то, что в ней его можно писать. :)

f(x) = GROUP SUM g(y) IF h(z(y)) = x; // для всех y, у которых h(z(y)) = x, считаем сумму по g.

В чем собственно вопрос? Может вы просто не хотите понять? :) в SQL с JOIN’ами, которые здесь получатся (чтобы считать h) это было бы куда более мозговыносяще.

Так любой ORM умеет. Вопрос к вашим претензиям на простоту и уникальность решений.

В университете физкультуры? Или экономики? А функции в 9 классе общеобразовательной (!) школы учат.

Не, как раз вы же позиционируете свое решение на физкультурников. :) А я не вижу в вашем примере мат. функций, но это, видимо, все-таки мои проблемы. :)

amm
()
Ответ на: комментарий от amm

Здесь база одна, но запросы могут быть и к разным базам. При желании можно записать в одну строку. :)

Хм… Но она же так через сервер приложений все прогонит и всю таблицу в IN запихнет. Но в любом случае, это чисто .Net’кий специфичный синтаксис, я его также не понимаю, как и вы lsFusion’кий (хотя решать такие задачи расширяя язык полностью поддерживаю). Но в любом случае это если вы помните был мой ответ на сложность интеграций в высокоуровневых языках :) Мне гораздо интереснее, как assert sumX() > 5; будет в том же .Net будет смотреться.

Какое отношение PL/SQL имеет к реляционной алгебре? Это просто процедурное расширение Oracle RDBMS.

То что он (как комплекс PL + SQL) оперирует таблицами, JOIN’ами и UNION’ами , а не функциями, композициями и OR’ами как lsFusion.

Для C#, как языка, появление linq стало большим шагом вперед

Ура. Хоть в чем то мы сошлись, а именно что добавление нового синтаксиса это большой шаг вперед. И интеграцию с TCP даже я не предлагал добавлять в язык. А вот всякие IN @CustomerID (я так понимаю это .Net фишка) очень даже. Кстати а без строк можно ваш пример переписать? Чтобы подсветка ошибок, completion и т.п. работали.

NitroJunkie
() автор топика
Ответ на: комментарий от amm

Какое отношение IDEA имеет к бизнес-коду? Только то, что в ней его можно писать. :)

В том контексте на который я отвечал речь шла об ООП вообще, а не в контексте бизнес-кода.

Так любой ORM умеет. Вопрос к вашим претензиям на простоту и уникальность решений.

Не умеет. Нельзя сделать метод sumXForAllZ:

class X {

 List<Y> ys;

 int sumX(int z) {

   int sx=0;
   for(Y y : ys)
     sx += y.h(z);
   return sx;
 }

 int sumXForAllZ() {
    int xg=0;
    for(int s=sumX(int z)) // посчитать общую сумму для всех z 
          xg += s;
 }
}

А в lsFusion можно. Как? Магия, но вас как разработчика это не должно волновать (хотя там не сложнее SQL алгоритмов, хоть и не сильно проще)

В любом случае, я запутался вы говорите, что понять lsFusion не можете. А потом у вас претензии к уникальности :)

Не, как раз вы же позиционируете свое решение на физкультурников. :) А я не вижу в вашем примере мат. функций, но это, видимо, все-таки мои проблемы. :)

Ну я же вам специально пример привел (повторю еще раз):

f(x,y) = g(h(x), y) + x;

Это обычная математическая функция в нотации 9 класса. А в SQL это бы JOIN’ом выглядело (чтобы считать значение g).

SELECT h.param1, g.param2, g.value + h.param1 AS value FROM h JOIN g WHERE h.value = g.param1

Что по вашему легче понять начинающему разработчику?

NitroJunkie
() автор топика
Ответ на: комментарий от NitroJunkie

Хм… Но она же так через сервер приложений все прогонит и всю таблицу в IN запихнет.

А как по-другому, если сервера БД будут разные? Можно, конечно, временную таблицу заполнить, потом с ней работать, но данные все-равно через приложение пойдут.

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

А что здесь в синтаксисе не понятно? C# это же как Java, только лучше. :)

Dapper – это расширение для ADO.NET (аналог JDBC), предоставляет несколько методов для удобной работы с базой. Так метод Query принимает строку запроса и объект с параметрами, результат вопроса возвращает в виде IEnumerable<T>, где T может быть как конкретным типом, так и динамческим объектом. Весь цикл prepare-bind-execute-fetch происходит внутри метода.

Единственная магическая вещь в примере это IN @CustomerID. Здесь Dapper позволяет привязать коллекцию к @CustomerID, в результате получится IN (coll0, coll1, coll2, ...).

Но в любом случае это если вы помните был мой ответ на сложность интеграций в высокоуровневых языках :) Мне гораздо интереснее, как assert sumX() > 5; будет в том же .Net будет смотреться.

Подписываемся на события об изменении коллекции и поля, вычисляем значение, проверяем, если не удовлетворяет условию, кидаем исключение.

То что он (как комплекс PL + SQL) оперирует таблицами, JOIN’ами и UNION’ами , а не функциями, композициями и OR’ами как lsFusion.

Он этим оперирует только на уровне встроенного SQL, сам язык, как язык обработки данных, очень слабый, точнее вообще никакой.

Ура. Хоть в чем то мы сошлись, а именно что добавление нового синтаксиса это большой шаг вперед. И интеграцию с TCP даже я не предлагал добавлять в язык.

Вы сказали «если бы была нужна поддержка TCP, ее бы добавили в язык». Меня это и удивило. В языке должны быть более фундаментальные вещи, но никак не поддержка TCP.

А вот всякие IN @CustomerID (я так понимаю это .Net фишка) очень даже.

Нет, конкретно @CustomerID это фишка провайдера СУБД, IN @CustomerID фишка Dapper.

Кстати а без строк можно ваш пример переписать? Чтобы подсветка ошибок, completion и т.п. работали.

Есть расширения к Dapper, которые позволяют не писать строки insert, update, простых select (с выборкой по ключу). Но сложные запросы все-равно придется писать строкой, в этом и основная задача Dapper – удобная работа с raw sql. Да, подсветки и дополнений кода не будет, но опять таки это не задача языка, это должна делать IDE, но почему-то никто такого расширения еще не написал. :)

Если хотите писать запросы прямо на C#, то для этого есть linq2db. Вот примеры использования от автора библиотеки https://www.youtube.com/watch?v=m--oX73EGeQ.

amm
()
Ответ на: комментарий от NitroJunkie

В любом случае, я запутался вы говорите, что понять lsFusion не можете. А потом у вас претензии к уникальности :)

Судя по комментам на хабре, я не первый кто вам эту претензию высказывает. :)

f(x,y) = g(h(x), y) + x;

SELECT h.param1, g.param2, g.value + h.param1 AS value FROM h JOIN g WHERE h.value = g.param1

Эти выражения точно описывают одно и тоже? Где например в функции условие WHERE h.value = g.param1, где поля param1, param2, value? У меня не получается отобразить одно на другое.

amm
()
Ответ на: комментарий от amm

А как по-другому, если сервера БД будут разные? Можно, конечно, временную таблицу заполнить, потом с ней работать, но данные все-равно через приложение пойдут.

Ну я к тому что так только IN можно сделать, а скажем ок я выгружаю таблицу с двумя полями скажем кроме ID еще и Limit, и хочу сделать выборку из orders, где сумма заказа больше лимита для заказчика которому заказ отгружается. Как тогда будет выглядеть ваш пример?

А что здесь в синтаксисе не понятно? C# это же как Java, только лучше. :)

Ну ок, тогда lsFusion это как SQL только лучше :) Что в синтаксисе не понятно?

Подписываемся на события об изменении коллекции и поля, вычисляем значение, проверяем, если не удовлетворяет условию, кидаем исключение.

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

Вы сказали «если бы была нужна поддержка TCP, ее бы добавили в язык». Меня это и удивило. В языке должны быть более фундаментальные вещи, но никак не поддержка TCP.

Абсолютно согласен. Но фундаментальность понятие относительное. Вот Java считает что весь этот linq это не фундаментально. А вы что фундаментально. И опять таки фундаментальность определяется задачей. В бизнес-приложениях одни вещи фундаментальны, в играх 0 другие и т.п.

Нет, конкретно @CustomerID это фишка провайдера СУБД, IN @CustomerID фишка Dapper.

Ну и? Видите добавили в язык @. Но я же не кричу, уберите, я не знаю что такое эта собака, почему это параметром или существующими средствами языка не сделали.

таки это не задача языка, это должна делать IDE

По такой логике компилятор тоже не нужен, раз все IDE может делать. А что тогда насчет автотестов скажем?

linq2db

Я знаю что такое linq2db и всячески поддерживаю идею, то что все базовые вещи лучше делать в языке, а не библиотечными функциями с параметрами.

NitroJunkie
() автор топика
Ответ на: комментарий от amm

Судя по комментам на хабре, я не первый кто вам эту претензию высказывает. :)

У комментариев где угодно есть «ошибка выжившего». Никто не будет писать коммент «да все понятно», будут писать в основном те кому что-то непонятно, или с чем-то не согласен. То есть это не показатель ничего.

Но вы так и не ответили на вопрос. Вам не понятно или вы не согласны с уникальностью? Так как это в общем то противоречивые вещи.

Эти выражения точно описывают одно и тоже? Где например в функции условие WHERE h.value = g.param1, где поля param1, param2, value? У меня не получается отобразить одно на другое.

Все просто. Любую функцию можно рассматривать как таблицу, у которой ключи - параметры функции (допустим param1, param2, …), а не ключ - значение функции (допустим value). Хотя точнее любую таблицу в 3 НФ можно рассматривать как множество функций. Соответственно WHERE h.value = g.param1, это «g(h(x)». Но вот видите, даже вы этого не понимаете, а говорите, что SQL понятный язык. Появись он сейчас, люди бы просто в шоке были.

NitroJunkie
() автор топика
Ответ на: комментарий от NitroJunkie

Все просто. Любую функцию можно рассматривать как таблицу, у которой ключи - параметры функции (допустим param1, param2, …), а не ключ - значение функции (допустим value).

Firebird имеется https://firebirdsql.org/refdocs/langrefupd25-psql.html
Так вот частенько результат вызова функции является набором каких-либо значений и в какой-то мере это ТЗ.

Вы уж извините, что скажу то, что вам не понравится.

Уже лет пятьдесят индустрия разработки программ топчется на месте.
Создание компиляторов, SQL, …
Как будто нет иных путей решения этих вопросов.

Назначение SQL понятно, но запросы решают лишь задачу выбора данных и ИМХО очень слабенько.

Поэтому и создают велосипеды типа PSQL в Firebird, но они обычно «хиленький прехиленький» и в целом больше похожи на студенческую лабу.

Гм., в какой-то мере вас похвалил однако и не считаю это зазорным.

Владимир

anonymous
()
Ответ на: комментарий от anonymous

Гм., в какой-то мере вас похвалил однако и не считаю это зазорным.

Вы действительно увидели некоторые из слабостей при работе с SQL и пытаетесь их решить.
Это конечно похвально.

Владимир

anonymous
()
Ответ на: комментарий от NitroJunkie

И все из них lsFusion решает. Как впрочем и все из «Почему не 1С».

Какие планы в разработке?

Владимир

anonymous
()
Ответ на: комментарий от anonymous

Во вторник на хабре статья выйдет. Собственно она уже готова, просто на выходных публиковать не хотели.

NitroJunkie
() автор топика
Ответ на: комментарий от NitroJunkie

Ну я к тому что так только IN можно сделать, а скажем ок я выгружаю таблицу с двумя полями скажем кроме ID еще и Limit, и хочу сделать выборку из orders, где сумма заказа больше лимита для заказчика которому заказ отгружается. Как тогда будет выглядеть ваш пример?

class OrderLimit
{
    public int OrderId { get; set; }
    public int Limit { get; set; }
}

List<OrderLimit> limits = externalService.GetOrderLimits();

conn.Execute("CREATE TABLE #temp ([OrderId] int, [Limit] int)");
conn.Execute("INSERT INTO #temp ([OrderId], [Limit]) VALUES (@OrderId, @Limit)", limits);

И работаем с таблицей #temp.

…Боюсь вы его даже написать не сможете.

А вы не бойтесь. :)

Абсолютно согласен. Но фундаментальность понятие относительное. Вот Java считает что весь этот linq это не фундаментально. А вы что фундаментально. И опять таки фундаментальность определяется задачей. В бизнес-приложениях одни вещи фундаментальны, в играх 0 другие и т.п.

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

Ну и? Видите добавили в язык @. Но я же не кричу, уберите, я не знаю что такое эта собака, почему это параметром или существующими средствами языка не сделали.

В какой язык добавили @? Вы знаете, что такое placeholders или bind-переменные в базах данных? Так вот, это они есть.

По такой логике компилятор тоже не нужен, раз все IDE может делать. А что тогда насчет автотестов скажем?

Ээээ, подсветка и дополнение кода это задача языка? Компилятор может предоставлять такие сервисы, но компилятор C# предоставляет их только для C#, потому как ничего не знает про SQL. Для него это просто строка.

Вот, например, расширение для проверки синтаксиса SQL в строках https://marketplace.visualstudio.com/items?itemName=PKochubey.VerifyRawSQL. Но оно к языку никакого отношения не имеет.

Я знаю что такое linq2db и всячески поддерживаю идею, то что все базовые вещи лучше делать в языке, а не библиотечными функциями с параметрами.

Так что для вас такое базовые вещи в языке?

amm
()
Ответ на: комментарий от NitroJunkie

У комментариев где угодно есть «ошибка выжившего». Никто не будет писать коммент «да все понятно», будут писать в основном те кому что-то непонятно, или с чем-то не согласен. То есть это не показатель ничего.

Тогда это «ошибка неосилевшего». Получается, ваши «выжившие» на форумах не сидят, а лабают бизнес-код в своих песочницах. :)

Все просто. Любую функцию можно рассматривать как таблицу, у которой ключи - параметры функции (допустим param1, param2, …), а не ключ - значение функции (допустим value). Хотя точнее любую таблицу в 3 НФ можно рассматривать как множество функций. Соответственно WHERE h.value = g.param1, это «g(h(x)». Но вот видите, даже вы этого не понимаете, а говорите, что SQL понятный язык. Появись он сейчас, люди бы просто в шоке были.

То есть вы рассматриваете таблицы как отображение ключевых полей на остальные поля?

WHERE h.value = g.param1, это «g(h(x)»

Откуда x появился?

amm
()
Ответ на: комментарий от amm

И работаем с таблицей #temp.

А где удаление таблицы? Ну и кода тогда значительно больше будет, не в пользу .Net. Впрочем это не лучший пример.

А вы не бойтесь. :)

Ну давайте. В lsFusion можно просто пометить sumX lazy и сделать assert sumX() < 5; Все. Покажите теперь код на .Net, который сделает тоже самое с инкрементальным обновлением sumX (то есть скажем при изменении h на 5, к результирующему значению добавлялось 5, или при добавлении y в коллекцию ys к результату добавлялся y.h() ну и так далее).

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

streams это как раз подход библиотеки (против языка). А linq это подход языка (против библиотеки).

Так вот, это они есть.

И это и есть изменение языка. Очень маленькое, но изменение. Без обертки из dapper у вас будет синтаксическая ошибка.

Для него это просто строка.

Так в этом и проблема, что вы ошибку можете чисто в продакшне получить, а не на стадии компиляции.

Так что для вас такое базовые вещи в языке?

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

NitroJunkie
() автор топика
Ответ на: комментарий от amm

Тогда это «ошибка неосилевшего». Получается, ваши «выжившие» на форумах не сидят, а лабают бизнес-код в своих песочницах. :)

Они сидят, но ничего не пишут . Я например использую много технологий, но не пишу ни на каких форумах, если мне в них все понятно и нет никаких вопросов.

То есть вы рассматриваете таблицы как отображение ключевых полей на остальные поля?

Да (а собственно отображение AxB на C и есть определение матфункции смотри программу 9-го класса). Понятно что это применимо, только к 3НФ, но именно она используется в 99 процентах современных бд).

Откуда x появился?

x это первый параметр f, соответственно равен h.param1. Еще раз с комментариями:

SELECT h.param1 AS param1, // x
       g.param2 AS param2, // y
       g.value + h.param1 AS value 
       FROM h JOIN g WHERE h.value = g.param1

Если вы функциональную логику f(x,y) = g(h(x), y) + x отобразите на sql (предположив что h, g и f - таблицы / подзапросы), вы именно такой запрос и получите. Ну и что по вашему легче понять начинающему разработчику?

NitroJunkie
() автор топика

Правильно делаете, что перестали на https://forum.mista.ru/ «воевать».

На ней в основном одни прикладники и понять суть вашего проекта они просто не могут, потому как у них нет опыта в использовании Java, .Net, C/C++ …
Результат любого треда в котором говорится не о 1С предсказуем и всегда один …

Владимир

anonymous
()
Ответ на: комментарий от NitroJunkie

Ну давайте. В lsFusion можно просто пометить sumX lazy и сделать assert sumX() < 5; Все. Покажите теперь код на .Net, который сделает тоже самое с инкрементальным обновлением sumX (то есть скажем при изменении h на 5, к результирующему значению добавлялось 5, или при добавлении y в коллекцию ys к результату добавлялся y.h() ну и так далее).

А если надо вычислить не сумму, а например записать все изменения коллекции в журнал? Тоже все автоматом отработает?

Если делать «руками» через события, то клиентский код для суммы будет выглядеть примерно так (полный код здесь):

var coll = new ObservableCollection<Item>();

var sumAggr = EventAggregator.Create(
    coll,
    seed: 0,
    execute: (int accum, Item item) => accum + item.H,
    undo: (int accum, Item item) => accum - item.H,
    validate: accum => accum < 5,
    propertySet: new HashSet<string>() { nameof(Item.H) }
);

var item0 = new Item() { H = 2 };
coll.Add(item0); // sumAggr.Value: 2
item0.H = -1; // sumAggr.Value: -1
coll.Remove(item0); // sumAggr.Value: 0
coll.Add(new Item() { H = 10 }); // Exception: AddItems validation error

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

Да, приходится указывать список полей, по которым будут учитываться изменения, но можно разобрать execute и undo и заполнить этот список автоматически, вся инфраструктура для этого есть.

streams это как раз подход библиотеки (против языка). А linq это подход языка (против библиотеки).

Streams – библиотека? При их релизации язык тоже неплохо подтянули. Как минимум лямбды добавили.

И это и есть изменение языка. Очень маленькое, но изменение. Без обертки из dapper у вас будет синтаксическая ошибка.

Изменение в каком языке? Шарп для данной функциональности не меняли.

Так в этом и проблема, что вы ошибку можете чисто в продакшне получить, а не на стадии компиляции.

Далеко не все проверяется на стадии компиляции. Работа с внешними ресурсами тем более.

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

Ну так какие базовые вещи в бизнес языках? И почему им место в языке, а не в библиотеке?

amm
()
Ответ на: комментарий от NitroJunkie

Да (а собственно отображение AxB на C и есть определение матфункции смотри программу 9-го класса). Понятно что это применимо, только к 3НФ, но именно она используется в 99 процентах современных бд).

Так зачем так заумно? Сказали бы, что представляете таблицы как словарики, и люди бы к вам потянулись. :)

amm
()
Ответ на: комментарий от amm

Если делать «руками» через события, то клиентский код для суммы будет выглядеть примерно так (полный код здесь):

Ну круто всего 256 строк кода. Вместо:

sumX(X x) = GROUP SUM h(y) IF ys(y) = x MATERIALIZED;

А если чуть усложнить задачу и суммировать l(h(y)), а не h(y). Или еще разрез добавить:

sumX(X x, Z z) = GROUP SUM l(h(y)) IF ys(y) = x AND zs(y) = z MATERIALIZED;

В lsFusion это три секунды. А вы будете полчаса минимум исправлять / отлаживать ваш код (и там будет куда больше 256 строк). Без гарантии, что он будет правильно работать.

Но это все ладно. Главное, если мы хотим это все persistent сделать? Как сделать, чтобы это все на SQL выполнялось? Чтобы N+1 проблемы не было. Это собственно главный кейс в бизнес приложениях.

Streams – библиотека? При их релизации язык тоже неплохо подтянули. Как минимум лямбды добавили

Да, streams - библиотека. И лямбды к ним прямого отношения не имеют. Кстати как ваше отношение к лямбдам, до 8 джава они отлично заменялись анонимными классами. Тоже зачем усложняли, а не воспользовались возможностями языка, что гораздо проще и выразительнее?

Изменение в каком языке? Шарп для данной функциональности не меняли.

В мини-языке используемом в Dapper.

Далеко не все проверяется на стадии компиляции

Ну так это и плохо. Чем больше проверяется на стадии компиляции тем лучше.

И почему им место в языке, а не в библиотеке?

А почему лямбдам место в языке, а не в библиотеке (анонимных классах). Или linq?

Про базовые вещи я писал - события предметной области, ограничения, классы, агрегации, регистры, формы.

NitroJunkie
() автор топика
Последнее исправление: NitroJunkie (всего исправлений: 2)
Ответ на: комментарий от amm

Так зачем так заумно? Сказали бы, что представляете таблицы как словарики, и люди бы к вам потянулись. :)

Потому что словарики это .Net терминология. В Java они называются Map (отображения), именно этот термин используется в математике и более корректен на мой взгляд.

Ну и это не мы представляем таблицы как отображения, а 3 нормальная форма их так представляет, как и 99% процентов разработчиков.

И отображения = функции как бы по определению. И мне во всяком случае это казалось очевидно. Но похоже я все же немного переоценил людей :)

NitroJunkie
() автор топика
Последнее исправление: NitroJunkie (всего исправлений: 1)

В 1C 8.3 потенциал большой.
Беда в том, что версий ее много и не все они стабильны.
Вот простой вопрос.
Открыл конфигурацию и скажем отвлекся на другие вопросы.
Казалось бы все должно быть ok!
Дудки!
1C бац и «радует» 1С Предприятие должно быть перезапущено …
С какой кстати если ни чего не делал?

PS: На форумах многие плачутся на «ломки», «поломки», … - нестабильность.
Стабильность то можно достигнуть, но при этом нужно разобраться, что же там в 1С «не так».

Тяжелая эта работа, из болота тащить бегемота.

Некоторые из-за этого и по сей день 8.2 используют, так как она стабильна.

Владимир

anonymous
()
Ответ на: комментарий от NitroJunkie

Ну круто всего 256 строк кода.

Большая часть кода уйдет в библиотеку. Клентский код это:

var sumAggr = EventAggregator.Create(
	coll,
	seed: 0,
	execute: (int accum, Item item) => accum + item.H,
	undo: (int accum, Item item) => accum - item.H,
	validate: accum => accum < 5,
	propertySet: new HashSet<string>() { nameof(Item.H) }
);

Но это все ладно. Главное, если мы хотим это все persistent сделать? Как сделать, чтобы это все на SQL выполнялось?

В начальной задаче ничего про persistent ничего сказано не было. :) Но решается также, как и без событий: с помощью ado.net, dapper, linq2db, entity framework.

А что у вас с инкрементальностью, если функция будет не SUM, а например среднее или дисперсия? Тоже все будет автоматически работать?

Можно реализовать журнал изменения коллекции?

var logAggr = EventAggregator.Create(
	coll,
	seed: new List<string>(),
	execute: (List<string> accum, Item item) => { accum.Add($"Added item: {item}"); return accum; },
	undo: (List<string> accum, Item item) => { accum.Add($"Removed item: {item}"); return accum; }
);

Да, streams - библиотека. И лямбды к ним прямого отношения не имеют. Кстати как ваше отношение к лямбдам, до 8 джава они отлично заменялись анонимными классами. Тоже зачем усложняли, а не воспользовались возможностями языка, что гораздо проще и выразительнее?

Так и linq библиотека в виде набора extension methods.

Вас не удивляет, что лямбды и streams появились в одном релизе? Отношение к ламбдам в java сугубо положительное, так как они упрощают написание кода и без них в было бы совсем грустно. Кстати, в lsFusion лямбды есть? :)

В мини-языке используемом в Dapper.

Тогда уж микро-языке: dapper добавляет к стандартному sql только поддержку списков и возможность безопасно вставить в запрос литералы.

А почему лямбдам место в языке, а не в библиотеке (анонимных классах). Или linq?

И как это можно сделать в виде библиотеки? :)

Про базовые вещи я писал - события предметной области, ограничения, классы, агрегации, регистры, формы.

Вот это всё как раз можно реализовать на лямбдах и linq в библиотечном коде без изменения языка.

amm
()
Ответ на: комментарий от NitroJunkie

Ну и это не мы представляем таблицы как отображения, а 3 нормальная форма их так представляет, как и 99% процентов разработчиков.

Кто-то еще проектирует приложения в терминах нормальных форм? По мне так это все не более чем гимнастика для ума.

И отображения = функции как бы по определению. И мне во всяком случае это казалось очевидно. Но похоже я все же немного переоценил людей :)

Ну да, отбражение – функция. Но зачем возводить это в абсолют и выдавать за преимущество перед другими языками?

amm
()
Ответ на: комментарий от amm

Большая часть кода уйдет в библиотеку.

Не, в библиотеке у вас один частный случай, примитивное суммирование (даже по сути без замыканий). А если задача чуть чуть изменяется (добавляются условия / разрезы) нужна новая библиотека?

В начальной задаче ничего про persistent ничего сказано не было. :) Но решается также, как и без событий: с помощью ado.net, dapper, linq2db, entity framework.

Ну это из разряда, что космолет строится с помощью пилы, молотка и такой то матери. Очень интересно посмотреть как именно это решается. И опять таки чуть усложняем задачу добавляем условия, ещё какие нибудь умножения, сравнения, композиции и т.п. Собственно в конечном итоге через 16к комитов у вас lsFusion и получится. :)

Отношение к ламбдам в java сугубо положительное, так как они упрощают написание кода и без них в было бы совсем грустно.

Что значит было бы совсем грустно. В 7 все тоже самое делалось анонимными классами. Собственно лямбды это синтаксический сахар для них.

Кстати, в lsFusion лямбды есть? :)

Скажем так замыкания (возможность использования внешнего контекста во всех выражениях / действиях в том числе анонимных) есть практически везде. Но передачи функций / действий в качестве параметров пока нет.

И как это можно сделать в виде библиотеки? :)

Анонимными классами с замыканиями, что до 8й java и делали. Хотя вредная IDEA визуально и сворачивала их в лямбды. Но назло языкофобам в восьмой джава лямбда добавили в язык.

Вот это всё как раз можно реализовать на лямбдах и linq в библиотечном коде без изменения языка.

Можно не значит что нужно. Собственно лямбды яркий тому пример.

NitroJunkie
() автор топика
Ответ на: комментарий от amm

Кто-то еще проектирует приложения в терминах нормальных форм? По мне так это все не более чем гимнастика для ума.

Что значит проектируют в терминах? Проектируют и проектируют, а дальше соответствует или нет. И да, сейчас считается моветоном когда у таблицы нет ключей.

Но зачем возводить это в абсолют и выдавать за преимущество перед другими языками?

Что значит возводить в абсолют? По факту сейчас все таблицы в 99 процентах БД это множества функций (именно математических или чистых). И lsFusion именно в этой парадигме функций и работает. А SQL и его обертки остались в парадигме таблиц до сих пор (честно говоря загадка почему). И повышение уровня парадигмы потенциально даёт огромное количество преимуществ которые и есть в lsFusion.

NitroJunkie
() автор топика
Ответ на: комментарий от anonymous

В 1C 8.3 потенциал большой.

Нет никакого потенциала у 8.3. Сейчас он превратился в недо.Net, при этом куда хуже спроектированный и с закрытой собственной экосистемой. За пределами совка без шансов (в борьбе с тем же .net). А тут живёт только из за большой клиентской и сложной бухгалтерии.

NitroJunkie
() автор топика
Ответ на: комментарий от NitroJunkie

Нет никакого потенциала у 8.3. Сейчас он превратился в недо.Net, при этом куда хуже спроектированный и с закрытой собственной экосистемой.

Скажу вам по секрету 1С 7.7 двадцати летней давности прекрасно дружит с последними версиями .Net, а уж 1С 8.3 тем более.

1С 8.3 это не недо .Net …
Кстати ваше суждение еще больше укрепляет меня в суждении, что 1С 8.3 знаете «не очень».
Сказал это не к тому, чтобы вас обидеть.
Почитайте про ВК и что они дают.
Мне приходилось разрабатывать ВК и ActiveX как на C++, так и .Net /и не мало/.
Сказал об этом, чтобы вы не подумали, что просто с вами спорю и не знаю сути вопроса. Еще раз

Возможности у 1С 8.3 и потенциал хороший

Но скажу вам по секрету многий из предоставляемого API ИМХО тянет на студенческую лабу, но много и профессионально разработанного.

PS: На всякий случай, на .Net приходилось вести разработку и не только ВК. Как ранее в постах говорил скажу, что и в вэб PHP, PERL, JavaScript, … имеется неплохой опыт разработки.

Не к тому об этом сказал, что хвастаюсь, а для продолжения диалога …

Владимир

anonymous
()
Ответ на: комментарий от anonymous

Возможности у 1С 8.3 и потенциал хороший

Потенциал, в смысле возможности относительно не сложного добавления в 1С 8.3 нового API и не сложного сопряжения с любым существующим.
Несомненно это имеется и в lfusion …

Приведу вам простой пример, а заодно и задам вопрос.
В 1С несложно разработать код /где-то пятьсот строк/, который обеспечит возможность загрузки/выгрузки всех объектов 1С например в MySQL, MSSQL или Firebird без использования всяких ORM.
Так вот в 1С легко производить разработку обобщенных алгоритмов.
В lfusion это также тривиально можно сделать?

Владимир

anonymous
()
Ответ на: комментарий от anonymous

Ни коим образом не являюсь фанатом 1С и говорил о ней не с целью принизить lfusion.
Проект у вас конечно интересный.

Владимир

anonymous
()
Ответ на: комментарий от NitroJunkie

Не, в библиотеке у вас один частный случай, примитивное суммирование (даже по сути без замыканий). А если задача чуть чуть изменяется (добавляются условия / разрезы) нужна новая библиотека?

Не, вы даете пример с суммой, и потом тычите мне этой суммой. :) Я привел еще пример, где изменения вместо суммирования будут журналироваться, спросил, можно ли так у вас, ответа не получил, так что предполагаю, что как раз в lsFusion только сумма и обрабатывается. :) Приведите пример с журналом и с инкрементальным вычислением среднего и дисперсии.

Ну это из разряда, что космолет строится с помощью пилы, молотка и такой то матери. Очень интересно посмотреть как именно это решается. И опять таки чуть усложняем задачу добавляем условия, ещё какие нибудь умножения, сравнения, композиции и т.п.

Огласите весь список, пожалуйста. :) А то и в правду потом космолет запросите.

Собственно в конечном итоге через 16к комитов у вас lsFusion и получится. :)

Нет, я этим заниматься точно не буду, меня и текущее положение дел в ИТ устраивает. :)

Скажем так замыкания (возможность использования внешнего контекста во всех выражениях / действиях в том числе анонимных) есть практически везде. Но передачи функций / действий в качестве параметров пока нет.

И после этого вы ставите свой язык на верхнюю ступеньку? Вам не стыдно? :)

amm
()
Ответ на: комментарий от amm

А что у вас с инкрементальностью, если функция будет не SUM, а например среднее или дисперсия? Тоже все будет автоматически работать?

LAST и MAX скажем инкрементируются эффективно. Остальные агрегирующие функции хуже (сами разрезы эффективно, но в рамках каждого разреза все равно нужен пересчет). Среднее и дисперсия, строго говоря реализуются через два GROUP SUM, каждый из которых инкрементируется эффективно, соответственно и общий результат можно / будет инкрементироваться эффективно.

Но это касается группировки. Остальные операторы тоже зависит. Рекурсия эффективно, разбиение также как и остальные агрегирующие функции (только в рамках разрезов). CASE эффективно (особенно исключающий), +/- игнорирующие null - эффективно, не игнорирующие средне эффективно и т.п.

Но даже в самом худшем случае инкрементируется более менее. И все работает автоматически.

NitroJunkie
() автор топика
Ответ на: комментарий от NitroJunkie

Что значит проектируют в терминах? Проектируют и проектируют, а дальше соответствует или нет. И да, сейчас считается моветоном когда у таблицы нет ключей.

Я бы даже сказал, когда нет суррогатного ключа. Но я забыл, когда об этом говорили в последний раз в контексте соответсвия 3НФ.

А SQL и его обертки остались в парадигме таблиц до сих пор (честно говоря загадка почему).

Думаю, из-за наличия качественных реализаций движков РСУБД. Чем брать кота в мешке, лучше взять проверенное решение. Хранение данных – консервативная область, потому что ответственность высока.

И повышение уровня парадигмы потенциально даёт огромное количество преимуществ которые и есть в lsFusion.

Нет никакого повышения парадигмы, я пока вижу только еще одну платформу со странным языком.

amm
()
Ответ на: комментарий от NitroJunkie

EXPORT Object o WHERE o IS Object;

В каждой из перечисленных СУБД ведь и свои особенности есть …

А насчет обобщенных алгоритмов как?

Владимир

anonymous
()
Ответ на: комментарий от amm

Не, вы даете пример с суммой, и потом тычите мне этой суммой.

Я не тычу. Просто привел примитивный пример, потом поменял задачу (добавил композицию в разрез и еще один разрез) чуть-чуть, в lsFusion это 3 секунды. Вам придется еще одну библиотеку на 500 строк писать.

Я привел еще пример, где изменения вместо суммирования будут журналироваться, спросил, можно ли так у вас, ответа не получил

Естественно можно WHEN CHANGED(sumX(X x)) DO NEW ls = LogSumX { date(ls) <- currentDate(); prevValue(ls) <- PREV(sumX(x)); newValue(ls) <- sumX(x); }

Огласите весь список, пожалуйста. :) А то и в правду потом космолет запросите.

Persistent и чтобы n+1 не было, достаточно.

И после этого вы ставите свой язык на верхнюю ступеньку? Вам не стыдно? :)

Есть несколько «заменителей» лямбд метакоды (типа макросов C, только по элементам) и EVAL (выполнение кода заданного в строке, например того же вызова действия).

А вообще лямбды перпендикулярный функционал. В SQL тоже лямбд нет, но по уровню декларативности (магии как вы ее называете) логики вычислений он превосходит все императивные языки на порядок. Хорошо это или плохо можно спорить, но факт что он сейчас один из самых распространенных языков в бизнес-приложениях говорит сам за себя (обертки могут быть на 1С, .Net, Python, PHP но SQL там есть всегда).

NitroJunkie
() автор топика
Ответ на: комментарий от NitroJunkie

Смотря что вы под этим имеете ввиду.

О eval() вы уже сказали, так что на вопрос вы ответили.

Владимир 123

anonymous
()
Ответ на: комментарий от anonymous

О eval() вы уже сказали, так что на вопрос вы ответили.

… В основном конечно речь шла о run-time генерации и выполнении кода.
С загрузкой/выгрузкой данных в СУБД как раз такой подход и используется, но имеются и другие способы разработки обобщенных алгоритмов …

Владимир 123

anonymous
()
Ответ на: комментарий от NitroJunkie

LAST и MAX скажем инкрементируются эффективно.

Очень интересно посмотреть на инкрементальную реализацию этих функций. С добавлением все понятно, но что происходит при удаление элементов из списка?

Среднее и дисперсия, строго говоря реализуются через два GROUP SUM, каждый из которых инкрементируется эффективно, соответственно и общий результат можно / будет инкрементироваться эффективно.

Да, с суммой проблем нет. :)

amm
()
Ответ на: комментарий от NitroJunkie

Просто привел примитивный пример, потом поменял задачу (добавил композицию в разрез и еще один разрез) чуть-чуть, в lsFusion это 3 секунды. Вам придется еще одну библиотеку на 500 строк писать.

В библиотеке ничего не надо будет менять. При описании классов с данными только надо указать, что при изменении Item.H.L должно приходить событие об изменении Item.H.

Persistent и чтобы n+1 не было, достаточно.

Persistent для вычисляемого значения или для списка с данными? Где здесь n+1 может возникнуть?

Есть несколько «заменителей» лямбд метакоды (типа макросов C, только по элементам) и EVAL (выполнение кода заданного в строке, например того же вызова действия).

Лямбды в computer science настолько фундаметальная вещь, что вы просто не понимаете о чем говорите.

В SQL тоже лямбд нет, но по уровню декларативности (магии как вы ее называете) логики вычислений он превосходит все императивные языки на порядок. Хорошо это или плохо можно спорить, но факт что он сейчас один из самых распространенных языков в бизнес-приложениях говорит сам за себя (обертки могут быть на 1С, .Net, Python, PHP но SQL там есть всегда).

SQL – всего лишь язык для доступа к данным в РСУБД, в этом он хорош, потому как хорошо поддерживается всеми вендорами. Зачем его сравнивать с языками, которые реализуют совсем другие парадигмы, мне непонятно.

amm
()
Ответ на: комментарий от NitroJunkie

Смотря что вы под этим имеете ввиду.

Еще раз.
Проект у вас хороший и дельных идей много.
Что касается 1С, то «присмотритесь» к ней.
У них много хороших архитектурных решений /но не панацея/.
Например почитайте о событиях, подписке на них, …
Сказано это не к тому, что у вас не правильный подход …

Владимир 123

anonymous
()
Ответ на: комментарий от amm

Очень интересно посмотреть на инкрементальную реализацию этих функций. С добавлением все понятно, но что происходит при удаление элементов из списка?

Хороший вопрос. Но реализация как раз простая - индекс по порядку в LAST (MAX - частный случай LAST, где порядком выступает само значение). Индекс это как правило 2-3 дерево (в современных субд), которое обновляется за логарифм (то есть за константу). Соотвественно достаточно определить разрезы в которых идет изменение, и при удалении считать из индекса.

Другое дело, что материализация (laziness) самого значения функции в принципе не обязательно, так как ее функцию и выполняет сам индекс.

В любом случае для разработчика это все прозрачно, всей этой ерундой занимается платформа вместе с СУБД,

NitroJunkie
() автор топика
Ответ на: комментарий от NitroJunkie

В любом случае для разработчика это все прозрачно, всей этой ерундой занимается платформа вместе с СУБД,

СУБД разные бывают.
Ваша платформа на какую ориентирована.

Владимир 123

anonymous
()
Ответ на: комментарий от amm

В библиотеке ничего не надо будет менять. При описании классов с данными только надо указать, что при изменении Item.H.L должно приходить событие об изменении Item.H.

Тут фокус, что при изменении H1.L, нужно найти все Item у которых Item.H = H1 и для них вызвать события изменения до, потом изменить L и вызвать события изменения после. Я честно не понимаю, как это сделать, тем более прозрачно (чтобы была «общая библиотека»). Даже императивно, а так чтобы в итоге был один SQL запрос как это делает lsFusion (причем одновременно могут меняться и Item.H и H.L) тем более.

Persistent для вычисляемого значения

Да для вычисляемого значения. Впрочем и Item, все коллекции persistent тоже.

Где здесь n+1 может возникнуть?

Да везде. Сама идеология notify (триггеров по сути) императивна в вашем случае, так как вызывается для одного объекта.

Ну и вообще хочется посмотреть как этот ваш EventAggregator будет маппиться на SQL (чтобы выполнять все там).

Лямбды в computer science настолько фундаметальная вещь, что вы просто не понимаете о чем говорите.

Причем тут computer science? Если не заниматься теоретизированием (как с монадами), в той же java, лямбда это не более чем анонимный класс с одним методом. До 8 java так все и делалось, было чуть больше кода не более. Зато не раздувался язык.

Ну и опять таки фундаментальность вещь относительная (и зависит от предметной области). SQL тоже в свое время не был фундаментальным, потом стал.

SQL – всего лишь язык для доступа к данным в РСУБД, в этом он хорош, потому как хорошо поддерживается всеми вендорами. Зачем его сравнивать с языками, которые реализуют совсем другие парадигмы, мне непонятно.

Это язык работы с данными. Ровно как и любой классический язык это язык работы с данными. Собственно сам факт того, что разработчику часто приходится выбирать, между тем, делать работу на сервере приложений через ORM или на сервере БД через SQL, говорит о том что решаемые задачи очень схожи (я кстати знаю много случаев реальных проектов, где 1 подход приходилось менять на второй). То есть их сравнение более чем актуально. Да они используют разные парадигмы, но оба подхода полны по тьюрингу и оба используются для решения задачи вычисления данных. Типа как электромобили и автомобили с ДВС, абсолютно разные механизмы, но и те и те используются для перемещения (хотя тот же электромобиль можно еще использовать для электрификации дома, а бензин еще и для розжига костра).

NitroJunkie
() автор топика
Ответ на: комментарий от anonymous

Например почитайте о событиях, подписке на них, …

События в 1С это не более чем триггеры в СУБД. В lsFusion они поддерживаются куда в более общем случае, можно подписываться на изменение вычисляемых данных скажем.

WHEN SET(debt(Customer c)) DO
    EMAIL 'ALERT';

Где debt может вычисляться по весьма сложному алгоритму.

NitroJunkie
() автор топика
Ответ на: комментарий от anonymous

СУБД разные бывают. Ваша платформа на какую ориентирована.

Да, бывают. https://habr.com/ru/company/lsfusion/blog/463095/

Но именно задача платформы сделать так чтобы под все СУБД она работала одинаково. Но естественно правильнее всего ориентироваться на «самое слабое звено» - Postgres, у которого оптимизатор тупой как пробка, или точнее как автомат Калашникова (что впрочем во многих случаях скорее плюс).

NitroJunkie
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.