Здравствуйте, Serginio1, Вы писали:
S>·>Немного многословно, приходится типы полей прописывать, но вполне юзабельно. S> Кстати в Java завезли аналог IEnumerable c yield
yield как конструкцию языка нет, не завезли. Другие средства есть на уровне библиотек, вроде хватает.
S>То есть вызов осуществляется с права на лево как в C#?
Классика map-reduce — вначале строится цепочка преобразований (flatmaps & Co) потом коллектор (reduce). Коллектор тащит всё через цепочку. Вроде слева направо. Не знаю что ты имеешь в виду "как в C#".
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, ·, Вы писали: S>>·>Немного многословно, приходится типы полей прописывать, но вполне юзабельно. S>> Кстати в Java завезли аналог IEnumerable c yield ·>yield как конструкцию языка нет, не завезли. Другие средства есть на уровне библиотек, вроде хватает.
S>>То есть вызов осуществляется с права на лево как в C#? ·>Классика map-reduce — вначале строится цепочка преобразований (flatmaps & Co) потом коллектор (reduce). Коллектор тащит всё через цепочку. Вроде слева направо. Не знаю что ты имеешь в виду "как в C#".
Ну в C# ты получаешь IEnumerable. Причем не первый а последний. При MoveNext последний дергает MoveNext предыдущего.
И получается, что у самого первого будет проходов равного его размера.
То есть IEnumerable.Range(1,3).Select(i=> new {twice = i * 2, str = "val" + i}).Where(v => v.twice > 3 && v.str.contains("3"));
можно разложить на несколко операторов
list=IEnumerable.Range(1,3);
Обозначим анонимный тип new {twice = i * 2, str = "val" + i} как TResult
select=Enumerable.Select<int,TResult>(list, i=> new {twice = i * 2, str = "val" + i})
и поледний
result=IEnumerable.Where<TResult>(select, v => v.twice > 3 && v.str.contains("3"));
В Итоге ты получаешь IEnumerable<TResult>
И когда ты начинаешь обход или то вызываешь MoveNext у result
Внутри этого класса State Machine. Кстати по этому же принципу работает и async/await/
То есть компилятор берет на себя генерацию анонимных классов (или уже существующих как WhereEnumerableIterator<TSource>) реализующих State Machine и методов IEnumerable MoveNext и Current в итоге.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Sinclair, Вы писали:
S>И там уже даже вроде бы решение придумали, которое всех бы устроило, но "this proposal isn't currently Championed which means that it's not being worked on by the team at this time."
Здравствуйте, ·, Вы писали:
НС>>Можно. А вот если ты те модели выставишь в публичное API — скорее всего будет кака. ·>Whatever, другое api может иметь другое описание и по нему тоже генериться код.
Ну то есть вместо того чтобы просто написать модель мы вынужденны, в силу недостаточной выразительности языка, описывать ее на каком то другом языке и прикручивать генератор. ЧТД.
·>Это довольно частный пример. Впрочем даже в этом случае, можно поверх метода-всемогутера написать соответствующие клиентские юзкейсы конкретного клиента.
Но генератор тогда приносит минимум пользы, основное API приходится описывать руками.
НС>>И во вручную написанном клиенте вместо одного метода-всемогутера было бы N методов под каждый юзкейс. ·>Вручную — это как? Склейкой строк?
Вручную это вручную описывать методы. При чем тут склейка строк?
·>Потому что ты похоже путаешь сценарии конкретного клиента и API предоставляемый сервером, который должен уметь обслуживать различных клиентов.
Нет, это ты почему то решил что есть какой то универсальный API сервера, который не имеет отношения к сценариям использования этого API.
НС>>Аналогичная ситуация и с ORM. Вся идея с тем, что мы ORM кормим POCO, а потом эти же POCO выставляем в публичный API работает только на демках. Еще хуже работает когда эти POCO не вручную пишутся, а генерируются из схемы БД. Поэтому в реальности в лучшем случае только сабсет модели общий для всей цепочки, а полная модель у ORM, REST и клиента у каждого своя. ·>Это проблема SRP, а не кодогенерации.
Это проблема несовпадения разных моделей.
·>Если одну и ту же штуку пытаться впихнуть в два места, то ничего хорошего не выйдет.
Так твое предложение по единому описанию генерировать несколько моделей как раз такое впихивание и есть. Или ты предлагаешь для каждой модели свое описание и свой генератор?
·> .map(i -> new Object() {final int twice = i * 2; final String str = "val" + i;})
Здравствуйте, Ночной Смотрящий, Вы писали:
НС>>>Можно. А вот если ты те модели выставишь в публичное API — скорее всего будет кака. НС>·>Whatever, другое api может иметь другое описание и по нему тоже генериться код. НС>Ну то есть вместо того чтобы просто написать модель мы вынужденны, в силу недостаточной выразительности языка, описывать ее на каком то другом языке и прикручивать генератор. ЧТД.
Я говорю о language-agnostic спеке. Когда ты пишешь какой-нибудь rest api, то у тебя уже должна быть какая-то спека, которую ты выдаёшь консьюмерам api. Или ты предлагаешь отправлять исходники твоего сервера, чтобы они потом сами разбирались что твоё поделие делает? Или так, в pdf-ке пишешь, чтоб было с чем развлекаться?
Следовательно, если эта спека есть, то надо бы как-то проверить, что "просто написанная модель" этой спеке хоть как-то соответствует. Самый простой и прямой способ — сгенерить по спеке код, а не писать ещё одну модель и потом неясно как валидировать.
НС>·>Это довольно частный пример. Впрочем даже в этом случае, можно поверх метода-всемогутера написать соответствующие клиентские юзкейсы конкретного клиента. НС>Но генератор тогда приносит минимум пользы, основное API приходится описывать руками.
Не API, а сценарии.
НС>>>И во вручную написанном клиенте вместо одного метода-всемогутера было бы N методов под каждый юзкейс. НС>·>Вручную — это как? Склейкой строк? НС>Вручную это вручную описывать методы. При чем тут склейка строк?
И что эти методы будут делать? Тебе по сути надо преобразовывать языковые конструкции в пачки байтов, в виде json/fix/protobuf/etc. Как именно это будет происходить?
НС>·>Потому что ты похоже путаешь сценарии конкретного клиента и API предоставляемый сервером, который должен уметь обслуживать различных клиентов. НС>Нет, это ты почему то решил что есть какой то универсальный API сервера, который не имеет отношения к сценариям использования этого API.
Это не я решил, это ты сам так заявил: "имеем один uri (часто это явно зафиксировано в гайдлайнах), и, как следствие, один метод контроллера сервиса... на все случаи жизни".
НС>>>Аналогичная ситуация и с ORM. Вся идея с тем, что мы ORM кормим POCO, а потом эти же POCO выставляем в публичный API работает только на демках. Еще хуже работает когда эти POCO не вручную пишутся, а генерируются из схемы БД. Поэтому в реальности в лучшем случае только сабсет модели общий для всей цепочки, а полная модель у ORM, REST и клиента у каждого своя. НС>·>Это проблема SRP, а не кодогенерации. НС>Это проблема несовпадения разных моделей.
Я об этом и говорю. Одну модель пытаешься впихнуть в два разных места. Это нарушение srp. Ну не надо так делать.
НС>·>Если одну и ту же штуку пытаться впихнуть в два места, то ничего хорошего не выйдет. НС>Так твое предложение по единому описанию генерировать несколько моделей как раз такое впихивание и есть. Или ты предлагаешь для каждой модели свое описание и свой генератор?
Скажем, в условном приложении у тебя есть rest api с openapi и sql с каким-нибудь query-builder-ом. Ясен пень будет совершенно разные модели и свои генераторы.
НС>·> .map(i -> new Object() {final int twice = i * 2; final String str = "val" + i;}) НС>А чтобы свойства?
Не понял вопрос. Метод что-ли (что-то вроде new Object() {String calc(){return "calc" + i;}})? Или модифицируемое поле (просто убери final)?
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, ·, Вы писали:
НС>>Ну то есть вместо того чтобы просто написать модель мы вынужденны, в силу недостаточной выразительности языка, описывать ее на каком то другом языке и прикручивать генератор. ЧТД. ·>Я говорю о language-agnostic спеке. Когда ты пишешь какой-нибудь rest api, то у тебя уже должна быть какая-то спека, которую ты выдаёшь консьюмерам api.
У меня эта спека генерируется по классам контроллеров. Описание на C# — основное.
НС>>Но генератор тогда приносит минимум пользы, основное API приходится описывать руками. ·>Не API, а сценарии.
API должно быть ориентировано на сценарии, иначе это плохое API, неудобное.
НС>>Вручную это вручную описывать методы. При чем тут склейка строк? ·>И что эти методы будут делать?
Непонятен вопрос.
·> Тебе по сути надо преобразовывать языковые конструкции в пачки байтов, в виде json/fix/protobuf/etc. Как именно это будет происходить?
Какое это имеет отношение к обсуждаемому вопросу?
НС>>Нет, это ты почему то решил что есть какой то универсальный API сервера, который не имеет отношения к сценариям использования этого API. ·>Это не я решил, это ты сам так заявил: "имеем один uri (часто это явно зафиксировано в гайдлайнах), и, как следствие, один метод контроллера сервиса... на все случаи жизни".
Я сказал совсем другое. REST API проектируется исходя из одного гайдлайна, структура БД — из другого, классы моделей — из третьего. Если одно генерировать из другого — неизбежны проблемы, потому что принципы проектирования не совпадают, а иногда даже противоречат друг другу.
НС>>Это проблема несовпадения разных моделей. ·>Я об этом и говорю. Одну модель пытаешься впихнуть в два разных места.
Это не я пытаюсь, это следствие попыток генерации нескольких моделей по одному описанию. Я говорю прямо обратное — модели эти должны быть разными.
НС>>Так твое предложение по единому описанию генерировать несколько моделей как раз такое впихивание и есть. Или ты предлагаешь для каждой модели свое описание и свой генератор? ·>Скажем, в условном приложении у тебя есть rest api с openapi и sql с каким-нибудь query-builder-ом. Ясен пень будет совершенно разные модели и свои генераторы.
Нет, не ясен. Я пока не понимаю что ты описываешь. Откуда берутся разные модели, что делает каждый из разных генераторов? Давай конкретно. Есть классический бэк RDBMS -> код бэка на Java/C# -> REST API -> код клиента на Java/C#/JS. Какие у тебя тут будут описания, генераторы и модели?
Здравствуйте, Ночной Смотрящий, Вы писали:
НС>>>Ну то есть вместо того чтобы просто написать модель мы вынужденны, в силу недостаточной выразительности языка, описывать ее на каком то другом языке и прикручивать генератор. ЧТД. НС>·>Я говорю о language-agnostic спеке. Когда ты пишешь какой-нибудь rest api, то у тебя уже должна быть какая-то спека, которую ты выдаёшь консьюмерам api. НС>У меня эта спека генерируется по классам контроллеров. Описание на C# — основное.
Т.е. code-first, далеко не всегда работает, как минимумт только если ты вендор api. И посмотрел бы я на такой подход для, скажем, схемы субд.
НС>>>Но генератор тогда приносит минимум пользы, основное API приходится описывать руками. НС>·>Не API, а сценарии. НС>API должно быть ориентировано на сценарии, иначе это плохое API, неудобное.
Я знаю. Ты сам стал рассматривать такое api. Я сразу заявил, что это частный случай.
НС>>>Вручную это вручную описывать методы. При чем тут склейка строк? НС>·>И что эти методы будут делать? НС>Непонятен вопрос.
Ну вот нужен тебе сервис для общения через protobuf. Что ты предлагаешь писать вручную?
НС>·> Тебе по сути надо преобразовывать языковые конструкции в пачки байтов, в виде json/fix/protobuf/etc. Как именно это будет происходить? НС>Какое это имеет отношение к обсуждаемому вопросу?
Ты заявил, что ты собрался писать что-то вручную. Объясни как ты будешь писать тот же json вручную, да так, чтобы убедиться, что его другие могут вменяемо прочитать.
НС>>>Нет, это ты почему то решил что есть какой то универсальный API сервера, который не имеет отношения к сценариям использования этого API. НС>·>Это не я решил, это ты сам так заявил: "имеем один uri (часто это явно зафиксировано в гайдлайнах), и, как следствие, один метод контроллера сервиса... на все случаи жизни". НС>Я сказал совсем другое. REST API проектируется исходя из одного гайдлайна, структура БД — из другого, классы моделей — из третьего. Если одно генерировать из другого — неизбежны проблемы, потому что принципы проектирования не совпадают, а иногда даже противоречат друг другу.
Согласен. А кто-то пытается генерить бд из rest?!..
НС>>>Это проблема несовпадения разных моделей. НС>·>Я об этом и говорю. Одну модель пытаешься впихнуть в два разных места. НС>Это не я пытаюсь, это следствие попыток генерации нескольких моделей по одному описанию. Я говорю прямо обратное — модели эти должны быть разными.
Я не знаю кто так пытался и зачем. Может ты меня не так понял. Я предлагал иметь одно описание и генерить по нему код взаимодействующих участников. Т.е., например, по одному openapi генерить код и клиента, и сервера. сгенерённый код уже обмазывать реализующей логикой.
НС>>>Так твое предложение по единому описанию генерировать несколько моделей как раз такое впихивание и есть. Или ты предлагаешь для каждой модели свое описание и свой генератор? НС>·>Скажем, в условном приложении у тебя есть rest api с openapi и sql с каким-нибудь query-builder-ом. Ясен пень будет совершенно разные модели и свои генераторы. НС>Нет, не ясен. Я пока не понимаю что ты описываешь. Откуда берутся разные модели, что делает каждый из разных генераторов? Давай конкретно. Есть классический бэк RDBMS -> код бэка на Java/C# -> REST API -> код клиента на Java/C#/JS. Какие у тебя тут будут описания, генераторы и модели?
1. описание ddl для rdbms -> генерим код для бэка на java/c#
2. описание rest api (ну какой-нибудь openapi) генерим код для бэка на java/c#
3. Пишем логику бэка используя код сгенерённый в 1 и 2.
4. то же описание из 2 используем для генерапции клиентов на Java/C#/JS.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, scf, Вы писали:
scf>Здравствуйте, vaa, Вы писали:
vaa>>Вот смотрю я на фичи java
scf>Сумбурно и мысль не очень понятна, но вот моё мнение: дотнет как язык С# и платформа лучше джавы, но никогда не догонит её по популярности, т.к. доверять бесплатным решениям Майкрософт дураков нет, и к платным тоже хватает вопросов.
Здравствуйте, vsb, Вы писали:
vsb>В жаве в 2022 году нужно генерировать геттеры и сеттеры.
vsb>Это всё, что надо знать про разработчиков языка.
Java расширябельная в некоторых пределах, если не хочешь использовать автоматическую генерацию геттеров/сеттеров, можно использовать например https://projectlombok.org/features/GetterSetter
Здравствуйте, vsb, Вы писали:
vsb>Здравствуйте, iHateBrightVictories, Вы писали:
vsb>>>В жаве в 2022 году нужно генерировать геттеры и сеттеры.
HBV>>https://projectlombok.org/features/GetterSetter
vsb>Я про жаву а не про ломбок.
Ну Lombok это просто плагин к компилятору Java по сути, а не что-то отдельное.
Здравствуйте, VladiCh, Вы писали:
vsb>>Я про жаву а не про ломбок. VC>Ну Lombok это просто плагин к компилятору Java по сути, а не что-то отдельное.
Неправда.
Lombok is a huge hack that will only compile using javac or eclipse's compiler.
Здравствуйте, Ночной Смотрящий, Вы писали:
НС>·>Я говорю о language-agnostic спеке. Когда ты пишешь какой-нибудь rest api, то у тебя уже должна быть какая-то спека, которую ты выдаёшь консьюмерам api. НС>У меня эта спека генерируется по классам контроллеров. Описание на C# — основное.
А вот
Здравствуйте, ·, Вы писали:
НС>>У меня эта спека генерируется по классам контроллеров. Описание на C# — основное. ·>Т.е. code-first, далеко не всегда работает
А я и не говорил что работает всегда. Зато когда оно работает ...
НС>>>>Но генератор тогда приносит минимум пользы, основное API приходится описывать руками. НС>>·>Не API, а сценарии. НС>>API должно быть ориентировано на сценарии, иначе это плохое API, неудобное. ·>Я знаю. Ты сам стал рассматривать такое api. Я сразу заявил, что это частный случай.
Ничего не понял. API основанное на сценариях — частный случай?
НС>>>>Вручную это вручную описывать методы. При чем тут склейка строк? НС>>·>И что эти методы будут делать? НС>>Непонятен вопрос. ·>Ну вот нужен тебе сервис для общения через protobuf. Что ты предлагаешь писать вручную?
Я не понимаю какое это имеет отношение к разговору.
НС>>·> Тебе по сути надо преобразовывать языковые конструкции в пачки байтов, в виде json/fix/protobuf/etc. Как именно это будет происходить? НС>>Какое это имеет отношение к обсуждаемому вопросу? ·>Ты заявил, что ты собрался писать что-то вручную. Объясни как ты будешь писать тот же json вручную
Я не заявлял что я собираюсь писать json вручную. Я говорил о классах модели.
·>1. описание ddl для rdbms -> генерим код для бэка на java/c#
Разные модели — раз.
·>2. описание rest api (ну какой-нибудь openapi) генерим код для бэка на java/c#
Разные модели — два.
·>4. то же описание из 2 используем для генерапции клиентов на Java/C#/JS.
НС>Это не я пытаюсь, это следствие попыток генерации нескольких моделей по одному описанию.
·>Я не знаю кто так пытался и зачем. Может ты меня не так понял.
Здравствуйте, VladiCh, Вы писали:
HBV>>>https://projectlombok.org/features/GetterSetter
vsb>>Я про жаву а не про ломбок.
VC>Ну Lombok это просто плагин к компилятору Java по сути, а не что-то отдельное.
Ломбок это отдельный язык. Похожий на Java, но это не Java. У Java-компилятора нет никаких плагинов. То, что он реализован, как annotation processing tool и в процессе вызова использует внутренние API компилятора через reflection и прочее — не делает его просто плагином. В Java нет разрешённого способа реализовать функционал ломбока без хаков. Lombok ломается при каждой крупной переработке внутренностей компилятора. И когда-нибудь сломается окончательно.
PS при этом в своих проектах я его использую. Потому, что это прагматичный подход. Хак, не хак, а он пока работает и в IDE поддерживается неплохо. А когда перестанет работать — сделаю delombok. Тем не менее нормальной такую ситуацию я не считаю.
Здравствуйте, Ночной Смотрящий, Вы писали:
НС>>>У меня эта спека генерируется по классам контроллеров. Описание на C# — основное. НС>·>Т.е. code-first, далеко не всегда работает НС>А я и не говорил что работает всегда. Зато когда оно работает ...
Хреново оно работает.
НС>·>А вот
и результат такого подхода. НС>Нет, это результат кривого генератора.
Дело в том, что "прямой" генератор описания по коду невозможно написать даже теоретически.
Код — это тьюринг-полный яп, а описание — довольно примитивный язык разметки структур данных.
Можно, конечно, придумать поверх яп какой-то набор правил и соглашений (которые как формализовать-то? как валидировать?), следуя которым будем писать код, по которому может сгенериться вменяемое описание. Но зачем придумывать ещё один язык?..
НС>>>>>Но генератор тогда приносит минимум пользы, основное API приходится описывать руками. НС>>>·>Не API, а сценарии. НС>>>API должно быть ориентировано на сценарии, иначе это плохое API, неудобное. НС>·>Я знаю. Ты сам стал рассматривать такое api. Я сразу заявил, что это частный случай. НС>Ничего не понял. API основанное на сценариях — частный случай?
Смотри мою эту цитату и выше "Это довольно частный пример. Впрочем даже в этом случае, можно поверх метода-всемогутера написать соответствующие клиентские юзкейсы конкретного клиента.".
НС>>>Непонятен вопрос. НС>·>Ну вот нужен тебе сервис для общения через protobuf. Что ты предлагаешь писать вручную? НС>Я не понимаю какое это имеет отношение к разговору.
Лично я говорю о генерации кода по описаниям. А о чём говоришь ты — я не знаю.
Как правило по модели данных, описанных в виде .proto используют protoc генератор кода, создающий классы на разных яп. Ты, как я понял, предлагаешь вначале напедалить код (как именно — не сообщаешь) и попытаться из него сгенерить .proto-описания.
НС>>>·> Тебе по сути надо преобразовывать языковые конструкции в пачки байтов, в виде json/fix/protobuf/etc. Как именно это будет происходить? НС>>>Какое это имеет отношение к обсуждаемому вопросу? НС>·>Ты заявил, что ты собрался писать что-то вручную. Объясни как ты будешь писать тот же json вручную НС>Я не заявлял что я собираюсь писать json вручную. Я говорил о классах модели.
Что за классы модели? И причём тут генерация кода?
НС>·>1. описание ddl для rdbms -> генерим код для бэка на java/c# НС>Разные модели — раз. НС>Разные модели — два.
Где что разное? Модели чего?
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, ·, Вы писали:
НС>>>>У меня эта спека генерируется по классам контроллеров. Описание на C# — основное. НС>>·>Т.е. code-first, далеко не всегда работает НС>>А я и не говорил что работает всегда. Зато когда оно работает ... ·>Хреново оно работает.
Всегда хреново работает?
НС>>Нет, это результат кривого генератора. ·>Дело в том, что "прямой" генератор описания по коду невозможно написать даже теоретически. ·>Код — это тьюринг-полный яп, а описание — довольно примитивный язык разметки структур данных. ·>Можно, конечно, придумать поверх яп какой-то набор правил и соглашений (которые как формализовать-то? как валидировать?), следуя которым будем писать код, по которому может сгенериться вменяемое описание.
Ну вот, ты сам на все ответил.
·> Но зачем придумывать ещё один язык?..
Это наоборот, заставлять писать руками на OpenAPI это придумывать еще один язык.
НС>>·>Я знаю. Ты сам стал рассматривать такое api. Я сразу заявил, что это частный случай. НС>>Ничего не понял. API основанное на сценариях — частный случай? ·>Смотри мою эту цитату
Я ее уже смотрел. Это не отвечает на мои вопросы.
·> и выше "Это довольно частный пример. Впрочем даже в этом случае, можно поверх метода-всемогутера написать соответствующие клиентские юзкейсы конкретного клиента.".
Ну и? Какой тут бенефит от генератора?
НС>>·>Ну вот нужен тебе сервис для общения через protobuf. Что ты предлагаешь писать вручную? НС>>Я не понимаю какое это имеет отношение к разговору. ·>Лично я говорю о генерации кода по описаниям. А о чём говоришь ты — я не знаю.
Я говорю о генерации моделей, я с самого начала про это написал. Генерировать сериализаторы, по крайней мере в дотнете, не нужно. Они сами справляются.
НС>>Я не заявлял что я собираюсь писать json вручную. Я говорил о классах модели. ·>Что за классы модели? И причём тут генерация кода?
Ты совсем потерял нить разговора?
vsb>Глаза закрывать? У меня есть файл, описывающий АПИ. В нём 5 строк кода, вызывающего что-то. В запросе/ответе по 30 полей, к примеру. Итого 65 строк осмысленного кода. И к этим 65 строкам прилагается 480 строк геттеров-сеттеров. И таких запросов, скажем, 20 штук. Лёгким движением руки из 1200 строк получаем 10 000.
·>Обычно получается так, что API описывается каким-то внешним способом (FIX, swagger, avro, protobuf, етс) и код таких классов генерируется.
При чем тут сериализация?
НС>>·>1. описание ddl для rdbms -> генерим код для бэка на java/c# НС>>Разные модели — раз. НС>>Разные модели — два. ·>Где что разное? Модели чего?
Модели разные, а мы их пытаемся генератором преобразовать автоматически, получаем проблемы о которых я писал.