Как стать автором
Обновить

Комментарии 176

А вариант с nodejs ?

Здесь это подразумевается под TypeScript.
А вариант с nodejs ?

Так это не язык.
Раунд 6 см.
Scala мертва?

Может лучше поменять заголовок на «Go лучше всех»?
А если все же про Scala, то у нее есть две проблемы для того, чтобы не использовать ее где-то, кроме BigData:
1) Долгое время авторы Scala «забивали» на обратную совместимость (джаверы к такому не привыкли)
2) Из-за совмещения объектной и функциональной парадигмы (что само по себе круто), на Scala можно писать в стиле Java без точек с запятыми, а можно в стиле Haskel, с блэкджеком и линзами. Из-за этого много времени надо уделять подбору команды или написания гайдов.

Про заголовок — неплохо ;)
На самом деле вообще не было намерения восхвалять Го. Как я отметил, мне сам язык Но не нравится. Но, выходит, что на сегодня для меня лично это первый выбор на написание бэкенда общего назначения.


Что касается проблем Скалы:
1) я лично не считаю это такой уж большой проблемой. Ну да, нет совместимости, но я лично не вижу в этом проблемы. Даже переход между версиями java — это отдельные проект, где надо все проверить и убедиться, что ничего не сломалось.
2) ну тут тоже довольно странно: на java можно писать в объектном стиле, можно писать в процедурном, можно в "реактивном"… кроме того, безобразный код можно написать на любом языке. В любом случае каждый проект устанавливает свои стайл-гайды.

но я лично не вижу в этом проблемы

Вы не видите, а разработчики, которые по 10 лет поддерживают какую-то систему, видят
на java можно писать в объектном стиле, можно писать в процедурном, можно в «реактивном»… кроме того, безобразный код можно написать на любом языке

Ну ладно уж, по крайней мере в процедурном стиле на Java никто не пишет (объектное мышление прививается с самого начала). Да, можно где угодно писать в немного разном стиле и где угодно можно писать говнокод. Просто в случае с Java, если человек пишет в процедурном стиле, то все понимают, что он творит какую-то дичь. А в случае Scala оба подхода декларируются как верные.
Вы не видите, а разработчики, которые по 10 лет поддерживают какую-то систему, видят


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

А в случае Scala оба подхода декларируются как верные.


Но тут опять же возврат к проблеме выбора, которую автор описывал в статье: если ты пишешь ООП, то kotlin будет лучшим выбором для JVM. Другими словами — нету смысла писать чистое ООП на scala.
Разрабочики, которые поддерживают 10 летнее легаси не являются целевой аудиторией как данной статьи в частности

Это почему? В статье обсуждается падение популярности Scala («Scala мертва?»). Далее вопрос, а почему она мертва? Одна из причин это то, что Scala не берут в энтерпрайз, как бы они ни старались. Почему? Потому что ломают совместимость, а это в энтерпрайзе очень важно. Кто не берет? А вот эти дядьки, которые 10 лет поддерживают древнее говно. Когда они все таки уйдут делать что-то новое, то Java для них будет тот надежный инструмент, который они выберут и в дальнейшем.
если ты пишешь ООП, то kotlin будет лучшим выбором для JVM

Допустим, человек писал на ООП микросервис на Scala. Потом он уволился, пришел другой, который вроде тоже пишет на Scala, но на функциональщине. И дальше либо он все выкинет, что писал предыдущий, либо будет «прекрасный зоопарк»
Я всегда избегаю называть что-либо говно, если оно пишется в трезвом уме и прямыми руками. Языки — это лишь инструмент. И есть продукты, которые только написать и запустить займет пару лет, а для некоторых стартапов пару лет это уже «легаси». Так оно блин еще на рынок не вышло, вы чего?

А вот эти дядьки, которые 10 лет поддерживают древнее говно.

Вот серьезно, можно даже не заметить как все что вы пишете становится древним говном. Также как и не заметить что уже прошло 5 лет, 10 лет, 20 лет. Все время кажется что это было совсем совсем недавно, какое легаси как же так.

Для меня легаси означает то, что сейчас совершенно не подерживается.
Например winxp — легаси.
Например Pascal/Cobol легаси. А вот Delphi не легаси, хоть и полуживое.
если оно пишется в трезвом уме и прямыми руками

Это очень редко бывает с продуктом, которому 10 лет. Меняются разработчики, не все из них хорошие, также за долгое время неизбежно бывают костыли, которые впилили потому, что «надо вчера» и т.д. А вообще, выше «говно» я написал иронично, на контрасте к другому комментарию. Проект, который приносит деньги и спокойно развивается называть говном, конечно же, нельзя.
А вот Delphi не легаси, хоть и полуживое

Это вопрос мировосприятия. Для меня Delphi — уже легаси.
Это очень редко бывает с продуктом, которому 10 лет.


Ну вот Линуксу ~30 лет. Явный легаси.

Я наверное не совсем корректно выразился.
Я имел в виду, что отсутствие совместимости — это про леса, которую в принципе можно решать. Явно из-за нее я бы не стал отказываться от инструмента.
Под отсутствием совместимости я имею в виду, что обновив версию Scala, вам придется пройти процедуру миграции, обновить несовместимы код, все протестировать на новой версии.
Хотя как в примере из комментария ниже про Спарк могут быть нюансы.

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

Ну можно же договориться, какой из подходов использовать? Видел реальный проект на Джаве, где в стайл гайдах было написано не использовать стримы, а использовать циклы.

Я выше и написал про договоренности как раз
Из-за этого много времени надо уделять подбору команды или написания гайдов.

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

Я бы сказал, что разработчики, которые написали систему и выкинули ее — это особый класс людей, которым очень повезло (хотя я сам так работал много лет). Я конечно имею в виду тех, кто работает над "живым" проектом.
Да, есть разные ситуации — когда проект никто не трогал много лет и он до сих пор на 5 Джаве. Но в этом случае даже совместимость джавы вам не поможет его обновить на новую версию. Придется очень много всего переписать, заменить часть неподдерживаемых библиотек и т.д. А вот если проект изначально хорошо поддерживается и инкрементально обновляется, то имхо проблема совместимости становится гораздо менее острой.
Хотя опять же бывают исключения.

1) я лично не считаю это такой уж большой проблемой. Ну да, нет совместимости, но я лично не вижу в этом проблемы. Даже переход между версиями java — это отдельные проект, где надо все проверить и убедиться, что ничего не сломалось.


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

Ну да, есть такая проблема на самом деле.и в Джава мире она тоже часто встречается. Когда одна из зависимостей транзитивно зависит на очень старую версию другой библиотеки и не даёт обновить другие зависимости.
Похоже, что эта проблема может на любой платформе возникнуть. Варианта тут 2: либо изолировать такую зависимость (как Спарк) в отдельный сервис (или отдельный класслоадер), или же просто отказаться от ее использования.
Хотя да, скала больше способствует возникновению таких ситуаций. Хоть это и не так плохо как у Питона 2 и 3 :)

вы рассуждаете исходя из теории, но не знаете всей подноготной. Проблема совместимости в скала на удивление острая и решается совсем не так, как в мире джавы. В первую очередь это совместимость на уровне ABI, а не API. В джаве такого просто представить сложно. У вас log4j будет работать на жаве от 1.2 до 15 и далее, а в скале минорный апдейт и молитесь, чтоб был опенсорс и мейнтейнеры обновили со скалы 2.11 на 2.12 и КАЖДАЯ зависимость будет вас задерживать.

для меня лично это первый выбор

почему Go а не C#? C# удивительно немногословен. То что в C# можно сделать одной строкой в Go требуется от 10.
НЛО прилетело и опубликовало эту надпись здесь
>При этом зачем мне как хаскелисту писать на скале
В автономном проекте — скорее всего не за чем. А в условном Hadoop — очень даже есть преимущества. Ну тупо экосистема JVM большая, экосистема Hadoop — тоже. Можно еще парочку таких систем вспомнить (андроид, чего далеко ходить). Зачем вам как хаскелисту писать под андроид на котлине?
НЛО прилетело и опубликовало эту надпись здесь
Ну, теоретически в хадупе можно на чем угодно. Но если на скале это будет удобно и комфортно, то на чем угодно — через геморрой и маты. Ну то есть, если скажем есть API или REST API — то понятно что второй обычно уже не так хорош, особенно если через него нужно пихать терабайты.

Ну причиной может быть например экосистема, которой нет (предположительно) у хаскеля, но есть у скалы.
Вообще есть примеры того, как люди писали http сервера на баше :) (не сравниваю баш и хаскель, просто как пример).

НЛО прилетело и опубликовало эту надпись здесь

Нормальное ФП в JVM-мире есть у Clojure.

НЛО прилетело и опубликовало эту надпись здесь
Я согласен, что F# хорош из того, что годится для энтерпрайза, но если говорить именно о JVM — а я не просто так специально это указал — то единственным адекватным и чистым выбором в ФП-парадигме является Clojure.
НЛО прилетело и опубликовало эту надпись здесь
Недостаток популярности связан с маркетинговым каннибализмом со стороны шарпа. Технологически они одинаково годны для серьёзной разработки. Testimonials.


НЛО прилетело и опубликовало эту надпись здесь
К сожалению, за Хаскелл так и не встала ни одна крупная корпорация, поэтому не могу его обсуждать в контексте энтерпрайза, хотя язык хороший. У OCaml хотя бы есть Jane Street, а что есть у Хаскелла, кроме академии?
НЛО прилетело и опубликовало эту надпись здесь
это, ИМХО, не столь важно и скорее даже вредно для развития.


Начиная с какого то момента распространенности, как это сейчас у C++, можно и без крупной корпорации.

Но многие ли смогли достичь такого уровня самостоятельно?

Кроме Хаскеля не взлетет неплохой в общем то D.
Но взлетели поддерживаемые сильными Rust и Go, на нишу которых D вполне мог бы претендовать.
Python тоже оставался бы нишевым угасающим языком навроде Ruby, если бы не поддержка корпорации.
НЛО прилетело и опубликовало эту надпись здесь
Не уверен, что могу придать такой вес критерию «стоит крупная корпорация». С некоторого момента (который и для хаскеля, и для условного раста, и для окамла давно пройден) это, ИМХО, не столь важно и скорее даже вредно для развития.


Соглашусь, что это ИМХО, но моё ИМХО говорит о том, что когда за языком стоит кто-то, защищающий его от фактора автобуса и вкладывающийся в его маркетинг и поддержку, это больше хорошо, чем плохо.

Так Jane Street им пользуется. Так-то и Galois пользуется коком, но кок в тырпрайзе лично я точно не вижу.


Jane Street вполне себе участвует в разработке OCaml:

blog.janestreet.com/work-on-the-ocaml-compiler-at-jane-street

Microsoft (где работает широко известный в узких кругах Simon-Peyton Jones?), Facebook (Simon Marlow), Касперский что-то на хаскеле делает, из других российских недавно Serokell появился, всякие там Tweag, Well Typed и прочие активно консалтят и контрибьютят


Ребята хорошие, но это всё ресёрч. Касально Microsoft Research, он потом попадает в мэйнстримный шарп, как было с LINQ. Помимо этого, тут мы упираемся в первый вопрос, о необходимости кого-то крупного за спиной языка при его выборе для энтерпрайза — сущности, а не личности.

НЛО прилетело и опубликовало эту надпись здесь
Но тогда он сам становится фактором автобуса.

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

А если язык растёт и развивается без таковых компаний, то это, ИМХО, и значит, что у него всё в порядке.

Так не растут и не развиваются с той же скоростью, как с таковыми, в том и суть.

