Сообщение Re[13]: Догонит ли net java? от 05.12.2022 18:53
Изменено 05.12.2022 19:01 Sinclair
Re[13]: Догонит ли net java?
Здравствуйте, ·, Вы писали:
S>>А что там внутри этих updateBBB()?
·>Там ещё могут быть простыни кода, ведь у нас 40 полей которые надо по всякому вычислять и проставлять. Если модификация p происходит очень сложно, то хочется это всё разрезать на мелкие кусочки по разным методам или даже классам, иногда даже реюзабельным из разных мест.
Ну, и в чём проблема? Любое поле — это всего лишь значение. Для его вычисления есть формула.
В иммутабельном мире есть одна проблема — если, к примеру, целиковое "изменение" объекта тривиально расписывается в стиле
несмотря на его иммутабельность, сигнатуру "мутабельного" метода можно поменять
и всё будет работать, то с отдельными свойствами композитных объектов так сделать не получится. Если у меня immutable record Point(int x, int y), то запись вроде p.x += 5 запрещена.
Нельзя и сигнатуру у сеттера поменять, чтобы он перестал быть void, а стал возвращать Point.
И вот для обхода этой проблемы предлагается конструкция with.
Она позволяет легко и очевидно перейти от мутабельного кода к иммутабельному:
var mp = new MutablePoint(0, 0);
var ip = new Point(0,0);
mp.X += 10;
ip = ip with X = 10;
if (42 mod 17 != 1)
{
mp.X = mp.Y = 13;
ip = ip with {
}
S>>Почему нельзя просто сделать тот же With? Ведь при присванивании "в себя же" ескейп-анализ уберёт всю лишнюю нагрузку на GC, в итоге имеем тот же перформанс, лаконичный синтаксис, и отсутствие необходимости для каждого DTO еще и цельный билдер расписывать.
·>Как я понял, ты предлагаешь что-то вроде
·>
·>но это тоже частный случай, да и выглядит коряво, имхо. Захочется манипулировать одновременно двумя билдерами, то опять что-то новое придумывать:
·>
·>как тут можнро сделать красивее?
·>Лично мне пока самым удобным показалось то, что генерирует Avro, как тут. (генерацию setters для самих dto можно запретить, оставить только у билдеров).
S>>·>Ты прав. Можно только новый тип создавать оказывается.
S>>Переходите на сторону CLR. У нас всё это есть Включая "annotation processors"
·>Нее... мы мееедленно спускаемся.
S>>А что там внутри этих updateBBB()?
·>Там ещё могут быть простыни кода, ведь у нас 40 полей которые надо по всякому вычислять и проставлять. Если модификация p происходит очень сложно, то хочется это всё разрезать на мелкие кусочки по разным методам или даже классам, иногда даже реюзабельным из разных мест.
Ну, и в чём проблема? Любое поле — это всего лишь значение. Для его вычисления есть формула.
В иммутабельном мире есть одна проблема — если, к примеру, целиковое "изменение" объекта тривиально расписывается в стиле
var date = DateTime.Now;
date += TimeSpan.FromMinutes(42); // == date = date + TimeSpan.FromMinutes(42);
несмотря на его иммутабельность, сигнатуру "мутабельного" метода можно поменять
var l = new ImmutableList<int> {4, 8, 15, 16, 23};
l.Add(42); // ah-ah!
l = l.Add(42); // good boy!
и всё будет работать, то с отдельными свойствами композитных объектов так сделать не получится. Если у меня immutable record Point(int x, int y), то запись вроде p.x += 5 запрещена.
Нельзя и сигнатуру у сеттера поменять, чтобы он перестал быть void, а стал возвращать Point.
p1.x = p1.y = 0; // intuitievely clean, but doesn't work in immutable case
(p1.y = 0).x = 0; // in case p1.y = 0 yields Point, not int.
И вот для обхода этой проблемы предлагается конструкция with.
Она позволяет легко и очевидно перейти от мутабельного кода к иммутабельному:
var mp = new MutablePoint(0, 0);
var ip = new Point(0,0);
mp.X += 10;
ip = ip with X = 10;
if (42 mod 17 != 1)
{
mp.X = mp.Y = 13;
ip = ip with {
}
S>>Почему нельзя просто сделать тот же With? Ведь при присванивании "в себя же" ескейп-анализ уберёт всю лишнюю нагрузку на GC, в итоге имеем тот же перформанс, лаконичный синтаксис, и отсутствие необходимости для каждого DTO еще и цельный билдер расписывать.
·>Как я понял, ты предлагаешь что-то вроде
·>
·>public Person modify(Person p) {
·> p = updateAAA(p);
·> ...
·> if(...) p = updateBBB(p);
·> else p = updateCCC(p);
·> ...
·> p = updateDDD(p);
·> return p;
·>}
·>
·>но это тоже частный случай, да и выглядит коряво, имхо. Захочется манипулировать одновременно двумя билдерами, то опять что-то новое придумывать:
·>
·>public Result enrich(Person p, Order o) {
·> var iBuilder = Info.newBuilder();
·> var pBuilder = p.builder();
·> var oBuilder = o.builder();
·> updateAAA(pBuilder, iBuilder);
·> updateBBB(oBuilder, iBuilder);
·> updateCCC(oBuilder, pBuilder);
·> return new Result(pBuilder.build(), pBuilder.build(), iBuilder.build());
·>}
·>
·>как тут можнро сделать красивее?
·>Лично мне пока самым удобным показалось то, что генерирует Avro, как тут. (генерацию setters для самих dto можно запретить, оставить только у билдеров).
S>>·>Ты прав. Можно только новый тип создавать оказывается.
S>>Переходите на сторону CLR. У нас всё это есть Включая "annotation processors"
·>Нее... мы мееедленно спускаемся.
Re[13]: Догонит ли net java?
Здравствуйте, ·, Вы писали:
S>>А что там внутри этих updateBBB()?
·>Там ещё могут быть простыни кода, ведь у нас 40 полей которые надо по всякому вычислять и проставлять. Если модификация p происходит очень сложно, то хочется это всё разрезать на мелкие кусочки по разным методам или даже классам, иногда даже реюзабельным из разных мест.
Ну, и в чём проблема? Любое поле — это всего лишь значение. Для его вычисления есть формула.
В иммутабельном мире есть одна проблема — если, к примеру, целиковое "изменение" объекта тривиально расписывается в стиле
несмотря на его иммутабельность, сигнатуру "мутабельного" метода можно поменять
и всё будет работать, то с отдельными свойствами композитных объектов так сделать не получится. Если у меня immutable record Point(int x, int y), то запись вроде p.x += 5 запрещена.
Нельзя и сигнатуру у сеттера поменять, чтобы он перестал быть void, а стал возвращать Point.
И вот для обхода этой проблемы предлагается конструкция with.
Она позволяет легко и очевидно перейти от мутабельного кода к иммутабельному:
S>>Почему нельзя просто сделать тот же With? Ведь при присванивании "в себя же" ескейп-анализ уберёт всю лишнюю нагрузку на GC, в итоге имеем тот же перформанс, лаконичный синтаксис, и отсутствие необходимости для каждого DTO еще и цельный билдер расписывать.
·>Как я понял, ты предлагаешь что-то вроде
·>
Да, а почему нет?
·>но это тоже частный случай, да и выглядит коряво, имхо. Захочется манипулировать одновременно двумя билдерами, то опять что-то новое придумывать:
·>
·>как тут можнро сделать красивее?
Эмм, да всё что угодно тут будет красивее.
Хотя бы так — если уж очень хочется.
·>Лично мне пока самым удобным показалось то, что генерирует Avro, как тут. (генерацию setters для самих dto можно запретить, оставить только у билдеров).
Ну, это тот самый способ со сменой сигнатуры у сеттера на возврат self. Так себе решение, по сравнению с with operator, кмк. Лучше, чем ничего, конечно.
·>Нее... мы мееедленно спускаемся.
А стадо тем временем всё дальше и дальше.
S>>А что там внутри этих updateBBB()?
·>Там ещё могут быть простыни кода, ведь у нас 40 полей которые надо по всякому вычислять и проставлять. Если модификация p происходит очень сложно, то хочется это всё разрезать на мелкие кусочки по разным методам или даже классам, иногда даже реюзабельным из разных мест.
Ну, и в чём проблема? Любое поле — это всего лишь значение. Для его вычисления есть формула.
В иммутабельном мире есть одна проблема — если, к примеру, целиковое "изменение" объекта тривиально расписывается в стиле
var date = DateTime.Now;
date += TimeSpan.FromMinutes(42); // == date = date + TimeSpan.FromMinutes(42);
несмотря на его иммутабельность, сигнатуру "мутабельного" метода можно поменять
var l = new ImmutableList<int> {4, 8, 15, 16, 23};
l.Add(42); // ah-ah!
l = l.Add(42); // good boy!
и всё будет работать, то с отдельными свойствами композитных объектов так сделать не получится. Если у меня immutable record Point(int x, int y), то запись вроде p.x += 5 запрещена.
Нельзя и сигнатуру у сеттера поменять, чтобы он перестал быть void, а стал возвращать Point.
p1.x = p1.y = 0; // intuitievely clean, but doesn't work in immutable case
(p1.y = 0).x = 0; // in case p1.y = 0 yields Point, not int.
И вот для обхода этой проблемы предлагается конструкция with.
Она позволяет легко и очевидно перейти от мутабельного кода к иммутабельному:
var mp = new MutablePoint(0, 0);
var ip = new Point(0,0);
mp.X += 10;
ip = ip with X = 10;
if (42 mod 17 != 1)
{
mp.X = mp.Y = 13;
ip = ip with { X = 13; Y = 13; }
}
S>>Почему нельзя просто сделать тот же With? Ведь при присванивании "в себя же" ескейп-анализ уберёт всю лишнюю нагрузку на GC, в итоге имеем тот же перформанс, лаконичный синтаксис, и отсутствие необходимости для каждого DTO еще и цельный билдер расписывать.
·>Как я понял, ты предлагаешь что-то вроде
·>
·>public Person modify(Person p) {
·> p = updateAAA(p);
·> ...
·> if(...) p = updateBBB(p);
·> else p = updateCCC(p);
·> ...
·> p = updateDDD(p);
·> return p;
·>}
·>
Да, а почему нет?
·>но это тоже частный случай, да и выглядит коряво, имхо. Захочется манипулировать одновременно двумя билдерами, то опять что-то новое придумывать:
·>
·>public Result enrich(Person p, Order o) {
·> var iBuilder = Info.newBuilder();
·> var pBuilder = p.builder();
·> var oBuilder = o.builder();
·> updateAAA(pBuilder, iBuilder);
·> updateBBB(oBuilder, iBuilder);
·> updateCCC(oBuilder, pBuilder);
·> return new Result(pBuilder.build(), pBuilder.build(), iBuilder.build());
·>}
·>
·>как тут можнро сделать красивее?
Эмм, да всё что угодно тут будет красивее.
Хотя бы так — если уж очень хочется.
public Result enrich(Person p, Order o) {
var i = new Info();
(p, i) = updateAAA(p, i);
(o, i) = updateBBB(o, i);
(o, p) = updateCCC(o, p);
return new Result(p, o, i);
}
·>Лично мне пока самым удобным показалось то, что генерирует Avro, как тут. (генерацию setters для самих dto можно запретить, оставить только у билдеров).
Ну, это тот самый способ со сменой сигнатуры у сеттера на возврат self. Так себе решение, по сравнению с with operator, кмк. Лучше, чем ничего, конечно.
·>Нее... мы мееедленно спускаемся.
А стадо тем временем всё дальше и дальше.