Из ресёрча там, разве что, работающий в MSR SPJ. Остальные перечисленные вполне себе не ресерч-товарищи (а кучу людей с вузовскими аффилиациями я даже и не упоминал). Фейсбук там антиспам свой держит и другие внутренние инструменты, у гугла были какие-то внутренние проекты, well-typed — консалтеры, просто дофигя коммитят в основной компилятор, tweag — тоже, пусть и коммиттеров чуть меньше (зато вот именно они линейные типы впилили пару месяцев назад), и так далее.


Для Оракла и Майкрософта их языки это флагманы с соответствующими гарантиями, подтвержденными в том числе и юридически. А перечисленные выше проекты на Хаскелле это именно проекты, в крупных технологических компаниях их бывает много, на разных языках и без особых гарантий.
НЛО прилетело и опубликовало эту надпись здесь
Я думаю, что назвать Оракл или Майкрософт подверженными фактору автобуса это большое допущение. На уровне ядерной войны большое.
Интересно, пользователи Google Reader/Picasa/Google+ думали так же?


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

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


Не понял вопроса. Если речь о других языках с корпоративной поддержкой, то кроме Явы и Шарпа, мы имеем сейчас как минимум Го, Раст и Свифт.

Давайте лучше Go обсудим. Какие гарантии подтверждены юридически у Go?


golang.org/doc/go1compat

Критерий готовности языка к тырпрайзу «есть компании, стоящие за этим языком, с юридической поддержкой», то я не знаю, как мы на плюсах писали в прод. К кому надо было бы обращаться, если что? И, кстати, если что?

Да, это важный критерий, хотя и не единственный. Плюсы поддерживает ISO, до стандартизации пользоваться ими для серьёзного энтерпрайза было неоптимально. Собственно, Ява не просто так взлетела.
НЛО прилетело и опубликовало эту надпись здесь
Расказы про F# у меня всегда вызывают улыбку потому что язык вообще никакой да еще и абсолютно мертвый. Количество ПР да и вакансий раз в 5 меньше чем даже у Хаскеля.
Расказы про F# у меня всегда вызывают улыбку потому что язык вообще никакой да еще и абсолютно мертвый. Количество ПР да и вакансий раз в 5 меньше чем даже у Хаскеля.


Про вакансии сегодня — тут совершенно неуместно, если уж язык не развивается.

Язык был довольно интересным-перспективным по своей, если так можно выразиться в отношении языка, архитектуре.

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

Люди до сих пор сожалеют: вот же, был хороший в первом приближении язык, надо было довести до ума и использовать в радость, но злые денежные мешки рассудили иначе.
А Java для Оракла или C# для MS является флагманским продуктом?


Конечно, они или продаются сами или помогают продавать другие продукты.

Мне в языке интересно в первую очередь то, насколько быстро там исправляются проблемы и насколько быстро запиливаются новые фичи, которые упрощают мою жизнь (чтобы не ждать новых стандартов по 13 лет, как было с C++11, и потом ещё 2-3 года на компиляторы).

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


Напомню, что мы всё-таки про энтерпрайз. Новые фичи быстро для него это, скорее, зло. Фиксы, да, но с этим проблем не наблюдается ни у кого. То же касается вопроса про «новые фичи» в Го и Свифте.

Кстати, какой корпорацией поддерживается Rust?


Mozilla, очевидно.

golang.org/doc/go1compat
А юридические гарантии-то тут где? Если они нарушат все эти intensions и expectations, я смогу на них в суд подать?

Это уже придирки к словам, но подать точно сможешь, сможешь ли выиграть, это другой вопрос. Суть не в этом, а в наличии гарантий как таковых.

Что значит «поддерживает»? ISO занимается вопросом стандартизации, а реализациями она не занимается вообще.

Поддерживает в контексте нашего разговора — обеспечивает гарантии стабильности и развития.

Я, честно говоря, немного подустал спорить на эту тему. Оставим этот вопрос на уровне «я бы не стал использовать Хаскелл в крупной разработке, будучи бизнесом», как моё личное мнение. А так язык хороший, да.

НЛО прилетело и опубликовало эту надпись здесь
Окей. Мне просто было очень интересно, как можно считать готовым к тырпрайзу F#, но не считать Haskell.


На остальные пункты мне отвечать уже лениво, но этот это то, с чего мы начали разговор.

Во-первых, я не говорил, что Хаскелл не готов к энтерпрайзу — это ты выразил сомнение, что F# к нему не готов.
Во-вторых, следует уточнить, что F# готов к типичному энтерпрайзу в интеропе с C#, но голым вряд ли, да.
В-третьих, примеры использования в проде я привёл:

fsharp.org/testimonials
ИМХО, популярность микросервисов и сопутствующих технологий — это, как-раз, шанс для Scala. Не нужно убеждать всю корпорацию использовать один язык программирования. Если ваша команда верит в Scala и готова взять на себя ответственность за результат, вы можете начать с нескольких микросервисов и на практике доказать его преимущества.

И, опять ИМХО, преимущества у Scala все-же есть — языки программирования отличаются друг от друга своей мощностью. Пол Грэм, в статье «Lisp: побеждая посредственность», очень вдохновляюще раскрывает эту точку зрения.

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


Что касается мощности языка — чтобы писать круды, мощность не нужна, к сожалению.

готова взять на себя ответственность за результат

Очень часто слышу эту фразу.
Можете пояснить свою мысль, какая ответственность имеется ввиду?
В случае срыва проекта (по вине разработчиков, в данном случае, конечно же) команда разработки полным составом должна сделать харакири?
Часто владельцу бизнеса только это и остаётся в итоге, а вот вся команда просто встаёт и идёт к другому работодателю. Так что не очень понятно, что вы вкладываете в понятие этой самой ответственности.

Очень часто слышу эту фразу.
Можете пояснить свою мысль, какая ответственность имеется ввиду?
В случае срыва проекта (по вине разработчиков, в данном случае, конечно же) команда разработки полным составом должна сделать харакири?

Это значит, что сотрудник готов получать дополнительную сумму денег. В случае любого срыва любых сроков человек так же уйдет. Если управленец, то, правда, сначала, скорее всего, сведет все стрелки на подчиненных, а потом будет ныть, что он(а) весь в белом, а его предали конкретно вот эти люди.


А по факту — конечно, ничего не значит, Вы правы. Иногда еще могут согласиться на выплату части зп в виде бонуса, однако, так свои нюансы...


Все это очень грустно ...

Я бы выбрал джаву везде, потому что мне надо решение запустить, а не код писать. А на джаве полно зрелых библиотек, в отличие от

Ну если речь именно о библиотеках, то Kotlin ничем не уступает Java (все до единой библиотеки доступны)

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

Соглашусь про скорость компиляции. Ровно то же самое справедливо и для Scala, и для TypeScript. Вопрос в том, насколько будет большим прирост и насколько большой ожидается кодовая база.
Например, не так важно, занимает компиляция микросервис 20 или 30 секунд. Собственно как и неважно, занимает ли сборка 20 минут или 30 минут (и то, и другое — чудовищно много).
Что касается безопасности и поддержки, то не обладаю информацией, чтобы судить об этом. В любом случае, у Котлина есть мейнтейнер — уважаемая компания, которая должна на такого рода проблемы реагировать.

У JDK в мантейнерах RedHat (и сам IBM), VMWare, Oracle, которые на Java разрабатывают, у Котлина — одна небольшая компания, которая сама не особо много чего написала на Котлине
Например, не так важно, занимает компиляция микросервис 20 или 30 секунд. Собственно как и неважно, занимает ли сборка 20 минут или 30 минут (и то, и другое — чудовищно много).


В качестве замечания: как раз 20 или 30 секунд вполне может быть значимая разница, т.к. «не отвлечься за 20 секунд, но отвлечься за 30» — вполне возможный сценарий.

Есть некоторый порог, когда «незанятый текущей задачей мозг» переключает фокус внимания, откуда он рискует вынырнуть с вытравленным кэшем ;)
И по личным ощущениям этот порог времени в районе минуты.
в качестве генерируемого кода

А можно узнать по-подробнее? Вроде, байткод относительно идентичный для Java, кроме опциональных проверок на null.


и в любых историях, как-то связанных с информационной безопасностью

Вы про уязвимости от компилятора Kotlin, или про уязвимости JVM? Если про компилятор — а были случаи?

Нет, байткод далеко не идентичный, а сильно хуже

Про безопасность — я про средства анализа программ, про допуски котлина под аттестации/сертификации и т.д. Liberica JDK есть, а вот компилятор Котлина туда не входит
Нет, байткод далеко не идентичный, а сильно хуже

Можете, пожалуйста, перечислить конкретно, где хуже, кроме отключаемых проверок на null?


Вроде же все наоборот:


  1. В Kotlin классы/методы по-умолчанию закрыты, что позитивно влияет на JIT оптимизацию.
  2. В Kotlin легче создавать новые типы dto, что приводит к тому, что типы используются более локально, чем в Java. Как следствие, оптимизатору опять легче угадывать "hot path".
  3. Из-за синтаксического сахара, ряд рутинного кода генерится компилятором более эффективно. Например, создание строк по шаблону создается так, чтобы JIT было бы удобнее оптимизировать все это (вот пример). То есть синтаксический сахар генерит наиболее эффективный возможный код, что громадный плюс. Ну и добавим сюда inline функции/классы, которые снижают число аллокаций и пр.

я про средства анализа программ, про допуски котлина под аттестации/сертификации

А где конкретно это требуется и что это за средства? Для анализа кода есть detekt, который находит немало проблем. Veracode работает с байткодом, Kotlin официально поддерживается. Хотя я допускаю, что существуют нишевые решения, которые поддерживают малое число технологий.

Да, могу конкретно сослаться на некоторые исследования и проверки в статье. Это не мысленные эксперименты, а вполне реальный код, с вариациями medium.com/rsq-technologies/java-vs-kotlin-part-2-bytecode-42b2154f6ae0

Средства — возьмите любые, которые требуют процедуры DevSecOps для аттестация ФСТЭК, ФСБ РФ, PCI DSS. То, что какие-то инструменты появляются для Котлина, это хорошо, но для Java их намного больше, сложно с этим спорить.

Или возьмем due dilligence, раз речь идет о стартапе. Знаю компанию на слуху (и вы скорее всего их знаете), где ребят очень сильно «побрили» за то, что у них Vue (малораспространенный и рискованный выбор технологии)
Да, могу конкретно сослаться на некоторые исследования и проверки в статье. Это не мысленные эксперименты, а вполне реальный код, с вариациями medium.com/rsq-technologies/java-vs-kotlin-part-2-bytecode-42b2154f6ae0

Я прочитал статью. В ней сказано, что в некоторых алгоритмах Kotlin код создает больше объектов, в некоторых — меньше. А так же долго рассказывается, что "много лишнего байткода".


Вопрос (я не понимаю до конца): а в чем проблема того, что создается больше байткода и классов? Важна ведь производительность ПО, разве кто-то сейчас бьется за размер jar файла? В чем тайный смысл экономить на классах? И почему те люди, которым надо уменьшить байткод, не кодят напрямую в bytecode, а используют Java? Вроде, там же просто стековая машина, сложного ничего быть не должно…


Условно, в Kotlin компилятор создает методы для вызова copy у дата классов. И создает componentN методы, чтобы можно было бы делать unwrap в лябмдах. В большинстве кода эти методы никогда не будут вызваны (особенно часто такое встречается для приватных data class). Вопрос: а в чем проблема этих методов? Рядом ведь будет Spring на 30-50 Мб, в котором тоже тьма висячих методов, и народ не против особо.


Средства — возьмите любые, которые требуют процедуры DevSecOps для аттестация ФСТЭК, ФСБ РФ, PCI DSS.

Окей, я скажу коллегам из отделов под сертификацией PCI DSS, что все их сертификаты липовые и куплены в переходе. А если без шуток — напишите, пожалуйста, просто названия этих систем, которые понимают bytecode от Java, но не смогли распарсить байткод от Kotlin (при условии, что с JDK проблем нет, как мы видим)?

Окей, я скажу коллегам из отделов под сертификацией PCI DSS, что все их сертификаты липовые и куплены в переходе.


Не то, чтобы липовые…
Но сути сертификация PCI DSS фикция. Её получить несложно.
Но сути сертификация PCI DSS фикция. Её получить несложно.

И в чем тогда наезд на язык? Как я понял (уже мои догадки) — кто-то когда-то вроде бы не смог пройти PCI DSS сертификацию, и как одну из причин в компании объявили, что "виноват язык программирования К".


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

Вы передергиваете. Сначала вы просили показать, где код, сгенерированный Котлином, хуже, и я его показал. Вы заключаете далее — да ничего страшного, никого не волнует чуть больший размер кода. Если это так, зачем просить приводить примеры, если вам это изначально неважно? Ок, давайте согласимся, что это неважно, но я не спорил с тем, что это вам неважно, а с тем, что код генерируется принципиально хуже. Игнорировать или нет выбор каждого, я его не навязываю.

Сертификация систем под требования ФСТЭК, ФСБ, ЦБ, you name it анализирует не только байткод, а исходные коды системы. На Java это сделать можно, на Котлин — большой вопрос, кажется нет, то есть вопрос принципиально не проходим.

Сначала вы просили показать, где код, сгенерированный Котлином, хуже, и я его показал. Вы заключаете далее — да ничего страшного, никого не волнует чуть больший размер кода. Если это так, зачем просить приводить примеры, если вам это изначально неважно?

Я просил показать, чем сгенерированный код хуже. И он не может быть просто "хуже" (это не объективная оценка), я подумал, что Вы имеете ввиду "хуже по скорости", "хуже по памяти". После Вашей статьи я еще не до конца поверил, что размер байткода всерьез волнует людей, которые кодят на JVM языках, а не на Assembler'е.
После Вашего текущего ответа стало ясно — для части людей проблема Kotlin не в том, что скорость отличается (ибо она особо и не отличается), а в том, что размер Jar файла будет больше.


что код генерируется принципиально хуже

Еще раз все-таки правильная фраза звучит "хуже по размеру jar файла", так как по производительности просадки особо и нет, в вашей же статье. Если бы Вы сразу написали, что "jar файлы больше", то никто бы и не стал спорить.


Сертификация систем под требования ФСТЭК, ФСБ, ЦБ, you name it анализирует не только байткод, а исходные коды системы. На Java это сделать можно, на Котлин — большой вопрос, кажется нет, то есть вопрос принципиально не проходим.

Я напомню, Вы говорили — "Про безопасность — я про средства анализа программ, про допуски котлина под аттестации/сертификации и т.д.". Я потому и спрашивал — про какие конкретно программы Вы говорите. Я спрашивал их названия, так как сам программирую на известном нам языке, а потому хотелось бы знать больше возможных подстав в будущем. И вот здесь Вы не приводите ничего. Выше я привел Veracode, который используется "западными компаниями" — с ним все хорошо. Еще я нашёл Solar inCode — он, вроде, используется ФСТЭК, и с ним все тоже хорошо c осени 2018 года.

Нет, в статье не только про размер jar файла, а еще и про количество аллокаций
А что, скала уступает что-ли в этом месте? Ну то есть по скорости компиляции — возможно, а по библиотекам-то все равны.

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

Я знаю. В спарке большинство API скаловские + java, потому что иначе было бы неудобно. В HDFS скажем большинство API java — немного неудобно из scala. Ну так… в меру — можно написать обычно обертку достаточно быстро.
НЛО прилетело и опубликовало эту надпись здесь

Ну я писал на Akka, akka-streams, и т.д.
Так что я не тру фпшник :)
В принципе, впечатления были только позитивные. Нравится та самая "мощность" языка, его выразительность. Akka как платформа — тоже огонь ;)
Не очень понятно, как Докер помогает заменить или достичь похожих результатов. Основная фича — отсутствие проблем с конкурентностью и проч.
Да, хотелось бы попробовать тру фп стэк тоже, но, видимо, не судьба.

НЛО прилетело и опубликовало эту надпись здесь
Вы использовали акка кластер? Как часто ловили сплит брэйн?)

О, а можете подробнее об этом рассказать? Интерес далеко не праздный.

Да, действительно все именно так. Любая технология имеет свои недостатки. Сплит-брейн раньше (это было больше 3 лет назад) был очень большой и частой проблемой. Надеюсь, что с того времени ращработчики что-то с этим сделали. Но вообще акка-кластер не обязательно использовать. Также как и акка-персистенс. Да и вообще, как верно подмечено, для стейтлес-сеовисов это может быть немного оверкилл. По настоящему экторы нужну, где нужно хранить состояние. Но даже в этом случае есть миллион альтернативных подходов.
Я бы не назвал кривую изучения акка слишком крутой, я смог довольно без проблем въехать. Вот где действительно сложно — так это akka-streams. Вот где слом мозга протсходит. Блин, но зато какие открываются возможности.
Как говорил дядя Бен: "Чем больше сила, тем больше ответственность" :)
На самом деле я не утверждал, что я являюсь экспертом в области Scala. Скорее даже наоборот. Но тот опыт, что у меня был, не вызвал у меня отторжения, и желание продолжать углубляться не пропало (как могло бы). Более того, я наблюдал непосредственно несколько достаточно успешных проектов на Scala и akka.

Вот где действительно сложно — так это akka-streams. Вот где слом мозга протсходит.

Не сложнее Spring Reactor, RxJava и других реализаций реактивных стримов.

Ну нет, позвольте не согласиться. Я писал на RxJava до akka-streams. Знание rx не сильно помогло :(

если акка «заменяется контейнером с масштабируемостью», то в том проекте акка изначально была не нужна :)
Как часто ловили сплит брэйн?)

Есть же Split Brain Resolver'ы.

Весь Акка стэк — это сплошная боль в изучении, разработке и поддержке.

Не чувствовал боли ни в изучении, ни в разработке, ни в поддержке.
С приходом Scala 3 я надеюсь станет легче черпать разработчиков из Python комьюнити (путь Li Haoyi)

Чем Scala 3 привлечет питонистов?

Там без фигурных скобок можно будет писать. Как известно, Питонисты сразу же учат любой язык без скобок, как только он появляется.
Раунд 1: Go vs Java

Пока вы будете на Го описывать


res, err = getSome()
if err != nill {
   ...
}

Java уже будет в продакшене. Размер докера контейнера тоже по большому не играет роли, тк в Го у вас будет допустим 20Мб, а в Джава 200Мб но вы можете разбить на слои и изменяемый слой с вашим кодом будет весить пару Кб.


Для себя я выробатал стратегию — нет жестких ограничений по памяти берем Джава, а там где есть берем Раст. Го без вливания Гугла давно бы умер тк как язык он вообще не интересен.

Валидные замечания.
Правда пока люди будут писать if err != nil вы в java будете прокидывать исключения по всем слоям приложения и оборачивать в try/catch :)


А что касается размера образа, то не стоит недооценивать. Когда счёт пойдет на сотни и тысячи хостов, это все зачтется.

вы в java будете прокидывать исключения по всем слоям приложения и оборачивать в try/catch

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


request.header(HttpHeaders.AUTHORIZATION, "Bearer " + generateJWT(request))
    .retrieve()
    .bodyToMono(responseClass)
    .doOnError(WebClientResponseException.class, err -> {
        if (err.getRawStatusCode() >= 500) {
            requestMetric.mark5xx();
         } else {
            requestMetric.mark4xx();
         }
    })
    .doOnNext(resp -> requestMetric.mark2xx())

нет ни try...catch и за меня все делает Flux/Mono, которые вполне себе Монады :)


Когда счёт пойдет на сотни и тысячи хостов, это все зачтется.

  1. You Are Not Google
  2. Обычно на каждом хосте бегают десятки микросервисов, а значит и экономия будет на слоях.
  3. А если случилось так что у нас на каждом хосте по одному микросервису то разницы в цене не будет. Тк в том же амазоне вы EBS покупаете от Гб в месяц — в Орегоне 0,10 USD за ГБ-месяц выделенного хранилища.

Ну тут глупо спорить, в функциональном стиле писать на Java можно.
Я сам лично писал несколько проектов на RxJava, более сложно тестируемого кода я не видел :)
Такой код действительно можно писать и даже пытаться сопровождать, но, например, на Scala это будет более нативно имхо.
Что касается размера, то я скорее не про EBS и цену, а про время — время на сборку, время на упаковку, время на доставку и и.д.
Я работаю не в Гугле (то есть я не Гугл) но у меня сейчас размеры всего такие, что сборка, регрессия, деплой и прочее занимают часы. Так что да, тут в какой-то момент могут пригодиться и меньшее время компиляции, и меньшее время скачивания контейнеров на холодном CI-агенте, и так далее.

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

А что не так с этим кодом? По моему мнению разницы сопровождать и тестировать код который User getById(String id) vs Mono<User> getById(String id) разницы нет.


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

Значит у вас огромный проект и в Го у вас абстракции и структуры утекут и получится такая каша, что время компиляции будет цветочками :)


и меньшее время скачивания контейнеров на холодном CI-агенте

это какой кто граничный случай, что я бы не расматривал его. Только еще учтите что в Джаве вы взяли мавен и у вас все проекты практически одинаковые по layout и как собираются. Плюс плагинами вы можете много разного делать и это будет работать одинаково как в Дженкинсе так и у разработчиков под разными ОС. А в Го вы будете писать свой велосипед потому что там либо go build но такое катит для элементарных проектов либо портянки на make который под линуксом все ок, а под Виндовс начинаются пляски либо берете Bazel и мудохаетесь с ним. А в это время джава версия уже захватывает рынки.

Значит у вас огромный проект и в Го у вас абстракции и структуры утекут и получится такая каша, что время компиляции будет цветочками :)

Ну вообще-то совсем не значит. Абстракции могут утечь на любом языке, и на Джаве в частности.


это какой кто граничный случай, что я бы не расматривал его

Ну это конкретная проблема, которую я вижу ежедневно, когда 200+ разработчиков коммитят в мастер и запускают свои билды на 300+ ci-агентах (и это все ещё не Гугл).


Если у вас проект, который пишут 1,5 человека, то в принципе не так важно, на чем они пишут и с помощью каких инструментов. Важно сделать так, чтобы когда система начнет расти, ее можно было легко смасштабировать: не только прод инфраструктуру, но и CI, средства разработки, деплоймента и т.д.

Абстракции могут утечь на любом языке, и на Джаве в частности.

Могут и будут разные вещи. Простой пример в Джаве вы сделали класс с приватным конструктором, private final полями и билдером и можете быть уверены что никто по другому его не будет использовать. В Го вы это просто не сможете реализовать (одна структура в пакете не рассматриваем тк это вообще не жизнеспособный вариант).


Ну это конкретная проблема, которую я вижу ежедневно, когда 200+ разработчиков коммитят в мастер и запускают свои билды на 300+ ci-агентах

Во-первых, мне очень жаль что вам приходится мучаться на моно репе :)
Во-вторых, откуда тогда взялась большая проблема холодных ci-agent'ов в таком сценарии.


Важно сделать так, чтобы когда система начнет расти, ее можно было легко смасштабировать

не понимаю как это связано с Го или Джавой

Ну кмк Го покрывает большинство кейсов приватными и публичными структурами и функциями. Да, наверное, не так полно, как это в Джаве. Но, честно говоря, я 6икогда не понимал всех этих огораживания, когда код библиотеки пишут так, что ты его не можешь расширить. С моей точки зрения это скорее минус.


Тут вопрос ее в монорепе, а в желании тестировать каждый коммит. При большом потоке изменений в любом случае так происходит. Холодные агенты появляются изрза автоскейлинга — нагрузка на CI неравномерна, агенты запускаются и умирают. Запускаются, к сожалению, в данный момент холодными. Это все решаемо, но все требует усилий, которые могли бы быть меньше при меньшем времени сборки, меньшем размере артефактов и т.д.


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

Ну кмк Го покрывает большинство кейсов приватными и публичными структурами и функциями. Да, наверное, не так полно, как это в Джаве.

В Джаве у меня самые ходовые это public и private. В Го у меня нет private а максимум package и это значит я не могу ограничить доступ к ней. А значит у вас уже утекает информация наружу. И вы не можете гарантировать, что использовать будут как надо ваш код, а не как кому голову взбредет.


Го не гарантирует вам обработку ошибок, это уже мы обсуждали в другой статье. Так же Го не дает вам ни ООП ни функционального программирования ни какого другого подхода. В большом и сложном проекте у вас обязательно будут лезть со всех стороно interface{} и никакой гарантии на этапе компиляции вы не получите. А только в рантайме прилетят проблемы.


С производительности в Го тоже не все хорошо. И с памятью есть проблемы


Я уже как то предлагал спор — вы пишите на Го а я на Джаве. А потом сравниваем затраченное время, производительность и архитектуру в целом. Почему не согласились :)))


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

Расширить и залезть в кишки это разные вещи.


Тут вопрос ее в монорепе, а в желании тестировать каждый коммит.

это именно монорепо — потому что у нас в компании сотни микросервисов и протестировать и собрать каждый из них дело быстрое. А когда у вас монорепо то вам на каждый чих надо на холодном агенте выкачивать весь репозиторий и все зависимости.

В Го у меня нет private а максимум package и это значит я не могу ограничить доступ к ней. А значит у вас уже утекает информация наружу.


1) В чем проблема сделать sub-package?
2) В чем проблема в пределах одного пакета, когда вы еще можете охватить одним мысленным взглядом, вести себя с переменными корректно?
В чем проблема сделать sub-package

И так на каждую структуру? Я не хочу чтобы были видны кишки и доступ к ним кого либо кроме этого класса/структуры.


В чем проблема в пределах одного пакета, когда вы еще можете охватить одним мысленным взглядом, вести себя с переменными корректно?

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

Даже банальный автокомплит IDE мне в джаве будет показывать публичные поля, методы а не всю партянку и дальше сиди разбирайся можно этим пользоваться или это что то внутреннее.


Go же язык со строгой типизацией.
IDE показывает именно те методы, что имеют отношение к конкретной структуре.

Это с каким нибудь Python или JavaScript можно получить портянку.

сиди разбирайся можно этим пользоваться или это что то внутреннее.


Публичные методы в Go прекрасно видны.
Публичность требует написания идентификатора с заглавной буквы (прописной). Если идентификатор написан со строчной буквы — это приватный объект.

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

Если всё же остаются слишком объемные мешающие портянки, то выносим их в sub-package.

Или можно обращаться к ним не через структуру (struct), а через interface, в котором изначально нет ничего лишнего.

P.S.:
Довольно старанно требовать от одного языка ровно всех тех же особенностей, что есть в другом языке.

А зачем тогда вообще создавать другой язык, если он будет позволять делать всё ровно то же самое?
Go же язык со строгой типизацией.
расскажите это когда куда не плюнь interface{} а дальше кастуй :)))

IDE показывает именно те методы, что имеют отношение к конкретной структуре.

В Джаве у меня есть класс А у него есть публичные и приватные поля и методы. Когда я нахожусь в другом классе Б даже если они в одном пакадже то я все равно не увижу приватных полей и методов в авто комплите. В Го вы их не увидете только если класс Б в другом пакадже, а если пакадж тот-же то вся структура открыта для вас.

Go же язык со строгой типизацией.

расскажите это когда куда не плюнь interface{} а дальше кастуй :)))


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

Видимо, вы не поняли.
Я то писал про конкретизированный interface, а не про универсальный interface{}. Это разные вещи.

Когда я нахожусь в другом классе Б даже если они в одном пакадже то я все равно не увижу приватных полей и методов в авто комплите. В Го вы их не увидете только если класс Б в другом пакадже, а если пакадж тот-же то вся структура открыта для вас.


Спасибо, кэп.

Повторю еще раз:

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

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


То, что есть нечто называемое «пакет» и в Go и в Java вовсе не означает что эти понятия совершенно равны во всём.

Для Go package имеет отношение к области видимости, да.
Если вам нужно действительно ограничить видимость — просто делаете sub-package.

Другой вариант:
Обращаетесь к объекту-переменной не как к структуре, а через конкретизированный интерфейс.

Кстати, интерфейсы Go позволяет создавать не только публичные, но и локальные. Что позволяет ввести и третье понятие, нечто вроде protected в дополнение к private и public.

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


К сожалению, мне довольно часто приходилось сталкиваться с низкокачественными библиотеками на Джаве, в которых невозможно вообще ничего расширить как раз из-за паранойи разработчика :)


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


Что касается спора, учитывая мой бэкграцнд, я бы скорее сам предпочел писать на джаве, а уж никак не на Го :)))

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

Нет, сокрытие на уровне пакаджа что не тоже самое что на уровне класса. И много вы видели в Го проектов в которых каждая страктура в своем классе? Я вот не видел.


в которых невозможно вообще ничего расширить как раз из-за паранойи разработчика

Если вы хотите во внутрь библиотеки то fork и вперед. Вы уже своим желанием показываете что текущаа имплементация вам не подходит и вы готовы сломать совместимость, используя внутрености.


Как только вы захотите делать полное интеграционное тестирование всех микросервисов на регулярной основе

Я не знаю зачем мне это надо. Меня не интересуют внутрености остальных микросервисов так же как и их внутрености моего. Главное соблюдение публичного контракта. И больше нет проблем. А когда надо менять контракт то проще добавить новый ендпоинт и создать ишью на другие команды по миграции. И жить себе дальше а не пытаться заставить в монорепе чтобы остальные команды все бросили и пошли в вашей ветке фиксить использование вашего ендпоинта.


Те вроде как у вас микросервисы а на самом деле респределенный монолит, в котором сменить ждк 8 на ждк 11 нереально тк надо чтобы вся кодовая база поменялась.


Что касается спора, учитывая мой бэкграцнд, я бы скорее сам предпочел писать на джаве, а уж никак не на Го

И вот чего мы тогда тут спорим :)))))

Как только вы захотите делать полное интеграционное тестирование всех микросервисов на регулярной основе


Я не знаю зачем мне это надо. Меня не интересуют внутрености остальных микросервисов так же как и их внутрености моего. Главное соблюдение публичного контракта. И больше нет проблем.


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

А вот вам и запущенный случай:

Конкретно наш текущий проект отдаёт и принимает данные по чужим (внешним) API. И это не какие-то вторичные API, а именно то, за ради чего весь проект создавался.

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

Ситуация, когда речь идет о внутренних сервисах с хорошо описанными контрактами — просто мечта.
Ситуация, где, в случае выяснения косяка по контрактам легко настучать (через вышестоящее руководство) по голове коллеге, чтобы он поправил — ситуация мечта.

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

Так что интеграционные тесты — это наше всё.

На их фоне наше внутреннее тестирование — это маловажный детский лепет, это всё проходит легко и быстро.

Конкретно наш текущий проект отдаёт и принимает данные по чужим (внешним) API. И это не какие-то вторичные API, а именно то, за ради чего весь проект создавался.

а как это поможет когда у вас монорепо или нет? Если у вас проблема с одинм конкретным сервисом.


У вас один сервис принимает данные и дальше должен их конвертить во внутренний правильный формат и уже ими должны пользоваться остальные внутренние микросервисы. И тестировать вам надо только вот этот наружу смотрящий севрис. Это как я вижу.


У нас сотни микросервисов с 1-10К RPS на каждом. И мне не разу не сломали внешний (который на самом деле внутренний но для других микросервисов он внешний) контракт так же как и я другим. СЕрвисы которыми я заведую ходят в различные внешние системы, например Zoom и другим нашим сервисам абсолютно все равно что я там с тем Зумом делаю. Главное чтобы я им отдавал нормальные данные которые соответсвуют опять же публичному контракту.

У вас один сервис принимает данные и дальше должен их конвертить во внутренний правильный формат и уже ими должны пользоваться остальные внутренние микросервисы. И тестировать вам надо только вот этот наружу смотрящий севрис. Это как я вижу.


Так вот отладка именно внешней части и занимает львиную часть времени. По причине того, что публичные контракты не всегда исчерпывающе описаны.

С внутренними сервисами проблем нет. Но в том то и дело, что тестирование внутренних сервисов маловажно. Ибо оно осуществляется легко и на раз-два-готово.

Без интеграционных тестов никуда. Даже в куда как более простых случаев чем наш, интеграционные тесты вскрывают кучу сюрпризов.

Но, я замечаю, что разработчики зачастую уделяют внимание только локальным тестам (видимо, потому что их делать намного проще, и можно получить отмазку «а у меня всё работает»), а там где пересекается ответственность — трудоёмкость тестирования возрастает, именно там нас и поджидает куча сюрпризов. Но почему то интеграционные тесты делают «на отвяжись, у меня контракт соблюден, моком-имитатором все проверил, а дальше хоть трава не рости»
Так вот отладка именно внешней части и занимает львиную часть времени. По причине того, что публичные контракты не всегда исчерпывающе описаны.

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


Но почему то интеграционные тесты делают «на отвяжись, у меня контракт соблюден, моком-имитатором все проверил, а дальше хоть трава не рости»

Если вы про то, что разработчик сервиса А не тестирует сервис Б, а берет делает моки для Б и тестирует А. То не зная всех деталей можно сказать что он прав. Тк это ответсвеность сервиса Б тестировать свой публичный контракт и работоспосоюность. И сервис А должен лишь тестировать свое поведение если что то пошло не так.

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


Моно репа или мульти репа никак ничего не гарантирует, но и не мешает (при правильно поставленном процессе разработки).

Примеры гигантских монореп в MS и в Google, где далеко не самые глупые разработчики, — это показывает.
Если вы про то, что разработчик сервиса А не тестирует сервис Б, а берет делает моки для Б и тестирует А. То не зная всех деталей можно сказать что он прав. Тк это ответсвеность сервиса Б тестировать свой публичный контракт и работоспосоюность. И сервис А должен лишь тестировать свое поведение если что то пошло не так.


Вот вот, и вы туда же.

Я про то, что выполнив изолированное тестирование вы только получаете отмазку, что «у меня всё работает».

В реальной эксплуатации возникает много очень необычных нюансов.

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

И это только один пример.
Моно репа или мульти репа никак ничего не гарантирует, но и не мешает (при правильно поставленном процессе разработки).

Отлично мешает. Я жил с моно репо и сейчас мульти — и я счастлив, что я ни от кого не завишу в своем маленьком мирке микросервиса. А не так что хочешь ЖДК11 но фиг тебе, потому пока все не переедут не будет ЖДК 11, а для этого надо синхронизировать все команды. Что практически нереально.


Примеры гигантских монореп в MS и в Google, где далеко не самые глупые разработчики, — это показывает.

Я работал как то в проекте по интеграции MS Teams в наш продукт. Они может и умные, но то что делается за пару часов, с ними тратились недели.


Я про то, что выполнив изолированное тестирование вы только получаете отмазку, что «у меня всё работает».

Так что мешает в моке эмулировать ошибки данных или таймауты? Потому при интеграционном тестировани вам развернуть все микросервисы и для конкретного use case сделать задержу а для других нет будет стоит больших усилий.


и отлично протестированная изолированными тестами система не может работать.

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

Моно репа или мульти репа никак ничего не гарантирует, но и не мешает (при правильно поставленном процессе разработки).


Отлично мешает. Я жил с моно репо и сейчас мульти — и я счастлив, что я ни от кого не завишу в своем маленьком мирке микросервиса. А не так что хочешь ЖДК11 но фиг тебе, потому пока все не переедут не будет ЖДК 11, а для этого надо синхронизировать все команды. Что практически нереально.


Монорепа и компиляция в монолит — это разные понятия.

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

Я про то, что выполнив изолированное тестирование вы только получаете отмазку, что «у меня всё работает».

Так что мешает в моке эмулировать ошибки данных или таймауты?


Если бы программисты могли бы предвидеть абсолютно все ситуации на этапе отладки — программы давно были бы без единой ошибки.

Что, как мы знаем, не так.

Ну например по поводу предлагаемого вами решения по имитации в моке сетевых задержек:

Вам известен только ваш ближайший в цепочке микросервис. То что он по цепочке вызываете еще 2 штуки других микросервисов вам попросту неизвестно.

То есть вам нужно имитировать ситуацию при двух неизвестных. Что вы тут можете имитировать? Насколько это будет полноценная имитация? Разве что только полный фатальный сбой имитировать, но это совсем не то.

НЛО прилетело и опубликовало эту надпись здесь
Могут и будут разные вещи. Простой пример в Джаве вы сделали класс с приватным конструктором, private final полями и билдером и можете быть уверены что никто по другому его не будет использовать.

Хаха рефлексия goes brrrrr

Хаха рефлексия goes brrrrr

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


Так же никто не отменял SecurityManager если стоит проблема очень остро.


И если не в курсе то джава 9+ позволит сделать такие ограничения по рефлексии на уровне модулей.


Так что не хахаха

А что не так с этим кодом?

С этим кодом все хорошо, плохо может быть, когда придется что-то более сложное сделать.
Я писал на rx-java модуль, не сильно сложный. Но покрыть его внятно тестами не получилось.
Пришлось по сути взять и переписать так, чтобы каждый небольшой кусок обработки в стриме можно было протестировать независимо. В общем, несмотря на крутость решения вышло так, что пришлось потратить гораздо больше времени, и решение получилось довольно хрупким. Хотя, наверное, это вопрос практики.
Но у меня такой личный опыт

Хотя, наверное, это вопрос практики.

Это 100% так. Если в лоб императивно писать реактивщину, то да выходит ужасно. Поэтому надо изначально писать как поток данных, с разбиением по слоям и разным классам и тогда никаких проблем нет. Это как и Джава stream можно ужас наворотить, а можно сделать красивое понятное решение.

Ну никто не говорил про "писать в лоб императивщину" :)

Scala, похоже, в Data Science

Не встречал, если честно, ни одной конторы где бы DS пилили на Scala, это довольно убого, по сравнению с Python.


На Scala я писал, и много. Но я ее забросил, найти контору которая ее правильно использует невозможно. Правильно это со scalaz, без него Scala так себе, лучше уж на C# писать.

НЛО прилетело и опубликовало эту надпись здесь
Смотря какой data science. Какие-нибудь терабайты логов парсить на скале со спарком явно удобнее, чем питоном.

Если не ошибаюсь на спарке сейчас тянут одеяло в сторону sparkQL(да это ДСЛ на скале), а для этого вся мощь скалы не нужна, от силы 10 процентов. На спарке вроде и на питонах и на джаве пилить можно, глядишь так скоро и в скале нужда отпадет.

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

Если мы говорим именно о замене для Скалы, то шарп лучше. Меня в своё время интересовал этот вопрос, и я его исследовал. Рекомендую к прочтению вот этот цикл статей: https://medium.com/@alexyakunin/go-vs-c-part-1-goroutines-vs-async-await-ac909c651c11

Ну я как-то с трудом могу представить людей, переходящих со Скалы на C# :)
Я бы еще понял F# (если он жив еще).
Возможно, я немного застрял в прошлом, но .Net платформа всегда была догоняющей по отношению к JVM с точки зрения почти всего: производительности, сборки мусора, наличия библиотек и т.д. Будет хорошо, если это изменилось уже и .Net стал более развитым. И да, он может быть теоретически лучше, чем Го, но репутация, которая накопилась за годы того, как Микрософт развивал свою платформу, вряд ли позволит мне смотреть на нее непредвзято :)

Всё изменилось 4 года назад с выходом кроссплатформенного .NET Core.

Возможно, я немного застрял в прошлом, но .Net платформа всегда была догоняющей по отношению к JVM

Это уже давно не так, посмотрите фичи C# 9 и Java, и прослезитесь :). Type Ereasure в 2020 это позор, скала кстати попыталась решить эту проблему. Правильно говорят с .NET Core все изменилось. Compiler as service, java, ау. итд итп

Это уже давно не так, посмотрите фичи C# 9 и Java, и прослезитесь :)

Вы путаете платформу и языки. C# однозначно современнее Java, но платформа, увы, далеко позади
Хотелось бы более подробного раскрытия этой темы.
В первую очередь, кол-во библиотек (опенсорсных в том числе), размер комьюнити, охват платформ и железа где запускается Java. Во-вторую, как уже выше сказали внутреннее устройств виртуальных машин, но тут тема скользкая и холиварная. Поэтому я больше про первое.
Под словом платформа обычно подразумевают технологическую платформу, в случае C# это CLR.

Охват железа у .NET Core не меньше: github.com/dotnet/runtime/blob/master/src/libraries/pkg/Microsoft.NETCore.Platforms/runtime.json

Размер коммьюнити и библиотек это переменная величина, зависящая от качества языка и платформы. Учитывая, что мультиплатформенный .NET Core появился только 4 года назад, коммьюнити будет расти, как и количество библиотек. Стоит отметить, что большой размер экосистемы с длинной историей имеет и свои недостатки, что Java отлично иллюстрирует.

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

Мда, больше вопросов нет.
В первую очередь, кол-во библиотек (опенсорсных в том числе), размер комьюнити, охват платформ и железа где запускается Java.


Java существует еще с прошлого века.
И обещали её «в каждой кофеварке».
Как показала история — охват платформ ничего не гарантирует.

Ибо на сегодня количество языков мейнстрима даже больше, чем во времена рождения Java.

Другие, кроме Java, тоже никуда не исчезли. Ну разве что присутствие Перла стремительно сократилось.

Больше никого Ява не вытеснила.

Ничего я не путаю, Type Erasure это заноза платформенная, а не языковая. В 2005 когда крософт разобрался с Type Erasure, то они тогда рапортовали о 40% приросте в производительности. Это было тогда. Сейчас CLR медленнее не стал, скорее наоборот.

Я не знаю что вы такое пишите, но вангую, что микросервисы, задача которых — это сделать rest-frontend для базы данных. С этой точки зрения абсолютно пофигу что использовать — сегодня все умеют Rest и SQL, и сравнивать на чем лучше мепить просто бессмысленно.


Там, где задача реально посложнее стоит, вам будут необходимы не столько возможности самого языка сколько то, что предоставляет экосистема. С этой точки зрения Java не переплюнуть. Основная проблема Scala и Kotlin в том, что они переиспользуют экосистему Java но интеграция далеко не бесшовная. В Scala попытались создать свою экосистему с блэкджеком, которая, однако, не имела особенного успеха. Лишь некоторые проекты заняли свои ниши, сделав тем самым скалу нишевым языком. Kotlin, несмотря на хайп и более гладкой интеграции с Java, также по большей части является нишевым для андроида.


P.S. А еще Scala страшный и тяжелый

P.S. А еще Scala страшный и тяжелый

То верно, но скала 3 обещала быть легкой и красивой(Discriminated Union, прекрасны в любое время года). Вот ждемс, когда же запилят.

Kotlin, несмотря на хайп и более гладкой интеграции с Java, также по большей части является нишевым для андроида.

Сильно сказано. Именно поэтому Spring имеет тесную интеграцию с Kotlin, даже поддерживает coroutines. И именно поэтому, наверное, в Gradle (эта билд система используется в Spring, Spring Boot и еще в куче проектов) Kotlin добавили, так как он нишевой.


А в итоге:


  • В Android основным языком является Kotlin
  • В громадном числе Enterprise библиотек Kotlin используется или как второй официально поддерживаемый, наряду с Java (пример — Spring и компания), или же он вообще используется как основной язык (пример — okhttp)
  • В самой шустрой и быстроразвивающейся системе сборки из более-менее популярных Kotlin является вторым языком, наравне с Groovy (Java там даже не предлагают), причем на Kotlin DSL активно переводят проекты.

Неплохое нишевое решение.

Гы, я ждал этого коментария :)
Ничего не имею против самого языка Котлина, но давайте будем объективными. Котлин разрабатывается уже лет 8, но основной всплеск интереса получил именно, когда Google анонсировал его как основным для андорида. До этого он еле входил в 50-ку. А открыв простую статистику github можно увидеть на чем разрабатывают люди. Плюс вычтите отсюда львиный процент разработки под андроид, и оцените на чем все-таки реально пишут под JVM. Даже Scala тут обходит.


В громадном числе Enterprise библиотек Kotlin используется или как второй официально поддерживаемый, наряду с Java (пример — Spring и компания)2

В каком громадном? Spring вообще технологическая помойка, которая стремиться всосать в себя всю экосистему. Поэтому было бы странно, если бы он не поддерживал Kotlin, но поддерживал какой-то Groovy. С другой стороны, идея разработчиков языка заключалась именно в переиспользовании экосистемы Java без всякой специальной поддержки. Но здесь не обошлось без костылей типа allopen.


Своя же чисто котлинская экосистема еще меньше, чем у скалки, львиную долю которой занимает то, что пилят в самом JetBrains.


В самой шустрой и быстроразвивающейся системе сборки

Это самая отстойная и тормозная система сборки с ядром на Groovy (но тем не менее полезная за отсутствием чего-то лучшего). Опять же популяризировалась засчет андроида. В 80% случаев все-равно Maven.


Чисто мое субъективное ощущение, когда я писал на котлине: нафига извращаться, если то же самое можно сделать на Java, не многим сильно приседая. Была нужда в fullstack проекте налабать фронт и бэк на котлине, но по ходу эта технология еще очень далека от массового использования. Проще взать какой-нибудь Vaadin или (прости хоспади, GWT).

Котлин разрабатывается уже лет 8, но основной всплеск интереса получил именно, когда Google анонсировал его как основным для андорида.

И что? Мне казалось, что так всегда бывает — технология медленно развивается между всплесками, которые иногда ассоциируются с признаниями. Про Java говорили аналогичные вещи лет 10 назад — "мало кому нужная Enterprise технология, жрущая кучу памяти, которая бы ушла бы в забвение, если бы не Android". Не могу согласиться с этой фразой, однако, она мне кажется достаточно похожей на аналогичную про Kotlin.


Своя же чисто котлинская экосистема еще меньше, чем у скалки, львиную долю которой занимает то, что пилят в самом JetBrains.

Я тут так скажу — с моей точки зрения, её и быть не должно. Есть экосистема JVM — это разные сборщики проектов (Ant/Maven/Gradle), это система распространения артефактов и пр. А потому все корректно — Kotlin встраивается в текущую, а не делает свой велосипед рядом.


нафига извращаться, если то же самое можно сделать на Java, не многим сильно приседая.

Ну во-первых — приведите пример, пожалуйста, вынужденного извращения на Kotlin.
Во-вторых, Kotlin, Java, PHP, Bash, Brainfuck и еще куча других языков являются тьюринг-полными. То есть программа, написанная на одном, сводится к программе, написанной на другом. А потому фраза "то же самое можно сделать на Java" аналогична "то же самое можно сделать на сыром bytecode".
В-третьих, на языках K&S определенный класс задач решается проще. Например, если Вам надо ограничить наследование (я знаю, что в Java есть visitor, но ведь не всегда хочется писать много кода для такой простой вещи?). Или если надо написать неблокирующий код (вот как на Java он будет проще?). Но, что важно: не все задачи решаются легче, что также необходимо осознавать.


Это самая отстойная и тормозная система сборки

Вот сравнение скорости сборки. А тут можно глянуть gif, чтобы визуально сравнить. А мифы плодить не надо, пожалуйста.


с ядром на Groovy

И как бы в подтверждении Вашим словам, есть gMaven.


Опять же популяризировалась засчет андроида. В 80% случаев все-равно Maven.

Я напомню — проекты Spring & Spring Boot перешли с Maven на Gradle. И вот это — действительно показатель качества, а не 80% каких-то невидимых Enterprise проектов. Будто я по себе не знаю, кто работает в Enterprise.

Есть экосистема JVM — это разные сборщики проектов (Ant/Maven/Gradle), это система распространения артефактов и пр.

Экосистема — это во-первых, сторонние библиотеки и фреймворки. Многие из них сильно заточены под джаву, а не котлин. Поэтому интеграция всегда идет с дополнительными приседаниями.


Ну во-первых — приведите пример, пожалуйста, вынужденного извращения на Kotlin.

Вот только то, что следует помнить, просто микшируя код на котлине с джавой:
https://kotlinlang.org/docs/reference/java-interop.html
А вообще повсюду: интроспекция (reflection), annotation processing, проблема allopen, SAM & lambda conversions, проблема перекрытия ключевых слов (is/as, привет Mockito), static-и, не совпадает бинарно структура класса (здравствуй ASM/Javassist/ByteBuddy), не котлиновские коллекции в джаве — множество их. Не говорю, что они не решаемые, но это лишние накладки, которых можно избежать.


А потому фраза "то же самое можно сделать на Java"

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


Например, если Вам надо ограничить наследование (я знаю, что в Java есть visitor, но ведь не всегда хочется писать много кода для такой простой вещи?).

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


Вот сравнение скорости сборки.

Блин, не стоит тупо вестись на рекламу! Maven в отличие от Gradle по умолчанию не использует parallel builds, но их можно включить либо в самом pom.xml, либо опцией -T. Собственно и все, что нужно знать об этом "тесте", опубликованном на странице градла. К тому же на гифке не видно надписи "Starting gradle daemon...", что говорит о том, что билд уже не первый, и демон уже загружен и прогрет.

Экосистема — это во-первых, сторонние библиотеки и фреймворки. Многие из них сильно заточены под джаву, а не котлин
Это заблуждение. Библиотеки, заточенные под котлин — да, лучше работают на котлин. Остальные — так же, как на Java. За очень редким исключением, ведь язык создавался именно под такой кейс использования.
на джаве не сильно больше букав писать приходится, особенно с поддеркой IDE.
Сильно больше букав. Никакая IDE вас не спасёт от чтения килотонн boilerplate и не завезёт в язык перегрузку операторов и прочие полезные вещи.
Сильно больше букав. Никакая IDE вас не спасёт от чтения килотонн boilerplate и не завезёт в язык перегрузку операторов и прочие полезные вещи.

Я не заметил особого boilerplate, кроме пропертей. Но это легко решает Lombok. Также как и для большинства вещей из Kotlin stdlib в джаве решается сторонними библиотеками. А лишнюю скобку поставить или указать тип — это не проблема с хорошей IDE. По моим наблюдениям на котлине код компактнее лишь на 20%, за исключением некоторых специфичных кейсов, где требуется DSL или перегрузка. Тут котлин рулит.

Блин, не стоит тупо вестись на рекламу! Maven в отличие от Gradle по умолчанию не использует parallel builds, но их можно включить либо в самом pom.xml, либо опцией -T. Собственно и все, что нужно знать об этом "тесте", опубликованном на странице градла. К тому же на гифке не видно надписи "Starting gradle daemon...", что говорит о том, что билд уже не первый, и демон уже загружен и прогрет.

Тут тонкий момент. Локально у меня демон запущен, так что не вижу плюсов Maven в том, что надо каждый раз прогревать Java. К тому же, если говорить про холодные старты проектов из github, по моим ощущениям (тут уже видна необъективность), Gradle собирается оперативно из-за параллельного скачивания файлов и прочих оптимизаций.
Если говорить о серьезных проектах, то Maven там аналогичен PHP в мире Web'а — очень легко начать, но для ряда вещей надо написать кучу повторяющегося кода. Например, если у вас куча модулей, причем часть из которых на Java, а часть из которых публикуется в Maven (то есть по сути есть четыре группы проектов), то в Maven довольно сложно без копи-паста и без самописных плагинов выделить общий блок логики, а потом в как бы шахматном порядке её применять. А схеме с кешей Maven можно вообще можно посвятить главу в книге про паттерны проектирования с идеей "а вот так делать не надо". Но это лично мои заметки, и моя аналогия, не более. Как я уже сказал, если активноразвивающиеся проекты с большой кодовой базой уходят с Maven на Gradle, то это уже серьезный довод.


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

Если в проекте есть такой налог на зависимости, то там не до качества, конечно. Я понимаю подобное в npm, ибо каждая зависимость увеличивает размер bundle, что важно для web'а.
По моим заметкам, с Kotlin резко сокращается объем кодовой базы — буквально в разы. И увеличивается емкость логики на строчку кода. Как результат:


  • Если на Kotlin код занимает 400 строк (что близко к критичному), то на Java он будет около 1000 строк, что пробьет все барьеры читаемости. А разделив класс на 2-3 (плюс несколько файлов под интерфейсы и общие dto) мы получим просто дикую кучу кода, хотя описывающую все ту же логику, что и изначальные 400 строк на Kotlin.
  • На том же ревью не надо смотреть кучу генеренного лишнего кода, так что нет отвлекающего момента.
  • Как я уже писал, в проектах реже надо изобретать велосипеды, так как более емкий язык и стандартная библиотека большего объема дают возможность просто переиспользовать функции.

К тому же джава не стоит на месте, и скоро там появятся файберы, которые по-моему мнению, более органичны, чем корутины.

Это будет круто, когда они появятся. Сам очень надеюсь их увидеть в 17й Java. Однако, в своих проектах у нас уже сейчас неблокирующий код. И уже сейчас не надо писать CompletableFuture с callback hell, уже сейчас можно писать читаемый асинхронный код. И более того — он давно уже работает в проде.
А с приходом Java 17 необходимо будет просто массово удалить слово suspend из кодовой базы и поправить 3.5 ошибки компиляции. Тогда как проекту на Java надо будет удалять свои onError и пр.

Если на Kotlin код занимает 400 строк (что близко к критичному), то на Java он будет около 1000 строк

Можете показать пример?

У меня все-таки проект с закрытым исходным кодом, потому не могу.


Но давайте остановимся на этом файле — https://github.com/Kotlin/kotlin-script-examples/blob/master/jvm/simple-main-kts/simple-main-kts/src/main/kotlin/org/jetbrains/kotlin/script/examples/simpleMainKts/scriptDef.kt


В нем 169 строк. Где будут добавляться лишние строки на Java:


  1. При вызове public методов надо проверить параметры на null
  2. Здесь синглтон, так что в Java будут еще лишние поля и пр.
  3. Этот метод в Java будет довольно жирным, его надо будет разбить. Для понимания — когда пишут xxx { yyy() }, код преобразуется в xxx({ it -> yyy() }), то есть это означает, что на вход передали функцию.
  4. В строках отсюда для Java надо будет написать лишнего кода с stream(), плюс надо или сделать несколько if'ов, или использовать Optional с дополнительной памятью.
  5. А вот такие однострочники в Java пока невозможны, плюс тут используется библиотека из Kotlin, так что для Java надо Apache Common залинковать будет.

Главное:


  1. Код будет разбухать
  2. Чтобы функции не разрастались, надо будет создавать отдельные методы, в которые передавать параметры и пр., что увеличит еще размер класса.
  3. В итоге файл разбухнет настолько, что его надо будет подробить, так что логика будет размазана по нескольким файлам.
При вызове public методов надо проверить параметры на null

Lombok @NonNull


Здесь синглтон, так что в Java будут еще лишние поля и пр.

Может и круто, но я не помню когда я руками создавал синглетон. У меня как то ДИ и там повесил @Singleton и нет проблем. Не думаешь потом как статику выковырять.


Этот метод в Java будет довольно жирным, его надо будет разбить.

Этот пункт не понял. Как по вашему это будет в Джаве?


В строках отсюда для Java надо будет написать лишнего кода с stream()

Вот такое мне читать очень тяжело


val importedSources = annotations.flatMap {
            (it as? Import)?.paths?.map { sourceName ->
                FileScriptSource(scriptBaseDir?.resolve(sourceName) ?: File(sourceName))
            } ?: emptyList()
        }

или такое


hostConfiguration(ScriptingHostConfiguration {
            jvm {
                val cacheExtSetting = System.getProperty(COMPILED_SCRIPTS_CACHE_DIR_PROPERTY)
                    ?: System.getenv(COMPILED_SCRIPTS_CACHE_DIR_ENV_VAR)
                val cacheBaseDir = when {
                    cacheExtSetting == null -> System.getProperty("java.io.tmpdir")
                        ?.let(::File)?.takeIf { it.exists() && it.isDirectory }
                        ?.let { File(it, "main.kts.compiled.cache").apply { mkdir() } }
                    cacheExtSetting.isBlank() -> null
                    else -> File(cacheExtSetting)
                }?.takeIf { it.exists() && it.isDirectory }
                if (cacheBaseDir != null)
                    compilationCache(
                        CompiledScriptJarsCache { script, scriptCompilationConfiguration ->
                            File(cacheBaseDir, compiledScriptUniqueName(script, scriptCompilationConfiguration) + ".jar")
                        }
                    )
            }
        })

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


Flux.just(userUid)
                .flatMap(repository::getByUser)
                .collectList()
                .filter(not(List::isEmpty))
                .doOnNext(items -> cache.save(items).subscribe())
                .flatMapIterable(counters -> counters);

А вот такие однострочники в Java пока невозможны

Будет две строчки. Это настолько критично?


Вы же поймите что я тоже могу привести примеры где я сделаю на джаве в пару строчек а вы в Котлине будете простыню писать. Напримеру вас есть 20 пропертей в классе и надо одно из них убрать из вывода toString?
Помните мы уже с вами это обсуждали.
Вот как в Джаве это


@Value
@ToString(exclude = "creditCard")
public class CounterItem {
  String creditCard;
  ... и остальные 19 полей.
}

или вот такое


internal fun URL.toFileOrNull() =
    try {
        File(toURI())
    } catch (e: IllegalArgumentException) {
        null
    } catch (e: java.net.URISyntaxException) {
        null
    } ?: run {
        if (protocol != "file") null
        else File(file)
    }

взяв Vavr я напишу в одну строчку.


Поэтому все что у вас в Главное: это очень субьективно

Lombok @NonNull

Понимаете, это не Java. Просто байткод теперь генерируется не Kotlin Compiler, а Lombok Compiler. По сути, Вы явно сказали, что работа компилятора Java Вас не устраивает, о чем я и говорю.


Аналогично, если бы Вы захотели часть классов писать в Scala.


Может и круто, но я не помню когда я руками создавал синглетон. У меня как то ДИ и там повесил Singleton и нет проблем. Не думаешь потом как статику выковырять.

Эта библиотека не содержит зависимостей ни на что, кроме компилятора Kotlin. Если бы мы говорили про Enterprise приложение, то там, конечно, все будет упаковано в DI. А тут Вам опять не хватило выразительности языка, о чем я и говорю.


И DI не всегда заменит companion object в Kotlin:


  1. Через него можно выражать логгеры, см. kotlin-logging. Да, я знаю, что можно поставить Lombok, чтобы обойти недостатки языка, но ведь классно, когда все решается через изящный синтаксис, верно?
  2. Их можно еще использовать как "расширенные factory классы". Пример в статье https://habr.com/en/company/dbtc/blog/505162/, см ResultSetMapper<DbUser>
  3. На них же можно сделать иерархию конструкторов (если продолжать пункт выше), чтобы можно было бы писать MyClass.of(...), причем сама реализация этого of определена где-то в интерфейсе.

На деле, часто на Kotlin/Scala смотрят просто с позиции Java, в стиле "будем кодить так же, теми же способами, просто теперь можно будет final писать пореже", что некорректно. Это все равно, что на машине с коробкой автомат переключать передачи вручную.


Вы же поймите что я тоже могу привести примеры где я сделаю на джаве в пару строчек а вы в Котлине будете простыню писать. Напримеру вас есть 20 пропертей в классе и надо одно из них убрать из вывода toString?

Вы привели работу Lombok'а. Я тоже могу написать генератор кода и потом сказать, что по трем настройкам в xml файле создается гигабайт байткода. Приведите, пожалуйста, пример кода, который мог собраться просто с помощью Java Compiler. Мы ведь о Java говорим?

Нет — я говорю о разработке приложений используя Джаву и возможные библиотеки. Потому что я не расматриваю сферического коня, а беру свою реальную разработку. Мне не важно, что в Котлине есть сингленом из коробки в одну строчку или что в Го есть каналы в стандартной поставке. Потому что в Джаве есть все что угодно в виде сторонних библиотек. Хотите асинхроности берете Reactor или RxJava, слишком жирно, тогда берете сырой Нетти, надо по быстрому что то запилить берете Спринг с которым знакомо подавляющее большинство разработчиков, а можно Кваркус и компиляцию в нативный бинарник и этот список можно продолжать. Я опять же писал — что Котлин отличный вариант для Андроида с его застывшей старой джавой. А на бэкенде нет смысла вводить дополнительный язык, чтобы попытаться съекономить пару строчек кода.

разработке приложений используя Джаву

Такая постановка задачи у меня уже кучу лет вызывает вопросы. Вот учится человек в школе, изучает один язык программирования (у нас был Pascal). В университете человек изучает на первом курсе еще 1-2 (у нас был С++ и тот же Pascal). На втором курсе человек изучает еще языки (у нас были SQL и Java). Потом третий курс (у нас были Assembler, C#) и так далее. Причем я подсветил именно предметы по языкам программирования, так как из-за той же физики мы использовали Academic версию Matlab со своим языком.


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


И дальше возникают фразы "мы пишем на Java" — но зачем? К вам разве приходят только люди после первого курса? В резюме у каждого почти куча технологий, распальцовка такая, что бандиты из 90х позавидовали бы. А в результате, получаем синьора "я умею писать принципиально на одном и только одном языке".


Ведь язык — это инструмент, не более. Для Java Card разумнее писать на Java, для Data Science разумно на Scala (если мы говорим про JVM) и так далее. Какой смысл себя ограничивать одним языком? Это все равно, что имея шуруповерт человек принципиально отказывается пользоваться перфоратором или дрелью.


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


Но почему программисты насильно ограничивают себя в выборе инструментов? Ведь куча сервисов содержат и backend, и frontend. И в чем смысл того, что человек сможет писать код только в одной части проекта?


А потому, после относительно эмоционального рассуждения, я повторю вопрос — а откуда у вас пришло требование "разработке приложений используя Джаву"? Вам его бизнес поставил? Или у кого-то высокого уровень квалификации на уровне студента первого курса?

Вас что то не туда унесло. Я говорил про всю эко-систему Джавы и что нет ее брать одну в рамках вашей фразы


Эта библиотека не содержит зависимостей ни на что, кроме компилятора Kotlin.

а откуда у вас пришло требование "разработке приложений используя Джаву"

Смотря какие приложения. Где критична память то я бы брал Раст сейчас, если это Виндос то С# и прочие вещи от Микрософта. А когда надо в организации сделать микросервисы то брал бы Джаву, потому что много разработчиков, много библиотек. Общаясь на Хабре я выражаю свое личное мнение.

то я бы брал

Вы говорите про платформы — JVM, CLR и пр. И с Вашим выбором я не спорю, я написал аналогичное выше.


Я спрашиваю лишь: кто конкретно делает ограничение в стиле "если выбрали JVM, то только язык Java, никаких xml для мавена" или "если выбрали CLR, то только C#, никаких F#"?


Это вся команда так проголосовала (слабо верится, хотя статистически возможно)? Или это менеджер за все решил? Или это тимлид из моего описания так решил (ну то есть угадал)?


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


Сразу оговорюсь — по моему опыту (проверено на нескольких командах), программисту редко требуется больше недели, прежде чем он будет резво понимать код на Kotlin/Scala. Но я говорю про программиста, у которого главными инструментами являются IDE и пр., а не Outlook + PowerPoint.

Это вся команда так проголосовала
За других не могу говорить, но в текущей компании да — хочешь что то привнести новое докажи, что оно стоит того.
А усложнять проект потому что Котлин — это модно, стильно, молодежно смысла нет. И разговор не столько про понимать код на Котлине, сколько зачем оно мне надо в бэкенде.
Вот такое мне читать очень тяжело
Удивляет такое. Это не Java, это другой язык. Естественно, человеку, не использующему этот язык, будет сложно читать код на нём. Вы же не думаете, что Java легко читать всем? Как читать цепочки вызовов методов в BigDecimal, когда все привыкли к операторам?
А код на java будет выглядеть как-то так:
    List<FileScriptSource> importedSources = annotations.stream().flatMap(it -> {
        if (it instanceof Import) {
            var paths = ((Import) it).getPaths();
            return paths == null ? Stream.empty() : paths.stream().map(sourceName -> {
                var dir = scriptBaseDir == null ? null : scriptBaseDir.resolve(sourceName);
                if (dir == null)
                    dir = new File(sourceName);
                return new FileScriptSource(dir);
            });
        } else
            return Stream.empty();
    }).collect(toList());
Намного понятнее стало? По моему нет, это надо в отдельный метод выносить(в java, в kotlin и так понятно). И так везде, вот вам и экономия в «пару строк». В пару строк на квадратный сантиметр, разве что.
Намного понятнее стало?

Конечно нет, а вот так?


        Flux.fromIterable(annotations)
                .filter(item -> item instanceof Import).cast(Import.class)
                .flatMapIterable(im -> Optional.ofNullable(im.getPaths()).orElse(List.of()))
                .map(sourceName -> scriptBaseDir.map(sc -> sc.resolve(sourceName)).orElseGet(() -> new File(sourceName)))
                .map(FileScriptSource::new)
                .collectList();

Что не особо отличается от варианта с Котлином

Что не особо отличается от варианта с Котлином
Только у Вас даже на таком небольшом участке кода — NPE(scriptBaseDir по условиям задачи — nullable).
И да, оригинальный код — не самый понятный, вот вариант получше:
annotations.filterIsInstance<Import>()
            .flatMap { it.paths ?: listOf() }
            .map { sourceName -> FileScriptSource(scriptBaseDir?.resolve(sourceName) ?: File(sourceName)) }
Сравните — котлин со стандартной библиотекой выигрывает как по читаемости, так и по объему кода в два раза. Понимаю, если у Вас небольшая кодовая база — но для крупного проекта это очень большая разница.
А Flux, как и Lombok — это не стандарт, и Ваш код вполне может вызвать вопросы у рядового Java программиста.
Только у Вас даже на таком небольшом участке кода — NPE(scriptBaseDir по условиям задачи — nullable).

Нет, я его сделал просто Optional<...>


Сравните — котлин со стандартной библиотекой выигрывает как по читаемости

Мне обилие ? и ?: ну вообще не заходит. Я и в джава x ?y:z не люблю пользоваться.


так и по объему кода в два раза.
Переношу .map(FileScriptSource::new) в строчку выше и убираю .collectList(); тк у меня везде и так реактивщина и получаем 4 против 3 :)))

Так же всегда можно придумать код который будет использовать операторы от Flux/Mono и которых нет в Котлине и наоборот, как в приведеном примере filterIsInstance


А Flux, как и Lombok — это не стандарт, и Ваш код вполне может вызвать вопросы у рядового Java программиста.

Да это так, я проводил много интервью и люди со стримами не могут совладать, пишут такую жуть. Так что им и Котлин не поможет.

Нет, я его сделал просто Optional<...>
тогда ок. А как Вы решаете, когда использовать Lombok аннотации вроде Nullable, а когда использовать Optional?
Мне обилие? и ?: ну вообще не заходит. Я и в джава x ?y:z не люблю пользоваться.
А мне очень заходит, особенно для цепочек вложенных значений вроде
foo?.bar?.baz?.someField?.etc

Так же всегда можно придумать код который будет использовать операторы от Flux/Mono и которых нет в Котлине и наоборот, как в приведеном примере filterIsInstance
Придумать можно. А в котлине можно ещё и самому этот метод добавить, не меняя Flux(что-бы всё было в единообразном fluent стиле).
Да это так, я проводил много интервью и люди со стримами не могут совладать, пишут такую жуть. Так что им и Котлин не поможет.
согласен.
тогда ок. А как Вы решаете, когда использовать Lombok аннотации вроде Nullable, а когда использовать Optional?

Здравый смысл. и коллекции я не использую нулевые.


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

Такое и с Optional не особо отличаться будет.


А в котлине можно ещё и самому этот метод добавить, не меняя Flux

А вот это тоже на мой взгляд не надо делать. Для Flux можно сделать явно чере as а не прикручивать то чего в самой библиотеки нет. Но опять же все это IMHO и оно складывается, что Котлин не заходит мне на БЕ. Мыслить все равно приходится в одной и той же парадигме. А писать ? вместо map уже мелочь.

Здравый смысл.
Т.е. нет единообразного подхода?
Такое и с Optional не особо отличаться будет.
Ну да, и код вида
x.multiply(new BigDecimal("1200.000")).add(ONE.substract(y).multiply(new BigDecimal("1200.000")))
как бы от простого математического выражения не отличается. Если очень сильно глаза зажмурить
А вот это тоже на мой взгляд не надо делать
Это не только со Flux работает. Как видно из примера на kotlin — там вообще никакого Flux не понадобилось. А `as`- дополнительное усложнение в Java коде, и без того не маленьком.
А писать? вместо map уже мелочь.
А Вы попробуйте сначала язык — поймёте, что различие далеко не в паре символах. Простыни Java кода с разными кастомными наворотами, превращаются во вполне каноничный kotlin код. Плюс всякие удобные штуки для dsl, корутины опять же. Я, как бэкендщик, вижу кучу преимуществ, и с радостью бы использовал этот язык в нашем проекте, если бы была возможность.
Если очень сильно глаза зажмурить

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


Это не только со Flux работает.

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


А Вы попробуйте сначала язык

Пробовал, не зашло.

Ничего не могу сказать, тк за все время я ни разу не использовал BigDecimal и не могу сказать это плохо не плохо, есть ли что то оборачивающее в более наглядный вид или нет.
а я использовал, и могу сказать что это однозначно плохо. Тем более Java позиционируется как Enterprise решение, при этом не подходит для точных расчётов(обычно так считают деньги).
так и говорю что я не хочу чтобы у меня стандартный класс на каждом проекте магическим образом обрастал разными методами в каждом проекте.
как правило, так и не происходит.
да прямо в вашем примере Optional.ofNullable(im.getPaths()).orElse(List.of()))
заменяется
im.paths?:listOf(), хотя бы

Это не учитывая того факта, что я вполне могу обьявить возвращаемый getPath() результат как not nullable, и тогда проверка вообще не нужна

Я уже несколько раз говорил, что мне читать Optional.ofNullable(im.getPaths()).orElse(List.of())) гораздо понятней чем пытаться разобраться во всех знаках вопроса и Элвисах. Так же написание в ИДЕ джавовского кода быстрое из-за автокомплита и особо не замедляет ничего по сравнению с Котлин.

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

А так-то да, я помню, когда в дотнете только-только linq появился, народ в ужасе закрывал глаза от всех этих (i => ++i). Мне тогда на работе, помню, коллеги сказали — а не мог бы я попроще писать, без этой вот функциональщины. А сейчас ничего, сами пользуют со свистом
Смысл моей фразы был в том, что реальный выигрыш от использования котлина не столь значителен перед джавой, и на джаве не сильно больше букав писать приходится, особенно с поддеркой IDE.


Дело не в буквах, программеры просто любят котлин, это приятный язык — особенно после жавы

Когда я пишу на жаве, у меня стойкое ощущение, что я пытаюсь обьяснить какие-то вещи умственно отсталому ребенку; когда я пишу на К. — мне просто приятно. Возможно, это оттого, что до жавы я лет 10 писал на сишарпе, и переход на жаву 7/8 был очень болезненный — натурально как с мерса пересесть в волгу. Вдруг я лишился linq, var, пропертей, null propagation, функциональщины и еще кучи вроде бы мелочей, которые делают ежедневную работу легче и приятнее.

Котлин натурально был лучом света

Вобщем, на тему «why i love Kotlin» была уже масса статей, именно с таким заключением. Вы, конечно, можете утверждать, что жава не более многословна, и вообще отличная, но противоположных мнений гораздо больше

А потом вы можете открыть статьи "Why I love Go" и почитать как это замечательно писать много много букв, как не нужны генерики и так далее. Это я к тому, что люди разные и им нравится разное. И многие (включая меня) не видят смысла вводить новый язык только потому что это лишь сэкономит вам чуток кода но добавит допольнистельную сложность (теперь два языка вместо одного). В плане программирования Котлин ничего не привносит нового.

А вы думаете, что нужны только те ЯП, которые привносят новые идеи? А если они привносят простоту?
А если они привносят простоту?

Для меня простота между Optional.ofNullable(im.getPaths()).orElse(List.of())) и im.paths?:listOf() несущественна, что надо привносить новый язык. Который все равно будет работать в джава мире.

Можно было остановиться на ассемблере, да:)

Ну, люди разные, что тут сказать.
Мне вот больше нравятся лаконичные языки. Помню, давно еще, в 2000, пришлось полгода писать на VBA (я был молод, и мне были нужны деньги). Так так он меня достал, что я чисто для себя написал COM-обьект типа прогресс бар (его тогда не было в VBA) на плюсах. Такой же многословный как жава, имхо; такая у меня детская травма

Ну и речь не идет об экономии строчек кода as is. Одно тянет другое, б0льшая экспрессивнсть языка позволяет выражать программируемые концепции более лаконично, что приводит к да, уменьшению строк кода, лучшей читаемости (облегчает ревью) и уменьшению вероятности появления глупых ошибок. В среднем, по сравнению с жавой, кода меньше раза в два, и читать его проще

Но кроме этого, К. принес массу именно языковых улучшений. К примеру, мне теперь не надо везде пихать listeners as SAM интерфейц, достаточно обьявить поле типа функция в классе, или переадть как параметр в функцию. Нуллабилити уже все обсосали много раз, и она реально работает и помогает. Это все привело к тому, что на К. стали писать библиотеки, которые на всю катушку используют эту самую экспрессивность и прочее. И теперь у нас, например, есть отличные корутины, Room, и масса прочего. На жаве все подобные решения были бы весьма громоздки и неудобны, я вот с ужасом смотрю на примеры использования тех же корутин на жаве; да и упомянутый вами Optional — ну это ж какой-то позор, извращение элементарной Maybe monad.

Все имхо, конечно.

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

Котлин, и в какой-то мере Скала являлись своего рода ответом на более чем семилетний застой, который образовался в Java во второй половине нулевых. Но, благо дело сдвинулось с мертвой точки и Java стала обрастать модными фичами из других языков, делая все менее оправданным использование альтернатив.


linq, var, пропертей, null propagation, функциональщины

  • linq: http://www.jinq.org/, JPA/QueryDSL, JOOQ, etc...
  • var давно уже есть
  • null: https://www.jetbrains.com/help/idea/nullable-and-notnull-annotations.html, как показывает практика, этого достаточно в большинстве случаев, а иногда удобнее, чем Optional или nullable-types.
  • проперти: боль, но есть Lombok
  • функциональщина: Vavr, functional java, etc...

То есть все как бы есть, пусть не в самом языке, зато расширяемо библиотеками.


Программируя на Котлине, что я заметил:


  • Нет единого выработанного стиля. Да, более экспрессивный, но позволяет использовать разные конструкции для написания одного функционального фрагмента. Нет четких правил по структурированию кода (пакеты, классы, файлы, etc) и устаканившихся паттернов проектирования. Помножьте все на то, что в тот же проект коммитят еще несколько гениев, у каждого из которых свое понимание как правильно.
  • Пишется легче, но читается сложнее. Лаконичность приводит к бОльшей семантической нагрузке на строчку. Многие сложные многошаговые конструкции пытаются свернутся в однострочник. На порядок больше неявностей и контекстно-зависимой семантики. Естественно все от того кто и как пишет, но код, написанный на Котлине в стиле джавы проще и понятнее, нежели труЪ Kotlin-way.
  • Интегрируется с Java далеко не бесшовно. Если использовать чисто котлиновскую либу, то все ОК. Но с Java нужно всегда держать ухо в остро.
  • Компиляция медленней, поддержка IDE хуже.

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

Поясните про сложность, пожалуйста, мне непонятно.


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

Забудьте вообще про нее. Она вам нужна только, если вы планируете использовать ahead-of-time компиляцию и шипить ваше приложение в одном бандле с jvm. Модули — это внутренняя вещь jvm, которая была придумана только, чтобы реальный размер бандла был не 250М, а 20-30М. Все остальные кейсы неплохо решаются при помощи старых добрых build tools.

это внутренняя вещь jvm

И да, и нет. Ещё модули помогают инкапсулировать реализацию вашего модуля без создания неудобств публичному API вашего модуля (как это сделал бы пакет с названием internal). Также они помогают наводить порядок в библиотеках, потому что натурально следят, чтобы один пакет экспортировался одним модулем, и не дают собрать приложение если это не так. И это всё — через стандартные механизмы, которые теперь не зависят от условий сборки в общем случае.

Но, благо дело сдвинулось с мертвой точки и Java стала обрастать модными фичами

не в Андроиде:)

linq: www.jinq.org, JPA/QueryDSL, JOOQ, etc...


дотнетовский linq сильно шире обращений к БД
Да, в жаве с 8й, что ли, версии (не слежу) есть streams и функциональщина; но в нашем случае с андроидом их непросто использовать

var давно уже есть


с крайне серьезными ограничениями в использовании:)

null: www.jetbrains.com/help/idea/nullable-and-notnull-annotations.html, как показывает практика, этого достаточно в большинстве случаев, а иногда удобнее, чем Optional или nullable-types.


Так это ж аннотации IDE:) И к тому же, варнинги. Котлин-то просто не даст скомпилировать такой код, вне зависимости от ИДЕ

То есть все как бы есть, пусть не в самом языке, зато расширяемо библиотеками.


об этом и речь. Вроде есть, но не в полном обьеме, но со сторонними библиотеками и т.п. Несерьезно это

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


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

Пишется легче, но читается сложнее. Лаконичность приводит к бОльшей семантической нагрузке на строчку. Многие сложные многошаговые конструкции пытаются свернутся в однострочник. На порядок больше неявностей и контекстно-зависимой семантики. Естественно все от того кто и как пишет, но код, написанный на Котлине в стиле джавы проще и понятнее, нежели труЪ Kotlin-way.


Ну, как говорится, сдуру можно и ээ карандаш сломать. Но вообще, чтение кода на любом языке это вопрос привычки и скиллов для этого языка. Чем больше вы знаете/понимаете язык, тем проще с узнаванием семантических конструкций.
Собственно, в мире дотнета это все уже пройдено — и жалобы насчет var (непонятно, что за тип, а мне обязательно надо знать), и с linq (не понимаю что написано, и где обьявления переменных), и прочее.

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

Интегрируется с Java далеко не бесшовно


на порядок лучше, чем scala:)

Это все довольно небольшие минусы, достоинства языка все окупают, имхо. Ну и на аднроиде другого выхода нет, гугл жаву лет уж 6 не поддерживает

Это странный подход — не найти позиций по Скале и говорить, что их нет. Не программировать в продакшн на скале и рассуждать о ее преимуществах и недостатках. Как будто не читал, но осуждаю.
Мне на Скалу приходили рекрутеры неколько крайних лет, хотя в моем профайле скалы нет. А текущую работу (моя первая работа на Скале) я получил, прийдя на собеседование по "Жава-сеньор" где мне сказали, что они скалистов не ищут, потому что их не найти, что джавы у них нет, а надо быстро подучить скалу (тут сотни программистов на скале). И вот когда видишь эту самую скалу не в курсе Одерского, а на кровавом энтерпрайзе — микросервисы и никакого датасатанизма — то многие вещи видятся по-другому.

Если выразиться емко — scala геморройный язык.
Собственно это мой практический опыт, хотя изначально у меня были большие ожидания. Но работа на проектах со Scala за год, все поставило на места. Процесс разработки перерастает в борьбу с типами.
Получается что каких то реальных плюсов язык не дает — кол-во ошибок не меньше, скорость разработки не увеличилась, зато сильно усложняет код за счет множества сложных связей между типами.
Думаю это основная причина почему его перестали использовать.

Понятно, что опыт у всех разный. Но можете простой пример борьбы с типами? И вот этих всех сложных связей между ними?
Go vs Java: выбор очевиден. Go примитивнее Java, меньше библиотек, фреймворков и тулов. Гораздо труднее найти квалифицированных разработчиков. За 2 месяца можно только язык выучить, для полноценной разработки это крайне мало — надо знать инструменты, паттерны, best practices, библиотеки и их особенности. На это уйдёт не один год. В то же время никаких значимых преимуществ GO не даёт.

Go vs Scala: вообще разные весовые категории.

Scala/Java/Kotlin vs TypeScript: на TypeScript-e пишут фронтэндеры. А квалифицированный фронтэндер — это дорогой и труднонаходимый зверь, которого все хотят оторвать с руками.

Kotlin vs Scala: спорный вопрос, я бы точно предпочёл kotlin. Но очевидно есть аргументы и за другой вариант

Ну и если бы я верил в то, что система, написанная FullStack-разработчиками может в принципе работать :)


Вот этого комментария в сторону FullStack-разработчиков я вообще не понял — очевидно у автора своего рода юнешеский максимализм

Для разработки я выберу Rust. Но только в том случае, если нужно будет двигаться итеративно и проект будет достаточно большой и долгий. Если нужно быстро написать прототип, чтобы потом его выкинуть (а не развивать в законченный продукт) — то тут Rust точно не подойдет, нужно будет выбрать тот язык, который позволит создать прототип быстрее.

Интересно почему автор не рассматривает .Net стек:
  • Производительность лучше чем в Java и Go
  • Собранный docker image сравним по размеру с Go
  • Синтаксис не менее богатый чем Scala при куда более удобном тулинге: чего стоят синтаксические анализаторы, поставляемые с библиотеками и помогающие работать с конкретно этими библиотеками
  • Из основных фреймворков было вычищено все легаси. По сути произошел глобальный рефакторинг всей экосистемы 4 года назад


Я не пытаюсь рекламировать C#, просто интересно, почему он не входит в «поле зрения» при принятии решения.
Заголовок спойлера
image


Для неболших проектов, которые крутятся во круг CRUD'ов, нужна админка поднимаю на связке Groovy и Spring. А библиотека для тестирования — Spock, все еще самая лучшая для меня. Вот почему Groovy умер как скриптовый язык в JVM? Почему Kotlin заберает его нишу?
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации