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

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

1. Kotlin более проприетарный....


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

Не обязательно даже покупать. Вполне может случиться история как у Mozilla с Rust. Причем Mozilla, как я понимаю, изначально прикладывала усилия, чтобы создать здоровое сообщество вокруг языка, и по факту он смог продолжить самостоятельное плавание.


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

История то пока как раз хорошо развивается.

Вы возможно не в курсе, но теперь разработка языка финансируется из Rust Foundation, что то есть Rust теперь не "ничей", а "общий". Разница для некоторых может ускользать, но она существенная – сейчас в развитии Rust заинтересовано множество компаний и людей, а не только одна Mozilla.

Я ровно это и написал, с чем вы несогласны?

Котлин действительно полностью опенсорсный, rzwitserloot врёт. Почитайте ответ elihart17, например.

Бинарные блобы в драйверах для Линукса тоже можно дизассемблировать, но это не делает такие драйвера open source в исконном смысле этого слова. Open source — это то, что любой может форкнуть и переписать под себя. Хранение ключевого кода компилятора в обфусцированном виде этому явно не способствует.

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

Про @Metadata можно прочитать в доке например https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-metadata/, а сами данные в протобафе и лежат в репозитории котлина https://github.com/JetBrains/kotlin/blob/master/core/metadata/src/metadata.proto. Для любого кому это интересно – не сложно найти это (я нашел прямо в интерфейсе гитхаба). Ну и конечно чтобы понимать это нужно понимать компилятор :) Интересно как много джава разработчиков умеет в сорцы javac)

Похоже, это никакой не "проприетарный код" в компиляторе, а просто способ для компилятора дописать дополнительную инфу в жестко заданном формате .class-файлов, который, естественно был заточен только под javac.


Компилятор Scala тоже пишет достаточно много метаинфы в .class-файлы. С этим можно огрести, если например использовать обфускаторы, работающие на уровне байткода. Но ничего криминального и проприетарного в метаинфе нет.

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

@Metadata используется именно для котлиновского рефлекшена. Было очень много головной боли, когда ProGuard ломал мне метаданные внутренних классов и приложение начинало падать в случайных местах при десериализации через Moshi.

Нативная поддержка null, которая греет душу любого котлиниста, легко заменяется в Java на обёртку из Optional.ofNullable

a) Вместо Optional всегда может прийти null
б) Optional никак не избавляет от проверок на null. Просто вместо if(it!=null)по всему коду будет if(optional.isPresent())

в) Опять же, таскать повсюду эту обёртку. Вместо `(arg: MyClass)` посвюду будут `(arg: Optional<MyClass>`. А джава и так не отличается лаконичностью.

г) Ну и самое главное. В котлине null safety проверяется на этапе компиляции, а не в рантайме, что, какбы, значительно интереснее

Пара корректировок:


вместо if(it!=null)по всему коду будет if(optional.isPresent())

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


В котлине null safety проверяется на этапе компиляции, а не в рантайме

В джаве Optional это и есть способ обеспечения null safety на этапе компиляции. В рантайм это пролезает только в паталогических случаях, вроде Optional.get() или передачи null вместо Optional, но с такими случаями до какой-то степени можно бороться линтерами.

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

В Котлин можно написать val notNullValue = calculateNullableValue() ?: return. Как вам тут поможет map и flatMap?

Мы обсуждали Optional в джаве, про котлин я ничего не говорил. Но если вы спрашиваете, как в аналогичном вашему кейсе в джаве обойтись без if(!optional.isPresent()) return, то очень просто:


void myFunc() {
  ...
  optional.ifPresent(x -> ...);
}

Конечно, если в целом окружающий код императивный, то лучше сделать if и return/break. Но если это какие-то преобразования на стримах, например, мой вариант будет более уместен.

Конечно, если в целом окружающий код императивный, то лучше сделать if и return/break.

Ну то есть вы понимаете, что вопрос не в умении или не умении map/flatMap, а в том, какая у нас вообще задача и какой код вокруг? Просто вы так написали, будто готовы уволить любого, кто isPresent() в коде напишет.


ifPresent — это уныло. Мы можем находиться во вложенном if/while/for, тогда это не поможет. Если же у нас несколько проверок на null подряд, то будет opt1.ifPresent(x -> opt2.ifPresent(y -> opt3.ifPresent( -> {...}))). Ну и, конечно, замена if(opt.isPresent()) на opt.ifPresent() не делает код лучше в 99% случаев. Он не становится более функциональным, менее зависимым от сайд-эффектов, при этом его становится сложнее отлаживать в пошаговом отладчике, удлиняются стектрейсы и т. д.


Я вообще делаю обычно так:


V v = computeOptional().orElse(null);
if (v != null) {
  ... используем v
}

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

Просто вы так написали, будто готовы уволить любого, кто isPresent() в коде напишет.

Я отвечал на "Optional никак не избавляет от проверок на null", что по факту не так. Использовать или нет — это воспрос стиля, принятого на конкретном проекте.


opt1.ifPresent(x -> opt2.ifPresent(y -> opt3.ifPresent( -> {...})))

Ну такой кейс во всей своей жести и на if'ах будет выглядеть неочень, особенно если есть else-часть.


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

Ну да, ifPresent — это для сайд-эффектов как раз и сделано. И да, есть плюсы и минусы. Но все-таки он вполне избавляет от проверок на null, о чем собственно и был изначальный тезис.

На ифах будет плоская структура:


X x = calcX();
if (x == null) return;
Y y = calcY(x);
if (y == null) return;
Z z = calcZ(y);
if (z == null) return;
// пользуемся x, y, z на здоровье.

Ну если цель в том, чтобы минимизировать стектрейс то да, if вне конкуренции. Если цель — уменьшить вероятность NPE при помощи компилятора — я, уж простите, поеду с Optional.

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


img

Optional не решает проблему с null. Её лучше решают nullability-аннотации и в целом массовый отказ от null (non-null by default). Но, конечно, в Котлине это сделано красивее и удобнее.

Optional не решает проблему с null. Её лучше решают nullability-аннотации

Непонятно, почему аннотации лучше. С использованием nullable-аннотаций, на мой взгляд, есть несколько проблем. Процитирую свой старый коментарий:


  1. нельзя отличить неинициализированное по ошибке поле от необязательного без значения
  2. аннотации для локальных переменных выглядят сильно хуже, чем Optional
  3. для null нет никаких средств композиции, для Optional есть flatMap

Для локальных переменных аннотации не нужны, любая нормальная IDE и без них справится. А средство композиции есть. Называется if. Насчёт инициализации с Optional тоже бывает, что поле может иметь значение, может не иметь, но инициализировать его надо лениво. Как будем выкручиваться? Optional<Optional<X>>?

Насчёт инициализации с Optional тоже бывает, что поле может иметь значение, может не иметь, но инициализировать его надо лениво. Как будем выкручиваться? Optional<Optional<X>>?

А что не так? Ну, кроме того, что это должно быть Lazy<Optional<X>>

  1. Неициализированные поля, по-моему, в целом проблема дизайна, потому что всё подобное (поля) стоит делать final, инициализируя при создании объекта. Экзотику с не очень удачным DI, вроде оного в JFX, стоит рассматривать, скорее, как неудачное решение.

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

  3. Тут, увы, да, но в пределах API, скорее, nullа будут избегать (снова же, при удачном дизайне). Классический пример, пустая коллекция лучше nullовой.

Неициализированные поля, по-моему, в целом проблема дизайна, потому что всё подобное (поля) стоит делать final, инициализируя при создании объекта.

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

Ну почему же? Всё тот же Spring умеет в инициализацию через конструктор, либо, что ещё более приятно, static factory method. Единственное, что, по-моему, может мешать этому — циклические зависимости, но, это как раз чаще признак того, что что-то не так.

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

Не зря всякие @PostConstruct выдуманы. В Спринге еще есть такие же вещи. Которых в новом проекте не должно быть. А вот в старом иногда по другому не разрулить зависимости никак. Разработчики Спринга знают своих пользователей.
Неициализированные поля, по-моему, в целом проблема дизайна

В целом согласен, но иногда бывает нужно ленивую инициализацию. А если отойти от Optional и просто поговорить о final-полях в джава, то с этим до сих пор довольно много проблем. Тот же хибер, который совсем не экзотика, форсит делать изменяемые поля. Надеюсь, новые record'ы, который immutable by design, улучшат положение дел, но врядли это произойдет быстро.


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

А кем выводится? Я вот за то, чтобы выводилось компилятором. Optional для этого и сделан как раз.


Тут, увы, да, но в пределах API, скорее, nullа будут избегать (снова же, при удачном дизайне).

Возьмем например REST API. Насколько я знаю, при маппинге необязательных полей из Java в JSON и обратно, у вас два варианта — либо nullable, либо Optional. Как можно избежать null, если не использовать Optional?

Так потому и в стайлгайдах и в рекомендациях разработчикам пишут (и даже Идея это подсвечивает), что не надо возвращать Optional или принимать его в параметрах. По возможности, конечно. Если ожидаете что вам где-то может вернуться null или быть передан в параметрах — оборачиваете вызов в Optional, работаете с ним. Уверены, что такого не случится — работайте как работалось. Порой выглядит лучше чем код!.. белок!.. истеричек!!!

В параметрах передавать как раз таки антипаттерн.

Возвращать как раз хорошо. Принимать неправильно, да.

г) Ну и самое главное. В котлине null safety проверяется на этапе компиляции, а не в рантайме, что, какбы, значительно интереснее

Если рядом нет Java-кода.
На андроиде он обычно есть (старый код проекта или системный код андроида)
Какая то мелкая ошибка и креш с xxx must not be null. (xxx — объявлен в Java-коде)
И никаких вообще предупреждений компилятора.
Недавно пришлось править баг на эту тему. Dto-объект объявлен на java. одно из полей инициализируется вручную а не десериализатором (по историческим причинам, альтернатива — целиком этот модуль переписать, что в планах). вот только все забыли что у приложения есть (и используется иногда на проде) еще один legacy режим работы. в legacy-режими инициализации поля нет ни десериализатором ни вручную и при попытке обратится получатся xxx must not be null.

Ну уж в этом случае никто не мешал вам поставить Nullable на это поле. Это бы проросло в котлин.
НЛО прилетело и опубликовало эту надпись здесь

COBOL вполне себе успешно используется в банковском софте) Но мне тоже кажется, что автор прав и Scala не блещет какими-то успехами в последнее время.

НЛО прилетело и опубликовало эту надпись здесь
Между использованием кобола (в виде поддержки старого софта на нем) и написанием на скале нового вообще говоря разница огромного размера. По крайней мере — потенциально.
НЛО прилетело и опубликовало эту надпись здесь

На hh:

COBOL - 0 вакансий

Scala - 260 вакансий

Kotlin - 994 вакансии

Java - 4060 вакансиий

Так что COBOL скорее мертв, чем жив. Scala нашла свою узкую нишу. Kotlin до Java ещё далеко...

Kotlin уже набирает обороты, так что, мне кажется, что разрыв будет становится все меньше

Согласен. Kotlin развивается и в каждой вакансии под Android уже спрашивают знание Kotlin.

С бекендом этот процесс идет медленнее.

Просто программистов COBOL не набирают по объявлению )

Да они и не откликаются на объявления. Google "Cobol cowboys")

Похоже это отдельная вселенная... Такая же как и отдельная вселенная 1С-ников, отдельная вселенная рубистов и т.д.

Когда работал в Сбере ни разу не слышал, что ищут программиста Cobol (искали C, C++, Scala, JS, Python и больше всего искали Java) - хотя там тонны легаси. Но постепенно легаси заменяются на современные технологии....

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

Вместо кобола в России — абап.

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

Пользуясь случаем, хотел спросить. А отдельная IDE для Раста у вас планируется? Ну хотя бы в отдалённых планах может быть?

Не имею такой информации.

а зачем? можно тот же GoLand взять и в него поставить Rust

Скорее уж тогда CLion:


In CLion, you get even more: fully-fledged debugger, CPU profiler, and Valgrind memcheck.

Но, по сути, да, особого смысла в отдельной IDE сейчас нет.

Канеш мертва. А некроманты 3ую версию тут релизят
www.scala-lang.org/blog/2021/05/14/scala3-is-here.html

Ну и lightbend контора некрофилов тоже. Да и тинькофф туда же. Полностью согласен.
Да и сравнение с COBOL в точку прост. На рынке аж 1 вакансия в самом прогрессивном банке на рынке страны. да что там страны!
spb.hh.ru/vacancy/43083989?query=cobol

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

Тогда уж лучше всё же кобол

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

К тому времени все уже на Rust перепишут )

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

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

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

Понятно, что шутка, но все же за раст как раз в плане мощности системы типов душа болит. Специализация, гаты, конст генерики — всё прячется за min_min_min гейтами и практически не едет. Это грустненько.


Тогда как в скале б0льшая часть этого давно есть.

Согласен, наверное это самое большое разочарование для программиста на Rust: язык сначала воодушевляет, а потом оказывается, что то — нельзя, это — нельзя… И возникает уныние.


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

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

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

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

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

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

И я пробовал скалу именно на этом поприще. Сваял для пробы пера тетрис на связке scala + libgdx. Ну что могу сказать. У меня все время было ощущение, что мне хочется писать на скале именно как на джаве в ООП парадигме, и мне приходилось все время делать насилие над собой, чтобы придерживаться чистого ФП стиля. В итоге получилось обойтись почти без ооп, кроме тех мест, где надо было непосредственно с libgdx взаимодействовать, но вот само ощущение, что все время хотелось забить на ФП, и начать писать как на джаве, оно удивило. Ведь я пробовал писать рогалик в псевдографике в чистом ФП стиле на хаскеле и в принципе мне нравилось. По ООП совсем не скучал, наоборот было ощущение, что вот как клёво, никаких тебе объектов, которые вызывают методы друг друга хаотическим образом, как здорово, что нет этой путаницы, когда все зависит от всего.

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

Я не думаю что она куда-то уходит: сидит в своей нише и сидит. Изучить её в любом случае доброе дело — система типов там куда лучше чем у мейнстрима.

Если Java не будет «спать», как в нулевые, и продолжит развиваться, то в перспективе Kotlin — безусловно эволюционный тупик. Избавиться от «проклятия вторичности» JetBrains сможет, если в какой-то момент отвяжется от базы JVM и разойдется с Java по настоящему. Видимо и проприетарность в какой-то момент придется отменить. Хотя JB и создала Kotlin во многом для того, чтобы продавать больше IDEA.

У меня есть гипотеза, что Котлин создан не чтобы продавать IDEA, а чтобы разрабатывать IDEA. У JetBrains, я думаю, одна из самых развесистых Java-кодбаз в мире. Мало кто решается повторять их подвиг, предпочитают Electron. И когда несколько лет подряд 8 часов в день 5 раз в неделю пишешь Foo<bar> foo = new Foo<bar>, то в какой-то момент мысль о том "вот бы была такая Джава, как Джава, только лучше, и можно было бы в одном проекте их использовать" начинает преследовать.

Что такое развесистая JAVA-кодобаза? Electron используют по причине удобного рендеринга, движок chromium настолько оптимизирован, что даже не все десктоп приложения так быстро могут рендериться, плюс легкий вход css + js. Все же по мне JAVA отстает в плане графики. И при наличии jetbrains ide все же в некоторых проектах предпочитают VS Code, она шустрая, быстро запускается и самое главное есть интеграция с некоторыми тулчайнами, с которыми нет у jetrains.
Но ведь VS Code это не IDE. Максимум умный блокнот с плагинами. Нет ничего удивительного, что она быстрее запускается.
IDEA точно такой же умный блокнот с плагинами. Деление IDE/не IDE давно потеряло всякий смысл.
Ну просто есть какая-то критическая масса умности и плагинов, когда умный блокнот становится IDE.
В vscode это обычно достигается установкой плагина поддержки того или иного языка, который привносит весь необходимый набор инструментов. А потом можно еще поставить вагон других, которых либо вообще нет в IDEA, либо за них просят денег, да еще немалых. Это одна из причин, почему я похоже никогда таки не перейду на Goland. Как IDE для Go он не умеет ничего сверх Vscode, а его набор плагинов банально недостаточен мне.

Сколько бы плагинов в vscode не ставил - он всегда хуже чем web/phpstorm из коробки, да и работать начинает медленней, например go to definition срабатывает через пару секунд.
о том, что между ними нет разницы пишут только фанаты редакторов, которые не освоили нормальную ide

о том, что между ними нет разницы пишут только фанаты редакторов, которые не освоили нормальную ide

Ну у меня есть idea, для джавы ее использую, т.е. вроде бы по вашей класификации IDE освоил. А вот для JS/TS использую vscode и считаю его более удобным чем webstorm.

Осилил, и около 7 лет работал на идее, несколько месяцев назад пересел на VSCode. Из недостатков для меня только работа с гитом, в остальном не вижу особой разницы. По производительности ощущается намного лучше, ничего не зависает во время автокомплитов, не шумит как самолет из-за постоянных индексаций + есть remote development, которого почему-то до сих пор в «самой продвинутой» IDE нет

Вот этого нет?

Только что попробовал. Не совсем, хотя до недавних пор даже этого не было.
В VSCode полноценный клиент, который взаимодействует с анализаторами, плагинами, файловой системой и т.д. на сервере через api, за счёт чего разница с локальной разработкой фактически не ощущается, а тут просто сделали что-то вроде VNC, из-за чего скролл и шрифты выглядят странно и чувствуются задержки при взаимодействии с UI

Ну основное отличие — интегрированность. Обычно один плагин в умном блокноте никак не взаимодействует с другим. В той же идее есть некий протокол взаимодействия, что ли. Например, когда ты можешь в java-коде вставить jpql-строку. И она не просто подстветится в соответствии с синтаксисом, но и будут работать автодополнения. А если настроены datasource, то оно ещё и с реальными таблицами в базе интегрируется.

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

ПО закону мерфи именно те 2 плагина которые вам нужны интегрированны друг с другом не будут :)

Умный блокнот с плагинами это продукты Jetbrains. Уже ниже писал, что за свои деньги становишься каким-то бета тестером и не возможно нормально работать. Скажу больше, в плагинах VS Code поддержка некоторых тулчайнов, значительно лучше чем в продуктах Jetbrains. У Jetbrains конечно есть свои плюсы, но и есть кучу минусов…
Ага, в Райдере поддержка новых версий тулчейнов выходит с запозданием в месяц — два. В платном продукте. Или например в бесплатной Идее делать нельзя ни-че-го.

Это при том, что VS Community бесплатен.
Мафия вошла в чат… То есть сотрудники Jetbrains. Все минусуют…
Они кстати очень смешные, совсем не умеют признавать свои ошибки и баги в их продуктах, но искренно верят в свою исключительность и что их IDE одни из лучших. Когда им говоришь про серьезные проблемы и недоработки мешающие работать, даже огрызаются… Самое главное они недостаточно понимают специфику работы конечных пользователей их IDE, и какие задачи они решают, будь-то живут в своей вселенной Jetbrains… Вроде они что-то сделали хорошее, но все не то. Условно дали вам красивые кожаные ботинки, но не дали носков, а ботинки вроде есть, но натирают мозоль и протекают… В итоге вы носите старые кросовки…
То есть сотрудники Jetbrains. Все минусуют…

Везде заговор!


совсем не умеют признавать свои ошибки и баги в их продуктах

Я умею. Дофига багов, вообще глюкавище полное иногда релизим :( А кто не умеет? Можно более конкретный пример?


но искренно верят в свою исключительность и что их IDE одни из лучших

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


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

У наших IDE порядка 10 миллионов пользователей, большинство платных. Они все ошибаются? Пали жертвой агрессивного маркетинга? А может такое случиться, что как раз ваши потребности слишком специфичны и не укладываются в сценарии, которые нужны большинству (говоря русским языком, "пользователь хочет странного")?

У наших IDE порядка 10 миллионов пользователей, большинство платных. Они все ошибаются? Пали жертвой агрессивного маркетинга? А может такое случиться, что как раз ваши потребности слишком специфичны и не укладываются в сценарии, которые нужны большинству (говоря русским языком, «пользователь хочет странного»)?

Это случается потому, что для джавы Идея — лучше чем остальное (там совсем все плохо), а не потому, что Идея прямо идеальный инструмент.

Кто-то выше утверждал, что Идея идеальный инструмент? Была бы она идеальна, мы бы без работы остались :-)

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

Применимо для чего угодно. Ничего идеального не существует, а сама идеальность меняется со временем.

Посыл был в том, что много областей, где заставляют писать на Java

Я так же пользуюсь райдером вместо студии и Clion вместо VSCode для раста. А ещё датагрипом вместо прости господи pgAdmin. Ещё эпизодически есть dotPeek/dotMemory/… и некоторые другеи продукты.


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


img


Подводя итог: у нас в компании куплены и VS и Rider лицензии. Изначально все сидели на студии, потом райдеры купили. Так вот за пару лет не осталось ни одного разраба на студии, включая меня.


Всех подкупили, Не иначе.

Реально полное глюкавище распиаренное — пользоваться невозможно. Разве это софт? Вот пойду щас на notepad'e код попишу через экранную клавиатуру и через PowerShell позапускаю. Вот где стабильность, никаких тебе бесячих подсказок, никаких автоподстановок и глюкавых плагинов — только программистский хардкор!

Far Manager FTW: редактор и командная строка в одном флаконе!

говоря русским языком, "пользователь хочет странного"

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

Я хочу странного?

Скорее странно (мягко говоря) поведение JetBrains:

1) маскируются под чехов, на вопросы, заданные на русском языке, отвечают на плохом английском

...

N) Плачутся что их не внесли в реестр "отечественного" ПО

А вы много знаете продуктов мирового уровня, где есть поддержка и документация на русском? Мне на ум приходит MS Windows и некоторые сервисы Google. И то, и другое предназначено для широких народных масс.


Кстати, можно ссылку, где JetBrains плачется по поводу реестра? Ну потому что они очевидно не "отечественное" ПО.

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

Adobe, например: Illustrator, Photoshop — такая поддержка была лет 10 назад (сейчас — не знаю).

Кстати, можно ссылку, где JetBrains плачется по поводу реестра?

Один из руководителей(?) жыдбрэйнсов сетовал на это в своём интервью, которое вроде даже проскакивало здесь на Хабре.
можно ссылку, где JetBrains плачется по поводу реестра?


31 декабря 2016 Меня разрывает, когда я не могу писать код — интервью с Максимом Шафировым, CEO JetBrains

— Вы будете что-то с Россией специально делать, или воспринимаете рынок таким, какой он есть?

— Он хороший, нам нравится. Зачем с ним что-то специальное делать? Я думаю, что продуктовые российские компании к нам так или иначе все приходят, мы их знаем, вы их знаете. Можно назвать имена, но это ничего не расскажет дополнительного. Есть такой специальный сектор, как государственные компании или просто государственные структуры, вот с ними можно было бы как-то специально работать, но у нас тут случился казус, и теперь им нельзя покупать наш софт!


— То есть для них вы не российская компания?

— Для них мы не российская компания, потому что интеллектуальная собственность принадлежит чешской компании. У нас так устроен бизнес, что чешская компания заказывает разработку российской, российская делает на заказ за денежку, интеллектуальная собственность остаётся на балансе у чешской. Когда вы покупаете что-то, вы покупаете это у чешской компании. А [для продаж госкомпаниям] нужно быть в специальном реестре. И если в этом реестре есть хоть что-нибудь, отдалённо напоминающее конкурента по названию или по рубрике, то вы не можете купить зарубежный продукт, вы должны купить российский.


— Так а ведь нет же никого!

— Фактически нет, а если почитать реестр — то есть.


— Есть IBM с Eclipse, есть Oracle с NetBeans — и они же все тоже иностранные.

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


— Это довольно забавно. То есть это всё с импортозамещением связано, с такими вещами?

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


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

Я хочу странного?

Если коротко, то — да. Я обычно хочу обратного — чтобы все на английском было. Доходит до смешного: например, постгря ошибку авторизации всегда отдает в серверной кодировки, не важно в какой вы там просили её ответить. В итоге рождаются такие смешные костылики: https://github.com/zemian/pgjdbc/commit/bd6de1b360c6a72b5513597813bef3773835e84e


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


Так что да — странного.

Причём здесь «текст ошибки», который индус перевёл ПРОМТом?

Я говорю о том, что когда в JetBrains русские для русских пишут документацию на плохом английском — это #шизофрения

Как вы перешли от


1) маскируются под чехов, на вопросы, заданные на русском языке, отвечают на плохом английском

к


Я говорю о том, что когда в JetBrains русские для русских пишут документацию на плохом английском — это #шизофрения

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

Как вы перешли от

1) маскируются под чехов, на вопросы, заданные на русском языке, отвечают на плохом английском


к

Я говорю о том, что когда в JetBrains русские для русских пишут документацию на плохом английском — это #шизофрения


Это не я «перешёл», это перешли JetBrains

Я, решая вопрос о закупке ПО выбрал другое ПО (худшего качества, но производители которого не шизофренируют с «больше охват» за счёт отказа, себе в убыток, от собственной русскости).

Сначала я (потенциальный покупатель)
1) обратился в JetBrains на русском языке с вопросом «существуют ли официальные учебные курсы, документация и обучающие материалы на русском языке?»,
потом
2) получил ответ на ломанном английском что ничего такого нет,
затем
3) приобрёл (за деньги) другое ПО другого производителя
и ещё
4) повторил свой запрос (через несколько лет)
— 5) с тем же результатом.

А потом прочитал интервью их CEO(?) в котором он пожаловался, что "не может" торговать своим ПО в РФ.

#шизофрения

У меня в карме счётчик сотрудников жыдбрэйнс, набижавших на хабр.

Ещё раз, для «непонятливых»:

Шизофрения в данном случае — это отказ (по сути запрет самому себе) использовать свой родной язык и попытка «обьяснить» этот отказ «расширением охвата»,

а потом жалобы на то, что охват ВНЕЗАПНО сузился и оправдания в духе «не можем ничего поделать!» —
у нас тут случился казус...


habr.com/ru/company/funcorp/blog/558412/?reply_to=23063292#comment_23063136
русские для русских пишут документацию на плохом английском — это #шизофрения

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

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

А потом прочитал интервью их CEO(?) в котором он пожаловался, что «не может» торговать своим ПО в РФ.

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

Сначала я (потенциальный покупатель)

Формула «покупатель всегда прав» никогда не работала, работала «если покупатель приносит денег больше, чем стоят его хотелки, тогда он прав».

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

#шизофрения

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

вы описываете какой-то «гипотетический» случай. Или случай «общий» (причём вы его считаете общим, а я компания Adobe — нет :-)

А я — практический случай, имевший место быть,
причём случай прямо противоположный:

1) я обратился на русском языке в «чешскую» команию JetBrains по вопросу существования русских же материалов
2) мне человек с русским Ф.И.О. ответил на английском.

Т.е. имели место аж два лишних (стоящих денег, усилий, снижающих качество коммуникации) перевода на ненужный в данном случае язык.

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

1) Вы не поверите, но человек с русским Ф.И.О. может не иметь русский как родной (коллеги с Украины, Казакстана и те чьи родители давно иммигрировали из СССР передают вам привет), например, Серге́й Миха́йлович Брин хоть русский вроде бы знает, но если бы его вывезли из СССР в более ранем возрасте легко мог бы его уже и не знать,

2) Если вы напишите вопрос на русском на английском StackOverflow, я вам тоже ответ на русском не напишу, потому что у каждого ресурса есть свои правила, в лучшем случае напишу комментарий где попрошу использовать русский ресурс или перевести вопрос на английский,

3) Кстати, вот у меня ни на одной клавиатуры (ни дома, ни на работе) нет русских букв, разумеется, лично я давно освоил слепую печать однако знаю много сотрудников (тестировщиков, HR, иногда даже программистов), которым приходится писать транслитом при общении на русском или долго искать где же находится та или иная русская буква,
Вы не поверите, но человек с русским Ф.И.О. может не иметь русский как родной (коллеги с Украины, Казакстана и те чьи родители давно иммигрировали из СССР передают вам привет),

человек с русским ФИО, сидящий на Васильевском острове в СПб?
вы утверждаете, что они шпионы что ли :-)

JetBrains. Офис по принципу «сделать людям комфортно» 16.07.2014 Марина Кван
Представьте, у них есть офисы и за пределами РФ.

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


Но страждующие увидят и в этом русофобию. Это как радикальные SJW, но в отношении своего этноса. Так и ищут чем бы ещё оскорбиться :) Полезный навык наверное.

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

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

Давно это было?

Если надо ЕЩЕ примеров на тему "не того" языка -:)
то можно придраться к тому что Kotlin in Action / Kotlin в действии изначально написана на английском хотя казалось см хотя бы тот факт что авторы вычитывали текст после переводчика на русский (что не скрывается — https://habr.com/ru/company/JetBrains/blog/339400/ )


Т.е. имели место аж два лишних (стоящих денег, усилий, снижающих качество коммуникации) перевода на ненужный в данном случае язык.

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

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

А никак не надо переводить. Вот как перевести на русский слово атмосфера (греч.), галоши (франц.), зонтик (голланд.), бутерброд (нем.)? Да никак, просто берется слово вместе с понятием.


Можно изобретать колоземицы и мокроступы, но наверное не стоит.

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


ЧТО вы «не знаете как сказать по-русски»?!
есть ли документация, поддержка и обучающие материалы на русском языке?

со смыслом слов «есть» и «нет» затруднения?

или они вам кажутся неудачными кальками глагола 'to be' (are) и английского неоднозначного 'No'?
ЧТО вы «не знаете как сказать по-русски»?!
Комментарий был не в контексте Kotlin'а/Java'ы а вообще программирования.
при этом с точки зрения репутации лучше не иметь русской документации, чем иметь устаревший и кривой перевод с английского


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

Ну может потому и дороже и хуже, что компания Adobe потратила деньги на русскую/китайскую/монгольскую документацию? Вы же понимаете, что за все заплатит конечный покупатель?
и я заплатил — за то, что мне было нужно.
А джетбренс — вместо «выше охвата» потеряли деньги.
Уверен, их очень расстроили недозаработанные 100$ в год.
Уверен, их очень расстроили недозаработанные 100$ в год.


тогда не было модели «подписки», так что не в год

я заплатил что-то порядка 500 $ Адоуби единовременно, софт работает в пределах ветки, лицензия «навсегда»
шизофрения это Вера, что большой бизнес будет действовать против своих же интересов только потому что так захотелось ВАМ.

шизофрения — это аппелировать к «большому бизнесу», который создаёт и поддерживает документацию на русском и никаких репутационных рисков и «ниже охватов» из-за этого не имеет.

Как раз для большого бизнеса никаких «народов-изгоев» нет и не может быть — Google.ps тому пример

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

У меня не «госзакупка», мне просто нужно было какое-то «лицензионное» ПО (с бухгалтерсикими документами).

Я хотел отечественное, ДжетБрейнс сильно не хотели и играли в иносранцев
Причём здесь «текст ошибки», который индус перевёл ПРОМТом?

То есть майкрософт который со штатом лингвистов вполне неплохо перевел текст — это индусы с промптом виноваты? А не то, что современные системы поиска не могут найти англоязычные ответы как решить ошибку "повторяющееся значение ключа нарушает ограничение уникальности" при использовании библиотеки по работе с pdf.


Я говорю о том, что когда в JetBrains русские для русских пишут документацию на плохом английском — это #шизофрения

Они не для русских пишут — а для себя и в паблик в том числе. Да и у себя там не 100% арийцев рускоговорящих. У нас вот например в компании на 50 человек 45 русских. И ничего, общаемся все на английском, чтобы оставшиеся 10% компании не выпадали из процессов. Заодно тренируем язык.

майкрософт который со штатом лингвистов вполне неплохо перевел текст


Я достаточно часто встречал в интерфейсе Windows перлы типа «запись изображения на диск» (подразумевался ISO-образ), не считаю такой перевод хорошим.

Не понял как ваш пример связан с обсуждаемой мной темой.

По-вашему, русскоязычные [потенциальные] пользователи искали бы ответ на свой вопрос (наличие интересующего их русского языка) на английском?
Они что, шизофреники?
По-вашему, русскоязычные [потенциальные] пользователи искали бы ответ на свой вопрос (наличие интересующего их русского языка) на английском?

Я ищу исключительно на английском вопросы и документацию, да.


Во-первых потому что поиск более высокое качество имеет и больш выборка. В гугле вопрос на английском находится в первых нескольких строках выдачи, в яндексе на русском можно перелопатить первые 3 страницы и видеть только вопросы на мертвых форумах с битыми ссылками.
Во-вторых потому что тупо проблемы с терминологией, из-за чего ищется не то. Например Generics — у кого-то это генерики, у кого-то дженерики, у кого-то обобщения. У кого-то ещё как-то. Если я напишу запрос "ошибка обобщения Х" то я не найду ответ если кто-то написал "ошибка с генериками Х".


Про перевод вещей а-ля Stream/Thread/Flow я молчу — тупо "поток потока потока" — удачи найти что-нибудь. Использовали "потоки" и "нити" в поисковом запросе чтобы их разделять? Надейтесь, что и другие люди так же написали, а то гугол не найдет

Я ищу исключительно на английском вопросы и документацию, да


ну вот и потенциальная ЦА шизофренического поведения джэтбрейнз

— u vas est' dokumentatsiya na russkom yazyke?
— yes, off cause! Google for «russkaya dokumentatsiya dlya phpshtorm»!
Доля программистов, которые не сумели в английский (хотя бы на уровне гуглинга и чтения документации) — исчезающе мала, AFAIK. И часть из них — это 1С программисты :) Так зачем тогда ради них стараться?
Вы мне опять рассказываете про какую-то гипотетическую ситуацию. Я а вам — про реальный случай когда погромист с upper intermediate английским купил adobe dreamweaver за 500 долларов и не купил webstorm за 300 сколько он тогда стоил

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

Есть одно но, помимо взрослых есть дети (до 10-12 лет скажем) которым читать документацию на неродном языке сложно, увы, в итоге хотел ребёнка, после Scratch, MinecraftEdu, изучать kotlin (в связке с андроид) Но увы... Именно английский везде его оттолкнул (даже с учётом того что я готов был сидеть рядом и просто переводить всё что написано).

Играл в Dune, Warfcraft: Orc & Humans, первую циву… — никаких переводов не было, и ничего — всё понимал :) Было мне лет 5 на тот момент. До 5 лет играл в русифицированные квестики вроде кирандии.


Наоборот, лучше одноклассников шарил в языке класса до 8го

Вам не кажется что изучение программирования "методом тыка" когда нужно программу печатать буквами которых 20+ и играть в игру в которой всё визуально и надо использовать 10к кнопок с весьма информативными иконками это немного разное....

В игры дети и на китайском играть могут, а мультики спокойно смотрят на испанском и на других языках....

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


и играть в игру в которой всё визуально и надо использовать 10к кнопок с весьма информативными иконками это немного разное....

Ну я вот не уверен насколько тут информативные иконки например… Моя первая игра которую я начал играть в 2-3 года:
image


Как-то в итоге разобрался :)

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

А ведь есть спец версия idea education edition к примеру, там для детей много чего бы подошло, если бы не только английский...

Ну выигрывать игру на самой простой сложности как-то получалось. Видимо, все же не совсем "перелистывание картинок". Есть вполне простой критерий — окно победы.


А ведь есть спец версия idea education edition к примеру, там для детей много чего бы подошло, если бы не только английский...

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

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

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

  3. Я всё же про возраст когда на русском мы уже читаем относительно быстро и не встаём от этого(в среднем это где-то от 8 до 10 лет), а вот на английском ещё никак, при этом ограничения сред типа Scratch уже сильно мешают. (Про отдельных детей которые бегло читают на 2х языках в 6 лет речь не идёт)

А где задавали вопросы на русском? Кажется, в ZenDesk отвечают по-русски на русские вопросы.

Эта история началась в 2010.
Я рад что JetBrains стали чуть адекватнее с тех пор.

маскируются под чехов

Странно. Мне вполне отвечают по-русски. Может ты правда на чеха попал? :)

НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Яндекс, Mail.ru. Во первых это коррумпирует, так как вместо работы по профилю, фирма вовлекается во всякие схемы. Во вторых моральный аспект — платя подписку JeBrains опосредованно поддерживаешь нелигитимный режим


«нелигитимный режим» — это ГДЕ?!

В Чехии, где зарегистрировано юрлицо JetBrains?

Или в нидерландском аэропорту (где прописан yandex zoekmachine)?
Или в Британии и на Кипре (откуда родом MAIL-RU)?
«нелигитимный режим» — это ГДЕ?!

А как же ВШи?

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

image

Рука поднята, головы нет
Сраликов? Который русских вдов и сирот Донбасса обворовал?
Спасибо, НИНАДА
Каждый из продуктов сам по себе неплох — но если вам приходится писать на двух языках сразу (PHP/Python или Python/C++), вы скажете немало горьких слов.

VSCode использует Eclipse Language Srever (через Language Server Proticol). Получается, что и eclipse это тоже умный блокнот?

IDE - это не только LS

IDE это совсем НЕ LS. Например, у сишарпа IDE — Vistual studio, а LS — Roslyn

Развесистая - это пара миллионов строк и больше. Моя ставка - что ближе к миллионам пяти, считая более поздние не-IDE проекты. Поддерживать и развивать такие монолиты - настоящий трудовой подвиг)

А что мешает их делать не как монолиты а как модули/компоненты? Вроде бы как есть экспертиза.

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

Хорошо что для C# есть VS
IDEA у Jetbrains самая взрослая, и меньше багов мешающих работать, в остальных IDE встречаются довольно часто совсем критические баги. Некоторые запросы которые им писались в багрепорт 3-4 года назад до сих пор не выполнены, хотя технически там исправить некоторые можно довольно быстро.
Самая взрослая и самая легаси. Как-то писалось, что скины у них были настолько захардкожены, что темы просто гвоздями были прибиты.

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

3-4 года? Это мелочи. Есть тикеты, которые по 15 лет висят!


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

Бывает так, что технически исправить просто, но не нужно.

Бывает так, что технически исправить просто, но не нужно.

Для непосвящённых звучит, честно говоря, в лучшем случае довольно странно. Можете как-то пояснить на примере?

Такие примеры появляются с завидной регулярностью (говорю про свою подсистему — язык Java). Вот буквально сегодняшнее. Пять лет назад пользователь попросил прокачать анализатор, чтобы он понимал, что метод интерфейса-аннотации никогда не возвращает null. Чтобы при сравнении с MyAnno.value() == null выдавалось Condition is always false. Изменение буквально пять строчек кода плюс тест. Очень просто. Мы сделали. Правда сам пользователь написал:


(technically, annotation.x() can be null, if someone implements FooBar annotation explicitly, but I guess nobody does it).

И вот на днях другой пользователь жалуется, что ему выдаётся ложное предупреждение, потому что "I guess nobody does it" реализуется в некотором фреймворке. А ложное предупреждение — это гораздо более неприятная ситуация, чем отсутствие правдивого предупреждения. Потому что пользователи верят предупреждениям и могут сломать себе код, удалив проверку, которую IDE пометила как ложная. Простой пример фичи, которую не надо было делать, несмотря на то что она простая.

Нет, не такие запросы. К примеру, что в clion нельзя указать toolchain файлы cmake, нельзя указать переменные среды с помощью bat или shell скриптов, во вторых параметры для CMAKE удобно писать в много строчном режиме, в одну строку писать конечно хорошо, но там вмещается всего 2 параметра, и остальные не видно, и не удобно перемещаться по параметрам, ваши разработчики видимо не пишут сборочные скрипты для серьезных проектов? Все это ломает работу с крупными проектами. Понятное дело с простенькими скриптами созданными cmake комфортно работать, но с чем-то крупным нет. Clion жрет память как не в себя, не может проанализировать даже не очень крупные C и C++ проекты, начинает дико тормозить и жрать память, чтобы сделать вид, что эту проблему решили в Clion, просто включили ограничения на размеры файлов и их просто пропускает. Ошибки qt, которые ломают анализатор, автодополнение, кривая поддержка st embedded — у меня даже проекты не открывает. Вроде функционал заявлен, а все глючно. Rider тоже глючный и сыпется на моих проектах. Поддержка wls кривая. Ваши продукты только около веб разработчиков покрывают, кто занимается серьезной разработкой даже не подумают переходить на ваши продукты, потому что капец как все сыро там. Говорю же вы смешные, и отмазки смешные вечно лепите. Как обычно ответ «сам дурак», у нас все круто, у нас миллионы пользователей.
в clion нельзя указать toolchain файлы cmake, нельзя указать переменные среды с помощью bat или shell скриптов

Clion жрет в память как не в себя, не может проанализировать даже не очень крупные C и C++ проекты, начинает дико тормозить и жрать память

Ошибки qt, которые ломают анализатор, автодополнение, кривая поддержка st embedded — у меня даже проекты не открывает

Это вы перечислили проблемы, которые по вашим словам "технически можно исправить довольно быстро"?

За 3-4 года вполне… А вот еще вы мне напомнили, в дебагере clion нет просмотра переменных в бинарном и 16ричном формате, т.е. он есть но в эсперементальном виде и только в 16ричном формате. Когда gdb и lldb умеют все это из коробки, и их использует clion.
Но 200 баксов же вы берете? Это же не VS Code, сделаем когда сделаем.
во вторых параметры для CMAKE удобно писать в много строчном режиме, в одну строку писать конечно хорошо, но там вмещается всего 2 параметра


Это тоже тяжко сделать?
Но 200 баксов же вы берете?

Да, берём. И нам совершенно не стыдно. А что, где-то есть продуктовая компания, которая за 200 баксов вам все желания исполняет? Подскажите такую.


Это тоже тяжко сделать?

Не моя подсистема, не могу знать.

Есть MS, которая дает мне бесплатный Visual Studio. Да, там не все есть, что нужно как в Pro, но все равно можно доставить CodeMaid и Visafora и более менее работать. Я не требую от бесплатного продукта особо много, но тем не менее, он почему-то поддерживает новые версии Blazor с их появлением, а не через 3 месяца.

В бесплатной версии Idea работать нельзя. Соответственно, я плачу деньги. И тут такой вопрос, если я плачу, то почему проблемы не фиксятся годами? Мало плачу? Ну давайте буду платить 999, как за VS Pro. Однако что-то мне подсказывает, что ничего не поменяется.

Вот как всегда в спорах в интернете. Я задал один вопрос, а мне отвечают на другой. Звучит примерно как "Тут благотворительная организация бесплатно бомжам вкусные котлетки раздаёт, а вы продаёте за пятьдесят рублей и не можете фарш качественный накрутить".


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

Супер, оказывается потенциальные пользователи продуктов Jetbrains бомжи, хорошее начало… Что и писал выше, сотрудники Jetbrains смешные и не умеют реагировать на конструктивную критику… В VS Code есть OSS сборка, там нет телеметрии и проприетарных компонентов.

Тут, если не выпадать из контекста, смысл получился как раз таки наоборот: те, кто пользуется бесплатной версией VS - бомжи. А пользователи Jetbrains  возмущаются что им мясо плохо накрутили. ))))

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

Тулчейн файлы можно указать через параметры CMake. В 2021.2 еще завезем поддержку новомодных CMake прессетов. Про параметры среды через скрипты — есть такая беда (мы вместе с платформой думаем пока, как это решить), но кто мешает в самом CMake это все указать?


Память — мы постоянно оптимизируем потребление памяти в CLion, но я замечу, что даже простенький Hello World после препроцессора не такой уж маленький на C++, так что не удивительно, что CLion после сборки информации о резолве кода во всех конфигурациях со всеми инклюдами и ветвями препроцессора отъедает много памяти. Так что оптимизировать там не всегда можно. Но что-то мы уменьшаем постоянно.


Про ошибки Qt — я бы послушала примеры и передала ребятам, они поправят. Честно сказать, уже давно не видела Qt проблем в анализаторе и автодополнении.

Слышал что появление rider это в том числе и результат того что студия просто начала не вывозить весь солюшн решарпера. Что там в IDEA тогда я вообще представить боюсь.
Вот в этом эпизоде подкаста devzen в интервью с гостем подробно разбирается, почему электрон не подходит для построения отзывчивой IDE: devzen.ru/episode-0331 Если очень коротко — потому что в своей новой ide JetBrains собирается увеличить отзывчивость на порядок, приблизив её к «чисто текстовым» редакторам типа vim. И при таких амбициозных планах им с электроном не по пути. Но интервью действительно интересное
Бред полнейший! Поэтому продукты Jetbrains тормозят? Видимо так проявляется более высокая отзывчивость? Собирается, это не значит сделает. Вот вы к примеру собрались из дома выйти, но не вышли и в итоге ни куда не пошли… Если в electron не тригерить часто сборку мусора и перерисовку стилей, то там вполне можно уложится в пару десятков ms. Основная проблема всех платформ это разработчики, в случае electron порог входа ниже и там менее грамотные разработчики, отсюда есть серьезные баги в некоторых плагинах и они медленно работают. Но у IDE тоже не все так хорошо, как вы тут расписали…

В какой-то момент, мне казалось, что языком "как Java, только лучше" мог бы стать Groovy.

alexanderniki а автор Groovy сказал:

По мнению Джеймса Стрэчена[en], создателя языка программирования Groovy, Scala может стать преемником языка Java[5].


Стрэчен покинул проект за год до релиза Groovy 1.0 в 2007 году, а в июле 2009 года Стрэчен написал в своём блоге, что возможно не создал бы Groovy, если бы в 2003 году прочитал книгу Мартина Одерского с соавторами о программировании на языке Scala (вышедшую в 2007 году)[3].
НЛО прилетело и опубликовало эту надпись здесь
В какой-то степени так оно и есть. Просто лучше — это не лучше для всех. Это лучше в определенных задачах. У него есть своя достаточно стабильная, хоть и не очень большая ниша. Я лично его применяю с тех пор как он появился, и до сих пор, и знаю других людей, кто делает тоже самое. И да, это даже не gradle и не jenkins.
Groovy хорош для написания своих DSL, плюс для него есть dsld и сразу получить autocomplete для этого DSL. Единственная проблема — на dsld найти нормальную документацию непросто, такое ощущение, что проект подзаброшен (или просто некому эту документацию делать).
Была задача подключить скриптовый язык близкий к java с пробросом ряда переменных в скрипт. Выбирал между groovy и kotlin, по kotlin нашел описание проблемы, что по сравнению с groovy использование в качестве скриптового языка работает медленно. А groovy зашел на ура, особенно понравилось в нём сборка xml.
Ну еще у груви есть чистый синтаксис, т.е. литералы для списков, мапов, и т.п., билдеры, то есть код получается лаконичный, даже и без DSL. Насчет заброшенности — ну его же реально забросили, хотя потом Apache его подобрали — но какое-то время реально было состояние, что не поймешь, будет когда-то релиз еще, или уже нет.
Когда var в Java появился? А когда зарелизился Kotlin?

Спору нет. Но об этом вот в статье тоже есть.

Скорее new Foo<Bar> ctrl+alt+v, остальное само допишется.

Нет проблемы это дописать. Проблема — потом это читать

Advanced code folding plugin для желающих есть.

У JetBrains, я думаю, одна из самых развесистых Java-кодбаз в мире.

Видимо, вы мало знакомы с развесистыми кодовыми базами. У нас довольно скромно по сравнению с некоторыми компаниями, которые активно используют Java.

Я действительно не знаком с кодбазами больше 1м LOC. Было бы интересно послушать мнение человека более осведомлённого.

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

Мне интересно, угадал ли я с оценкой в 5м LOC для всей кодбазы JetBrains, или 2м LOC общей кодбазы всех IDE?)

Нет, не угадали. Только кодовая база IDE превышает 10M LOC (без комментариев и пустых строк). И, повторяю, у нас ещё скромно.

Вам не кажется) В каком-то интервью говорили

Мне кажется, рывок развития Java в последнии годы во многом был связан как раз с успехом Kotlin. JetBrains заставили Oracle проснуться.
DenisB12 JAVA в топе популярных языков последние 20 лет. Очень много бизнес софта на нем написано. И все это было далеко до kotlin. Язык изначально был с хорошей выразительностью, и быстрой обучаемостью. Синтаксический сахар до контлина еще был в C#.
безусловно. Я не спорю, что Java в топе, и будет в топе еще многие годы. Но это не отменяет того факта, что Kotlin отваевывает кусок рынка Java, особенно в Android-разработке. Да и back-end последнее время всё чаще пишется на Kotlin.
Сомневаюсь, что то так с ходу даже не вспомню какой нибудь крупный и известный проект на kotlin, кроме их IDE. И как правильно выше написали, тому причина проприетарность. Не изучал лицензию, но думаю, там тоже не все гладко для разработчиков.

Apache 2 на компилятор, библиотеки и плагин. Который кстати доступен в Intellij IDEA Comunnity Edition. Как говорится, не изучал, но осуждаю. Тем временем 80% процентов Android уже на Kotlin, куча бекенда на Kotlin https://kotlinlang.org/lp/server-side/case-studies/ (в том числе банки American Express, N26, Tinkoff, etc)


По разным пузомеркам у котлин уже минимум 20% отъедено от джавы. Джава кстати уже не растет последние 3-4 года, а наоборот стагнирует.

По вашей ссылкам там некоторые ссылки, что не используют они, а просто есть биндинги на kotlin для их продуктов))) Как вы всех Android разработчиков или приложения посчитали?)

А я думал там все компании в мире отметились, оказывается нет. Можете добавить IAC тогда в которой я работаю и пишу критикал приложения и аналитику на Kotlin.


Сомневаюсь, что то так с ходу даже не вспомню какой нибудь крупный и известный проект на kotlin, кроме их IDE

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


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

Научитесь делать выводы основываясь на фактах что-ли :)


Как вы всех Android разработчиков или приложения посчитали?)

https://android-developers.googleblog.com/2021/05/whats-new-for-android-developers-at.html


Kotlin: the most used language by professional Android devs

Kotlin is now the most used primary language by professional Android developers according to our recent surveys; in fact, over 1.2M apps in the Play Store use Kotlin, including 80% of the top 1000 apps. And here at Google, we love it too: 70+ Google apps like Drive, Home, Maps and Play use Kotlin. And with a brand-new native solution to annotation processing for Kotlin built from the ground up, Kotlin Symbol Processing is available today, a powerful and yet simple API for parsing Kotlin code directly, showing speeds up to 2x faster with libraries like Room.

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

Как вас батенька разнесло. А был лишь вопрос про то, как вы посчитали Android разработчиков. Вопрос вполне резонный, так как вы сами написали про 80%. Поэтому грамотных людей вполне заинтересует методология. И тут не мало людей, кто хорошо знаком со статистикой, им будет интересен ваш личный опыт, как собирались и анализировались статистические данные. А вместо ответа, начался переход на личности… Но все мимо, на JAVA программирую с середины 2000-х.

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

Java как язык конечно да. Увеличивается ли от этого значительно его популярность или это попытка удержать позиции? Массовый исход огромной индустрии Android разработки на Kotlin будем учитывать? :)


На последнем Kotlin 1.4 Online Event было представлено, что около 5.8млн разработчиков попробовали котлин (редактировали код в IDE), а также около 1.2млн активных пользователей Котлин [https://youtu.be/xJawa3C6pss?t=826]. По статистике самой JB в мире около 6.8млн разработчиков Java [https://blog.jetbrains.com/idea/2020/09/a-picture-of-java-in-2020/]


Это соотношение подтверждается различными рейтингами redmonk/pypl/etc
Или данными на Stackoverflow https://insights.stackoverflow.com/trends?tags=kotlin%2Cjava%2Cgroovy%2Cscala


Есть и другие анекдотические совпадения, так например число людей в сабредите Kotlin [https://www.reddit.com/r/Kotlin/ https://www.reddit.com/r/java/] около тех самых 20%


Откуда пришли эти разработчики? У меня нет четких статистических данных, но на митапах которые мы проводили, опросы показывали что в зале сидят бывшие джависты. Получается джава потеряла большой процент (около 20%) разработчиков за 5 лет, это ли не стагнация?

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

В Android ситуация с Java совсем печальна. Там все остановилось на Java 8. Собственно поэтому Kotlin и выстрелил именно в Android, так как там нет альтернативы.

Вы похоже еще не обновились на Android Studio 4.2

Там уже используется Java 11

Мы, собственно на котлине сидим, поэтому этот момент я не заметил. Но проблема еще и в том, что наше приложение поддерживает Android начиная с 6 (23 sdk), а это java 6. Там еще раньше и с котлином иногда проблемы вылазили, когда в рантайме не находилось нужного класса или метода на старых девайсах. Сейчас вроде такого не было давно, может компилятор подфиксили.

Да, наверно пофиксили. Я пишу под Android начиная с 5.0 - на старых девайсах проблем с использованием Java 8 не замечал.

А ART во всех версиях андроид что используют клиенты тоже до уровня Java 11 обновился с выходом Android Studio 4.2?

Конечно нет. Но уже можно писать код на Java 11 под Android, а то будет ли он вообще работать на старых устройствах или будет заменен на другой код - это другой вопрос.

Моя ошибка — надо было блогпост про релиз ASO 4.2 прочитать. После чтения гугловского блога более подробно — теперь яснее.
Конструкции языка — да, будут работать. Насколько понимаю — на любом андроиде.
Библиотечные API — вообщем все плохо. Как и раньше — работает (на любом андроиде) только то что указано в https://developer.android.com/studio/write/java8-support-table


Ну уже неплохо.

В Android как бы у Kotlin большое преимущество в том что то что вместо JVM(ART) у Android не обновляется почти в плане поддержки новых версий (а даже если бы и обновлялось — у андроида все далеко не хорошо с обновлением системы а значить — привет совместимость. ART хотя бы потенциально обновляем отдельно от самого Android начиная Android 10).
А Kotlin'у на версию JVM плевать вообщем то. Что в данной ситуации — огромное преимущество. Для Android разработки — Kotlin не с вышедшей полгода назад версией Java сравнивать надо а с Java 8 в лучщем случае.

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

Оригинальный автор неправильные выводы делает.
Показателен кусок про
В Java вплоть до 14-й версии это выглядело так:
Скрытый текст
if (x instanceof String) {
    String y = (String) x;
    System.out.println(y.toLowerCase());
}

В Kotlin сделали примерно так:
Скрытый текст
if (x instanceof String) {
  // теперь x имеет тип String!
    System.out.println(x.toLowerCase());
}

Но в Java версии 16+ стало так:
Скрытый текст
if (x instanceof String y) {
    System.out.println(y.toLowerCase());
}
Не дай Kotlin пинка, Java так и осталась бы без фич. А так хоть с «худшего языка» их взяла. Kotlin прокладывает путь для Java, и, очевидно, это сложно. Поэтому и вылезают проблемы, когда Java догоняет обратно
Переходить же с Java на Kotlin будет по-прежнему легко, т.к. уже Java адаптируется, а не Kotlin, идущий во фронтире. Значит новые версии Java всё более будут похожи на Kotlin
Не дай Kotlin пинка, Java так и осталась бы без фич.

Это да. Поговаривают даже, что дженерики в пятую джаву завозил лично Бреслав :)

В жабу внесли плохую фичу. В этом примере — 16+ вариант это синтаксический сахар для варианта 14+, с неявным созданием экземпляра класса, а в Котлине это неявное преобразование типа внутри.
Причём жаба как-то неинтуитивно модифицирует поведение самого оператора instanceof.

Какого экземпляра класса? Вы о чём? Никаких экземпляров не создавалось ни до, ни после.

"y" это что?

Локальная переменная.

String это уже базовый тип?

Удивительно, что люди рассуждают о дизайне языков программирования, не зная этих языков программирования даже в самом минимальном объёме. Я на третьей лекции по Java для начинающих уже рассказываю, что присваивание в Java копирует ссылку, но никогда не копирует сам объект, потому что это никому не нужно и копирование объекта в Java в общем случае неразрешимая задача. Причём JIT-компилятор может и копирование ссылки соптимизировать (и сделает это практически всегда в данном сценарии кода, потому что нет причин так не делать).

Вот я даже картинки из лекций нашёл, где показано, что при присваивании мы ссылаемся на тот же объект и можем его поменять:


Если они таки смогут нормально продвинуть мультиплатформу, то всё будет хорошо

А мне кажется java тоже уйдет на покой. Либо rust победит, либо им придется делать аналогично — т.е. будет +- та же java по синтаксису, но без GC. Т.к. rust сложнее для простых задач, должно появится что-то среднее между rust и java. Конечно это не так скоро будет, но у java уж слишком большой оверхед.

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

Вы ошибаетесь. Rust — универсальный ЯП, хоть и позиционируется прежде всего как системный. Поэтому так медленно и отвоевывает себе рынок. Реально Rust так же интересно использовать в прикладной разработке, как и в системном программировании, если не интереснее.

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

Сборка мусора превращает простые программы в неповоротливых монстров.
Вон, тот же Go это просто нативная Java. И проги на нём жрут оперативки ого-го! Да и мир приходится останавливать на время работы GC.
Вы тут прям собрали в одном сообщении буквально все страшилки начала нулевых…
Так я пользуюсь этими программами, и вижу сколько они занимают в памяти. Зачем мне врать?

У меня есть pet-project на Go, это IoT-сервер с большим REST и WS API, очередями, внутренними кэшами и т.д. Он занимает в памяти 50 мегабайт и работает на Raspberry Pi. Всё, как обычно, зависит от решаемых задач и умении инженера избегать лишних аллокаций.

А у меня pet-project на Расте, это DNS на базе блокчейна. Там DNS-резолвер с кэшем и т.п. Версия без GUI занимает в памяти 2Мб, а бинарник 1,6Мб. А с GUI на базе веб-вью занимает 20Мб и весит 3,5Мб.
Вон, тот же Go это просто нативная Java
Вы простите, но я не верю, что человек, трогавший оба этих языка хотя бы 15 минут каждый, может такое всерьёз сказать. И это даже не говоря об остальном.
Да дело не в трогании, а в использовании. Просто по наблюдениям получается так, что продукты на Go сейчас жрут довольно много памяти, больше чем Растовые, например.

Казалось бы, потребление памяти - далеко не единственный критерий сравнения языков программирования.

А продукты ещё и написать можно по-разному.

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

Помню когда-то давно читал о (почти) рандомизированном исследовании, где программистов пригласили решить какие-то задачи на Си или Яве.


The conclusions showed that Java was 3 or 4 times slower than C or C++, but that the variance between programmers was larger than the variance between languages, suggesting that one might want to spend more time on training programmers rather than arguing over language choice. (Or, suggesting that you should hire the good programmers and avoid the bad ones.) The variance for Java was lower than for C or C++. (Cynics could say that Java forces you to write uniformly slow programs.)


выделено мной

Выжимать скорость надо в нескольких процентах от всегда кода. Самый яркое это разные БД. Там каждый процент ускорения дает миллионы долларов экономии на серверах.

А вот в обычном серверном софте зачем? Ну будет он потреблять вместо пяти десять ядер. И что? Даже по ценам Амазона это все копейки.

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

Где же, блин, язык с RAII и сборщиком мусора? Не хочу руками закрывать файлы.

Справедливости ради, закрываются они не совсем руками, а через всякие "try with resources".


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


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

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

Я лично решаю это тем что классы иммутабельные и для изменения чего-то нужно делать глубокую копию. Кажется что неэффективно, но засчет fearless sharing как раз можно хорошо жить.

Я не в теме: а все стандартные классы тоже иммутабельные? Если да и в библиотеках тоже придерживаются такого подхода, то вероятно проблемы и нет.

Есть стандартный неймспейс System.Colletions.Immutable где есть всё, что нужно.


Многие библиотеки которым позарез нужна иммутабельность (например, Roslyn) используют их по умолчанию

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

Сразу оговорюсь, что в хаскеле я не особо разбираюсь, так что могу сказать глупость, но вижу, что кроме withFile есть и openFile. То есть, можно воспользоваться второй функцией и забыть вручную закрыть файл. Если апи использует RAII, то для этого потребуются специальные приседания.


И как быть если файл у нас вложен в другой объект? Какой-нибудь SomeManager внутри которого содержится ресурс (а может и не один). В деструкторе такого "менеджера" даже делать ничего не нужно. Правильно я понимаю, что в подходе с withХ придётся это всё протаскивать наружу?

НЛО прилетело и опубликовало эту надпись здесь
Так и в плюсах можно случайно вместо #include <fstream> сделать #include <чётосишное> и использовать старый-добрый fopen. Даже приседать не надо.

Я всё-таки больше раст в уме держал: там настолько легко сишные функции протащить не получится. Впрочем, у fstream интерфейс тоже достаточно отличается от сишного, чтобы это не прошто незамеченным.


Насчёт линейных типов и монад: изначально всё-таки речь шла про RAII против языков с GC. Формально, конечно, хаскель и прочие попадают во вторую категорию, но я верю, что там всё сделано достаточно хорошо и интересует как в C#/Java.


чего не было доступно во времена Haskell98, да и сейчас не факт что в хаскеле можно

Насколько я понимаю, все пользуются System.IO "без заморочек"?..


Да не особо. Там, конечно, появляется уровень абстракции в виде всяких управляющих ресурсами монад, но with вам тягать везде не нужно.

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

Насчёт линейных типов и монад: изначально всё-таки речь шла про RAII против языков с GC. Формально, конечно, хаскель и прочие попадают во вторую категорию, но я верю, что там всё сделано достаточно хорошо и интересует как в C#/Java.

так тот же бракет сделано в сишарп/джаве с using/try-with-resources. В этом плане тут паритет

НЛО прилетело и опубликовало эту надпись здесь
Ну withFile на openFile вам случайно заменить тоже не получится.

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


Ну ладно, я согласен, что такие проблемы звучат очень натянуто. С другой стороны, сишники вон тоже говорят, что как можно забыть проверить указатель на null?! RAII всё-таки делает апи чуть проще в использовании.

тем что оно лучше композируется и не требует лапши из коллбеков. Тот же bracket насколько я знаю хоть и решает проблему, но не идеально.


Впрочем, если обмазать API типами достаточно плотно (чего не было доступно во времена Haskell98, да и сейчас не факт что в хаскеле можно), то можно гарантировать статически, что любой openFile будет завершён с closeFile. Опять же, что-то там про линейные типы, про rank-2 polymoprhism, и так далее.

Раии по сути это и есть линейные типы и статическая гарантия что закрытие будет вызвано. По крайней мере если мы про раст.

НЛО прилетело и опубликовало эту надпись здесь
Я затрудняюсь вспомнить, когда мне последний раз нужно было что-то умнее, чем «открыть несколько ресурсов со строго вложенными скоупами».

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


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

Ну раии решает в т.ч. проблему с ошибками во время инициализации/деинициализации.


Да я ж не спорю. Просто вон выше противопоставляется RAII и GC, а при должном обмазывании типчиками одно другому вообще не противоречит.

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

Ну что принципиально она упрощает? Я писал долгое время web-приложения на Java, теперь пишу на Rust. И разницы не замечаю (в вопросах удобства управления памятью). А вот то, что теперь не надо тюнить JVM, чтобы сделать выделение памяти и сборку мусора предсказуемой — очень даже чувствую.

Можно пример того, что вы написали на JAVA и переписали на раст, где вас сильно мучала сборка мусора?

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

Вы пишете полную чушь. Так же товарищ выше писал про Rust. Глубоко сомневаюсь, что вы писали приличные приложения на Java и Rust. Вы сейчас тут распространяете непонятные мифы. Rust не решает проблемы GC и не заменит его! Читайте мой комментарий выше! Rust решает совсем другую проблему! Если вам нужен низкоуровневый доступ к памяти JAVA, то может использовать Unsafe, VarHandle, но вы видимо таких вещей даже не знаете.

Писал только неприличные приложения видимо.


Последний объем кодовой базы составляет порядкм 1mloc, не сверх много, но кмк релевантно. На расте многие вещи менее удобно делать чем на языках с гц, но не на порядок и думаю даже не в разы.

Да ладно? Вы в принце не понимаете даже зачем в Java GC. У многих есть ошибочное мнение, что GC это костыли. Ошибочное мнение. Вы неужели думаете, что C++ и С программисты настолько тупы, и так же создатели JVM, что не смогли до Rust придумать удаление сразу объектов как в C++ или C? Или сделать shared pointer? Такие вещи сделать совсем просто, это примитив, даже мне приходилось такое писать и оверхед там не более 1%. Rust это только оптимизировал на уровне компилятора. GC совсем не про это, GC решает проблему при работу с очень крупными данными, десятками гигабайт и больше, где нельзя просто взять и удалить объект, где создается и удаляется много объектов, что повлечет за собой фрагментацию памяти и скажется на производительности! На маленьком приложении вы в принципе это даже не заметите, а на крупном это серьезная проблема. Плюс алгоритмов сборки мусора существует несколько, и они решают именно определенные проблемы, что подходит одному не подойдет другому. Плюс в JAVA есть интеграция с алокатором ОС, там есть к примеру

-XX:+UseLargePages
-XX:+UseTransparentHugePages


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

Java это в первую очередь не десктоп, и не веб и микросервисы, это в первую очередь обработка больших данных для целей бизнеса! Все проблемы с GC от не понимания принципов его работы, и кривых алгоритмов и программистов, от которых не защищены все языки программирования…

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

Есть ли в Rust MapReduce?

Прям столько всего сразу что даже не знаю с чего начать:)


Да ладно? вы в принце не понимаете даже зачем в java gc.

Ну да, я пишу на жабе/шарпе 10 лет, но не понимаю зачем там гц. Не знаю что пространство ручек гц состоит из по крайней мере 15 тредофов. Не знаю про существование G1,Shenandoah,ZGC и какие у них характеристики… Ничего не знаю, просто фанбойствую по расту :)


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

Скажите, HFT биржи обрабатывают большие данные или нет? Просто любопытно.


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

может и не примут, но я бы поставил что примут. Надо подпилить некоторые вещи. Но при чем тут это не сильно понятно — у линуса проблема в том, что ядру паниковать плохо. А вот в юзерспейсе (где 100% жаба аппов выполняются) это наоборот хорошо — приложение просто падает, а не совершает УБ или молча портит чужую память.


Есть ли в Rust MapReduce?

Нет

HFT биржи? HFT это лишь стиль торговли, а не биржа, высокочастотная торговля, и да мне приходилось писать коннекторы для трейдинга. Впринципе можно писать на чем угодно, сборка мусора не помеха, у меня это было C++и С#. Если вы про Stock Sharp то он жестко кривой, изначально когда я писал своего работа использовал его как основу, но в итоге избавился и написал свое, которое не тригерит так сборку мусора и не копирует объекты раздувая память. Честно говоря мне не понятно за что там берут деньги, проект совсем кривой и тормозной, и по мне коммерческая ценность его 0. А еще у меня не самая плохая математическая база h0tc0d3.github.io/evtools
НЛО прилетело и опубликовало эту надпись здесь
Сразу видно профессионал. Точно совсем никак без GC? А можно уточнит для каких провайдеров данных вы писали коннекторы? Как организовывали риск менеджмент? Какой был у вас коэффициент шарпа по вашей стратегии и стандартное отклонение, максимальная просадка? Можно увидеть аналитику?) Можно было все на C++ писать. Вы меня не поняли писал не только коннекторы, но и платформу для алго. На C# банально проще визуализировать данные, работать с таблицами, графиками. C# биндинги есть даже в западных коммерческих платформах для алготрейдинга, не говоря про несколько российских. Вот они же лохи, чувак же на хабр сказал, что GC плохо и вообще никак нельзя вкорячить. Можно уточить, что вы там на сотни гигов грузите? Данные по объемам? В принципе при конвертации данных и компактном их хранения, по инструменту за последние несколько лет данные занимают не более пары сотен гигов. Для HFT впринципе столько данных не нужно, для HFT важна моментальная адаптация по времени. HFT это принципе не про стратегию на исторических данных, там другой принцип. Ага, чувак написал про хаскель, и сразу можно в боги программирования записывать…
НЛО прилетело и опубликовало эту надпись здесь
CSV медленно, тут вы жестко спалились. С бинарными данными всегда проще работать, плюс они выравнены, с текстом работать это самое медленное. Банально parseInt, parseDecimal у вас будет брать кучу времени, с бинарными данными все проще, плюс можно упаковывать данные практически бесплатно бинарными сдвигами, чтобы уменьшить место и увеличить скорость доступа. Все быстрые коннекторы поэтому передают данные только в бинарном формате, например протокол PLAZAII. Скажу больше, хранение больших данных в текстовом формате, это вообще гремучая смесь для сборщика мусора, и основная проблема очень большого количества программ почему они так жестко тормозят при работе.
НЛО прилетело и опубликовало эту надпись здесь
ЛОЛ. Так вы же говорили про крупные приложения под сотню гигабайтами данных… Да еще чето про HFT пытались писать впринципе не понимая специфику. А сейчас съезжаете… Для HFT даже лаг в несколько секунд много, HFT это быстрый алгоритм, который работает на не эффективности рынка, он просто эксплуатирует более медленных торговцев. Изучайте теорию игр и GTO. На больших данных там не на минуты время идет, а на часы и даже дни, мне приходилось конвертировать большое количество бинарных данных в текст и обратно. Вы никогда не думали почему базы данных все данные хранят в бинарном формате? Ничего сложного с бинарными данными работать, даже значительно проще чем с текстом)))
НЛО прилетело и опубликовало эту надпись здесь
Парсить сотни мегов и даже несколько гигогов логов в секунду вполне реально, но только если у вас нет сложной токенизации и сложной логики лексического анализатора. Даже на JS можно несколько мегабайт распарсить и построить AST за примерно 30мс. Проблема CSV совсем другая, это то, что файлы усыпаны большим количеством чисел, которые надо распарсить, вот это уже очень медленно! Вы мне затираете про rust и тонкие материи, а сами даже не работаете с бинарными данными. Такие смешные… Вы когда нибудь пробовали делать выгрузку и загрузку базы из postgresql в бинарном и текстом формате и замерить во сколько раз отличаются их скорости? Предлагаю вам поставить postgresql и это проверить прямо сейчас и выложить результаты тут. Сами же несете чушь и минусуете впридачу… Ох уж эти крутые программисты на хаскель… Вот так всегда кончились аргументы, и начали минусовать)))
НЛО прилетело и опубликовало эту надпись здесь
Знаете, что означает, что стрелчока вниз здесь не красная, а такая же серая, как и стрелочка вверх? Что я вам вообще никакие оценки не ставил.

Я программист — это фотошоп!

Для тех кто не верит, что в JS возможно парсить быстро файлы и уложиться в 30мс на файлах в несколько мегабайт.
То вот вам бенчмарк github.com/postcss/benchmark CSS парсеров на JS которые строют AST. Сам тоже лично достигал таких скоростей на JS. Расскажите им про GC и медленный JS. Вы в принципе даже не понимаете теорию компиляторов, и что компьютер работает только с бинарными данными, и что работа с текстом одна из самых дорогих операций, а еще минусуете. Сразу видно плохо учились… Вот они наши ясные солнышки и гордость современной компьютерной науки)))

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


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




За последние пару лет мне штук 10 разных контор предлагало писать хфт на расте. Дурачки, наверное, не осилили жабу :)

При правильном написании нет таких проблем и не было впринципе, мне лично удавалось значительно ускорить алгоритмы, только засчет уменьшения хранимых данных и переписать алгорим так, чтобы сборка мусора тригерилась меньше и не было долгих пауз. Мне очень нравится читать блоги jvm и nodejs разработчиков, они там не редко делятся секретами и показывают частые кейсы проблем с производительностью, есть так же среди них выходцы из постсоветского пространства, с ними интересно пообщаться и они принципе даже на письма по электронке отвечают очень охотно. Честно говоря я раньше JAVA и JS считал очень убогими и тормозными, но потом мое мнение резко поменялось, когда мне показали, что некоторые инструкции практически с нулевым оверхедом конвертируются в ASM сравнимый по скорости код, как из под компилятора. Когда начинаешь изучать и лучше уходить в принципы работы JVM, JIT, AOT, GC, начинаешь понимать какое сложное это изобретение, и какие гениальные программисты пишут там код. Ну и в принципе для таких как вы пишут такие книги www.piter.com/product_by_id/227095092. Издательство Питер ph_piter не забудьте мне заплатить за рекламу вашей книги.

Лично не принижаю достоинств Rust и он мне нравится как язык, мне просто не нравится когда принижают Java или nodejs, и не достаточно понимают как они работают. Впринципе в целях highload и чтобы избавиться от GC на их приложениях, не редко просто пишут свой алокатор для JAVA, которые оптимально подходит именно под их задачи, что даже видел лет 20 назад. Благо это все делается легко.
При правильном написании нет таких проблем и не было впринципе, мне лично удавалось значительно ускорить алгоритмы, только засчет уменьшения хранимых данных и переписать алгорим так, чтобы сборка мусора тригерилась меньше и не было долгих пауз.

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


Я более чем представляю, что из ГЦ языков можно выжать крутой перф. Вопрос в том, что не только лишь все это умеют, и что из джавы выжать приличный перф может быть сложнее, чем из раста слепить удобное приложение. Никто не говорит что невозможно — просто дороже, по тем или иным критериям.

НЛО прилетело и опубликовало эту надпись здесь
Так парсинг как раз не проблема, это довольно быстро, медленнее всего работа с AST, оптимизация дерева, к примеру упрощение выражений типа 2+3, и значительно более сложных выражений и конструкций языка, дальше сборка дерева и конвертация в объектные файлы. Те парсеры парсят, строят AST, дальше делают работу с AST, тут уже кому что надо, и потом уже выплевывают измененный css файл, и при желании создают сорсмап. Основное применение это удаление дублирующихся свойств с учетом наследования, проверка на валидность, проверка свойств на совместимость с браузерами, если нет префикса для какого браузера добавляются префиксы и т.д., замена макросов и т.д. Модулями можно написать любой функционал хоть сделать sass и less. Они дают API и строят AST, дальше извращайся как хочешь.
НЛО прилетело и опубликовало эту надпись здесь
1. Preprocessors — Compare CSS processors for parsings, nested rules, mixins, variables and math. Примерно тоже, что 3, но происходит еще разворачивание макросов, миксинов, переменныхи математики, может добавляться большое количество веток дерева, так как некоторые правила разворачиваются в ветки.
2. Просто парсер и постройка AST.
3. Prefixers — Это работа с AST на примере добавления префиксных свойств для браузеров с проверкой по базе совместимости. Т.е. полный пайплайн.
НЛО прилетело и опубликовало эту надпись здесь
Впринципе можно писать на чем угодно, сборка мусора не помеха, у меня это было C++и С#.

Ну да, норм ситуация когда решение нужно принимать за микросекунды, а люди стараются чуть ли не на крыше биржи развернуть компы чтобы снизить задержку, а вы можете себе позволить миллисекундные запуски ГЦ. Понимаю.

Впринципе другого ответа не ожидал, так бабки у подъезда говорят когда прочтут желтушную статью журналистов с хайповой новостью…
Все же вам отвечу. Начнем с того, что размещают ближе к бирже по причине дисконнектов, чтобы в дни высокой волатильности успевали сработать стоп приказы. Не все протоколы и не все торговые платформы могут хранить стоп ордера на сервере, и они реализованы только на ПО клиента. Да и в принципе сами биржи не представляют такой функциональности, только брокеры и их ПО. Поэтому не мало кто торгует с VDS, или заводит несколько провайдеров для балансировки трафика. Решения за микросекунды не надо принимать. Банально у вас не будет объема. Плюс при работе с бинарными данными количество сборок мусора в сотни, а то и тысячи раз меньше. Где используют текст там всегда есть заметные даже на глаз и отклик лаги. При правильной оптимизации их просто нет. HFT не подходит крупным игрокам, опять же не будет объема, а крупные ордера тупо раздуют волатильность и уже не получится купить по нужной вам цене, что сломает риск менеджмент и уменьшит потенциальную прибыль. Мне приходилось общаться с западными программистами из средних компаний, которые занимаются алго, и приципе HFT вообще никто не занимается, в лучшем случае там скальпинг на довольно маленькие суммы. По скальпингу так же как по HFT прибыль сильно ограничена объемом, для крупных игроков это копейки. Поэтому даже сильно вкладываться в инфраструктуру не имеет смысла, она не окупится. HFT и скальпинг это только для маленького игрока, который практически не влияет на объем и может заработать хорошие деньги(для него это хорошие, а для крупного игрока это копейки) медленность крупных игроков. Как только вы начнете своим объемом заметно влиять на рынок начнется адаптация и эксплуатация вас, весь трейдинг построен на подстройке и эксплуатации, кто быстрее видит изменения и быстрее подстраивается тот зарабатывает, и это невозможно запрограммировать. Вообще есть мнение среди алготрейдеров, что чем проще алгоритм тем он лучше зарабатывает. Изначально были только инвесторы которые покупали в надежде получить прибыль, но так как у них крупные обьемы, то столько им продать не могли быстро, поэтому они набирают месяцами и годами позиици. Потом появились трейдеры, которые начали спекулировать на боле маленьких отрезках времени, и начали съедать часть прибыли инвесторов, потом появились скальперы, которые начали эксплуатировать трейдеров, и в конце HFT. Но HFT вскоре практически вымер как стиль, но про него до сих пор ходят мифы и легенды. Игроки начали тоже адаптироваться и эксплуатировать не эффективность других игроков. Сейчас крупные игроки не дураки, они уже прячут объемы и размывают границы цен, плюс специально толкают такие алгоритмы и мелких игроков скупать или продавать в надежде движения, а потом их просто их выносят по стопу, и крупный игрок получает нужный объем по лучшей цене. Вообще все быстрые алгоритмы и алгоритмы маркет майкеров очень жестко выносит в волатильные дни, они жестко начинают быстрые убыточными, поэтому их стараются отключаться. В нормальном алго всегда заложено отключение алгоритма при определенном количестве плохих сделок по времени, или при достижении максимальной теоритической просадки.
при работе с бинарными данными количество сборок мусора в сотни, а то и тысячи раз меньше.

Простите, что?


HFT не подходит крупным игрокам

Простите, чтооо?

Вы плохо читали про объем? Вы никогда не слышали историю про то, как одна довольно крупная компания экперементировала с ВЧ алгоритмам, и благодаря сбою в алгоритме просела за день примерно на 200 миллионов? в итоге они отказались от ВЧ алгоритмов… Даже если на исторических данных алгоритм показывает, что можно заработать, на реальных данных очень часто там будет минус так как на рынок уже оказываете влияние своим объемом. Впринципе объем для HFT необходимый есть во фьючерсе на индекс S&P 500, но там тоже объем где-то на несколько миллионов, а у крупных игроков на миллиарды могут быть позиции. У них большии позиции и к примеру даже 15% годовых для большого количества миллиардов будет лучше, чем 40% годовых от 50 миллионов… Это просто математически не оправдано. Плюс получится так, что впринципе они эксплуатируют сами себя, и переносят свои деньги из одной в стратегии в другую. Им проще делать адаптацию, чтобы не эксплуатировали их, чем вводить HFT. Но я бы его не рискнул торговать, он слишком волатильный — высокая дисперсия, что не вписывается в мою модель риск менеджмента, мне комфортные с алгостратегиями где низкая дисперсия.
Простите, но HFT только своим разработчикам платит зарплату деcятки миллионов в год. Возможно что и сотни.

При прибыльности 50% в год (это очень-очень много, скорее даже нереально много) они должны иметь позиций миллионов на 100 только для оплаты программистов и офисов.
Вы уверены? Вы знаете кого-то из этих гениальных людей? Мне лично знакомо несколько людей из средних компаний, но там нет HFT и они даже не собираются заниматься HFT… Прична озвучана мной выше и кто разбирается в алго впринципе в большинстве будут солидарны со мной. Когда говорят про HFT и Роботов это имхо разводняк полнейший, чтобы кинуть потом инвесторов и домохозяйк...))
Вы уверены? Вы знаете кого-то из этих гениальных людей? Мне лично знакомо несколько людей из средних компаний, но там нет HFT и они даже не собираются заниматься HFT

В смысле знаю? Я и из Нетфликса, допустим, никого не знаю. Но существование кучи разработчиков в Нетфликсе же не вызывает сомнений?

огда говорят про HFT и Роботов это имхо разводняк полнейший, чтобы кинуть потом инвесторов и домохозяйк

Со стороны разработчика какой там разводняк? Вот работа. Работай ее и получишь зарплату о которой заранее договорились.

С учетом сферы выше средней по рынку получишь. Людей идеей не заманить, приходится платить больше.
Там впринципе слошной разводняк, от обучения, до продажи не рабочих роботов, и прочего блудняка. Особено с бумом крипты там особено активизировали всякие мошенники и лудики, которые предлагают свои услуги.
НЛО прилетело и опубликовало эту надпись здесь
Лям на весь отдел разработки?
У вас там как в стартапах, 3 человека и каждый все делает что ли?
НЛО прилетело и опубликовало эту надпись здесь
Чтобы понять порядок расходов компании на разработку.
И дальше прикинуть объем портфеля необходимый для этого. Деньги же надо брать где-то?

Началось все с этого:
Впринципе объем для HFT необходимый есть во фьючерсе на индекс S&P 500, но там тоже объем где-то на несколько миллионов, а у крупных игроков на миллиарды могут быть позиции. У них большии позиции и к примеру даже 15% годовых для большого количества миллиардов будет лучше, чем 40% годовых от 50 миллионов…

habr.com/ru/company/funcorp/blog/558412/#comment_23068348

Прикинув расходы только на разработку можно понять что объемы там точно на десятичные порядки больше.
НЛО прилетело и опубликовало эту надпись здесь
Как причем? Вы неужели не понимаете, что такое волатильность и дисперсия? Впринципе если не знаете, могли бы даже не начинать разговор. Не существует cancel ордеров, существует всего 4 типа ордеров это buy market, sell market и buy limit и sell limit. Все stop ордера реализованы только в ПО брокера, и некоторое ПО брокера может их хранить на серверах брокера, при сработке условия уже на биржу отправляется обычный ордер buy market, sell market, buy limit, sell limit. Даже не все ПО поддерживает их хранение на сервере брокера, это лишь софтовая реализация в клиенте, и при закрытии софта они удаляются, а где на сервере можно хранить там надо включать опцию, что не удалять стоп ордер после закрытия программы. У меня не HFT и не будет, выше прочитайте почему, там нет объема! Где этот чудо трейдер из соседней компании с FPGA железками? Как с ним можно пообщаться и перенять опыт? У меня тоже есть FPGA железки, но они у меня не для трейдинга, а для совсем других задач. Давайте вы не будете лезть туда где вы не разбираетесь и прикрываться соседом, у которого есть мерседес и вы по его словам тут рассказывается… Пусть он тут сам отпишется. Если человек адекватный, то вполне с ним возможно пообщаться, а пока вы просто пишете не понятные мифы. Скажу больше, откройте книги по HFT зарубежных авторов, там многие авторы признают, что HFT никто их них торгует. Впринципе таких как вы мошенники как раз и разводят затирая про трейдинг, чтобы вы им деньги отдали, или вложили в крипту… Все эти супер трейдеры начинают закапываться, когда им задают самые простые вопросы по статистике, по математическому ожиданию, и теории вероятностей, это единственное, что работает в трейдинге и трейдинг подчиняется закону больших чисел.
НЛО прилетело и опубликовало эту надпись здесь
Просто реализовал бы, SELL закрывает BUY, и BUY закрывает SELL. Так же вы можете частично закрыть позицию. Ну еще есть опционы, но это еще более сложная тема и там не работает линейная логика. Знаю товарная биржа фьючерс на сахар, кофе и т.д. А чего же не работаете дальше? Какая стратегия хеджирования у вас была? и что такое хеджирование? Привидите примеры без гугла. Чтобы не разводить тут порожняк совету вам вложить все ваши деньги в вашего друга с HFT, и просто покажите статистику сколько он вам заработал за год, какая были дисперсия, какая максимальная просадка была теоретическая и по факту, коэффициент шарпа или сортино. Темболее сейчас многие ищут людей кто вложится в их торговлю и думаю ваш друг вам не откажет… Знаю не мало случаев кидка среди хедж фондов и сам лично видел на разных ресурсах мошенников, которые пишут легенду, что работают в хедж фонде, готовы вас научить торговле, продать роботов и взять ваши деньги для торговли…
НЛО прилетело и опубликовало эту надпись здесь
cancel есть, речь у меня была изначально про стоп ордера, которые чаще всего программная реализация, это вы написали про cancel. В принципе FPGA могут использовать сами биржы для ускорения отдачи контента, но они решают не проблему задержки, а проблему отдачи большого количества запросов клиентам, fpga позволяют хорошо параллелить и работают изначально асинхронно. В принципе для этого же FPGA используют в гугл и амазон, и для машинного обучения. Для самого трейдинга не имеет смысла их использовать, да и машинное обучение в принципе тоже.
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Неважно на 64-битных системах.

А почему для 64-битных систем это не важно?

НЛО прилетело и опубликовало эту надпись здесь
Бред полный. Проблема фрагментации, не наличии непрерывного куска для аллокации, а скорость доступа к данным! Фрагментация это когда данные разбросаны рандомно в памяти, и вместо последовательного чтения и записи данных, происходит рандомное! Хоть память быстрая, они имеет физический предел скорости(предел в первую очередь вызван удаленностью памяти от процессора, поэтому ее стараются ставить ближе к процессору, но так как это все работает на очень высоких частотах, то реактивное сопротивление даже очень коротких дорожек платы довольно высокое, плюс ЭМС, антенный эффект, и много еще физического мешает развить высокие скорости), вот тут то фрагментация дает о себе знать на больших данных! Поэтому GC кроме сборки мусора, еще дефрагментирует память и двигает блоки памяти для эффективной работы, согласно частоте их использования, возрасту объектов и т.д. Это же есть в ОС, и она это делает в фоне, это же есть в драйвере сетевой карты, и если буфера драйвера сетевой карты слишком большие, то сборщик мусора будет тормозить систему и сетевой стек.

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

Спасибо КЭП. С каких пор кэша процессора равен размеру ОЗУ и может составлять гигабайты и терабайты, чтобы решить все физические ограничения ОЗУ?
Если у вас единичные запросы к памяти это не имеет роли, а если у вас миллионы запросов к памяти? Поэтому используют на больших данных Huge Pages и адресуют блоки большого размера, чтобы уменьшить количество циклов чтения-записи. Это в принципе даже разные вещи и разные проблемы, и разные решения проблем.
Чтобы не быть голословным:
1. Последовательный доступ к памяти
2. Рандомный доступ к памяти
3. Последовательный доступ к памяти, но еще включены Huge Pages
4. Рандомный доступ к памяти, но еще включены Huge Pages

В приципе тут Huge Pages не дают выигрыша, и даже могут быть медленными, все зависит от размера объектов, если у нас много маленьких объектов, то получим на практике замедление, а если много больших, то выигрыш. Поэтому всегда надо понимать с какими данными мы работаем. Что для русского хорошо, для немца смерть…

sysbench 1.0.20 (using system LuaJIT 2.0.5)

Running the test with following options:
Number of threads: 24
Initializing random number generator from current time


Running memory speed test with the following options:
  block size: 1KiB
  total size: 102400MiB
  operation: write
  scope: global

Initializing worker threads...

Threads started!

Total operations: 86360561 (8635349.12 per second)

84336.49 MiB transferred (8432.96 MiB/sec)


General statistics:
    total time:                          10.0001s
    total number of events:              86360561

Latency (ms):
         min:                                    0.00
         avg:                                    0.00
         max:                                    4.69
         95th percentile:                        0.00
         sum:                               224001.99

Threads fairness:
    events (avg/stddev):           3598356.7083/38465.60
    execution time (avg/stddev):   9.3334/0.02

sysbench 1.0.20 (using system LuaJIT 2.0.5)

Running the test with following options:
Number of threads: 24
Initializing random number generator from current time


Running memory speed test with the following options:
  block size: 1KiB
  total size: 102400MiB
  operation: write
  scope: global

Initializing worker threads...

Threads started!

Total operations: 7756804 (775616.10 per second)

7575.00 MiB transferred (757.44 MiB/sec)


General statistics:
    total time:                          10.0001s
    total number of events:              7756804

Latency (ms):
         min:                                    0.00
         avg:                                    0.03
         max:                                    5.03
         95th percentile:                        0.04
         sum:                               238535.76

Threads fairness:
    events (avg/stddev):           323200.1667/2891.61
    execution time (avg/stddev):   9.9390/0.00

sysbench 1.0.20 (using system LuaJIT 2.0.5)

Running the test with following options:
Number of threads: 24
Initializing random number generator from current time


Running memory speed test with the following options:
  block size: 1KiB
  total size: 102400MiB
  operation: write
  scope: global

Initializing worker threads...

Threads started!

Total operations: 86603946 (8659684.88 per second)

84574.17 MiB transferred (8456.72 MiB/sec)


General statistics:
    total time:                          10.0001s
    total number of events:              86603946

Latency (ms):
         min:                                    0.00
         avg:                                    0.00
         max:                                    4.02
         95th percentile:                        0.00
         sum:                               224407.46

Threads fairness:
    events (avg/stddev):           3608497.7500/41590.58
    execution time (avg/stddev):   9.3503/0.02

sysbench 1.0.20 (using system LuaJIT 2.0.5)

Running the test with following options:
Number of threads: 24
Initializing random number generator from current time


Running memory speed test with the following options:
  block size: 1KiB
  total size: 102400MiB
  operation: write
  scope: global

Initializing worker threads...

Threads started!

Total operations: 7765473 (776484.10 per second)

7583.47 MiB transferred (758.29 MiB/sec)


General statistics:
    total time:                          10.0001s
    total number of events:              7765473

Latency (ms):
         min:                                    0.00
         avg:                                    0.03
         max:                                    6.02
         95th percentile:                        0.04
         sum:                               238534.54

Threads fairness:
    events (avg/stddev):           323561.3750/2858.37
    execution time (avg/stddev):   9.9389/0.00
НЛО прилетело и опубликовало эту надпись здесь
Данные из памяти в кэш процессора загружаются страницами, время доступа к любой странице памяти — одинаковое.


1. Данные из памяти в кэш загружаются кэш-банками
2. На NUMA скорость доступа к «своей» и «не своей» памяти отличается, может отличаться сильно

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


1. Данные в кэш загружаются кэш-банками
2. На NUMA время доступа к разным участкам памяти разное (в частности можно управлять выделением памяти в «родной для процессора» памяти).
НЛО прилетело и опубликовало эту надпись здесь

Но память может в какой-то момент и кончиться. Ведь все эти запрошенные страницы где уже почти все умерло так и будут висеть в памяти. Что толку с этих миллиардов гигабайт виртуального пространства если физически у машины даже со свопом её сильно меньше

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

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

Вы не правильно пишите на Джаве. Данные занимают ровно столько же места. Инт, он везде инт. Стринг, он везде стринг. И занимают места одинаково на любом языке.
Пока с битами играть не стали. А это как правило не нужно.

GC требует 10-20% от хипа. На это обычно можно пойти. Оно не слишком дорого стоит.
НЛО прилетело и опубликовало эту надпись здесь
Для Джавы все уже придуманно и оптимизированно.

Нужны почти нулевые stop the world? Берите Shenandoah. Оверхед будет побольше, да и цпу потратите побольше, но ваша апишка почти не будет останавливаться.

Нужна максимальная скорость работы? Берите G1. ЦПУ наэкономите море. Оверхед средний.

Нужно все сразу и лучше без хлеба? Вы попали. Писать руками все, переиспользовать все выделенное по максимуму. Thread Local — ваш лучший друг.
Написать код так чтобы память почти не выделялась можно. Но долго. Для нагруженной обработки в hot path имеет смысл. Для типовой апишки нет.

В типовом случае достаточно просто понимать как разботает gc, где выделяется память и хотя бы специльно не копировать данные по 3-4 раза. Я видел такой код. Чтобы просто передать готовый byte[] по сети библиотечка его два раза копировала.
Зачем? Непонятно. А потом говорят что Джава жрет память.
Согласен с вами на все 100%. Очень сложно объяснить людям, что все проблемы в JAVA и JavaScript и во многих языках, именно из-за безразборного создания объектов, копирования объектов(тут C++ и C, и им подобные с указателями просто выигрывают и программисты хорошо понимают этот процесс, экономят память, в других языках знают про ссылки, но не используют или не до конца понимают) вместо передачи ссылки, работа с текстом очень дорогая, все строковые операции сами по себе очень дорогие, за исключением посимвольного чтения, там от C++ даже разницы в скорости не будет практически, и трансляция практически с 0 оверхедом, но другие операции как раз могут тригерить сборку мусора особенно после циклов, да и сами работают не очень быстро, к примеру в критических участках кода я отказываюсь от regex и replace c regex, и переписываю код на посимвольное чтение и посимвольную работу с текстом, там можно получить ускорения в тысячи раз по сравнению с regex(даже с предкомпиляцией регулярных выражений). Раньше всегда учили, что конкантенация строк в цикле плохо, там создавалась новая копия стрингбуфера, и память утекала, до тех пор пока цикл не завершится, пока код не вышел из контекста, контекст ограничивается фигурными скобками {}, GC не может запустится, в итоге цикл завершается и GC вместо малого количества объектов надо почистить сотни, а то и тысячи объектов, а где-то даже миллионы, такое тоже видел, отсюда к гадалке не ходи будет дикий лаг от GC… Или еще мною любимый антипатер это ресайз масивов…
Да. Я код с диким и ненужным оверхедом видел именно от разработчиков у которых С++ основной язык, а на Джаве им пришлось писать клиентскую библиотечку по необходимости.
Я такое вижу от всех программистов и в большом количестве языков… Очень низкий уровень подготовки к сожалению у людей. Особенно такое часто на JS во фронтэнде, там программистами могут работать врачи и экономисты, да и программисты не всегда понимают как все это работает…

В ряде имплементаций с/с++ 16-битный инт и строки по байту ))) Кстати строки в С++ мутабельные.
Похоже, вы ошибочно полагаете, что цена на GC — это только количество мусора, которое в данный момент в куче лежит и ждет сборщика. Нет, не только и даже скорее не это. Проблема еще и в том, что вы некотрые вещи делать не можете. Если в Си вам нужно вызвать функцию, которая изменяет элемент в массиве, вы можете передать это голым указателем. В Яве вам нужно передать ссылку на сам массив и индекс. Нельзя делать XOR linked lists. Нет value-types. Из-за этого массив каких-нибудь java.awt.Point будет занимать в разы больше места, чем в Си++, при этом НИКАКОЙ игры с битами тут не происходит. Ну, конечно, если заранее известно что в программе много таких данных будет можно хранить их в массиве примитивов и запаковывать-распаковывать по мере необходимости. Можно один массив байтов выделить на все, тогда оверхэда не будет. Но это будет не идиоматическая Ява.


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

В ряде имплементаций с/с++ 16-битный инт и строки по байту )))

16 битный инт это вам еще поискать надо. Под все типовое он 32 битный.

А строки в Джаве идеальны. Они сами знают что в них и занимают один или два байта. Все само оптимально работает.

Если в Си вам нужно вызвать функцию, которая изменяет элемент в массиве, вы можете передать это голым указателем. В Яве вам нужно передать ссылку на сам массив и индекс.

+4 байта параметров это правда такая проблема? Ну пока мы наносекунды не считаем?

Нет value-types

value-types есть. Примитивы называются.
И массивы из них есть.
И даже разнообразные коллекции. Не в стандартной библиотеке, но кому это мешает?

Но это будет не идиоматическая Ява.

Вот тут согласен.

95% кода пишем как красивее и проще. В нем скорость работы не важна. Зато важна скорость разработки и отсуствие багов.

А вот hot path оптимизируем по полной. На него времени не жалко. Он обычно небольшой. Можно и писать медленно и тестировать долго. Все окупается, за счет кратного ускорения всего приложения.

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

GC это свойство языка. Не плюс и не минус. С ним как и с любым другим свойством языка надо уметь правильно работать.

В сишарпе все это можно сделать. При этом такой же гц язык что и джава — просто с чутка другими возможностями.


При чем тут гц-то?

Ну допустим не все из списка, а что-то. Полиморфизм для value types там что-то порезанный по сравнению с с++.
Ну а гц тут при том что его наличие толкает в такую сторону развития языка. Так-то можно и с++/cli вспомнить в котором есть мусосборные указатели и традиционные и (вероятно) наличие 1-го не влияет на
В scala value types есть, но вроде как аггрегрировать в такой объект можно только один value-объект другого типа, остальные будут по ссылке.
А в сишарпе есть value-type arrays?

В шарпе есть и value-type массивы, и VLA на стеке, и много всякой всячины для байтокрутства.

Появилось таки о.о
Как и для байтокрутства там были голые unsafe pointers всегда.
Но эти новые фичи сколько-нибудь широко используются разве? Если там массив на стеке объявить, то будут ограничения, куда его можно передать и существующие библиотеки недружественны к этому?

Можно передавать куда угодно (только не возвращать из функции конечно :) ). stackalloc был в языке по-моему с самой первой версии. Но начиная с 7.2 с ним работать стало куда удобнее: в языке появилась нативная возможность безопасно создавать спаны (это так в шарпе слайсы называются) из них.


Большниство методов стдлибы были переписаны чтобы вместо массивов принимать слайсы (парсинг к примеру). Многие популярные библиотеки сделали так же.


В общем — жить можно.

Про "стринги"

https://m.habr.com/ru/post/134102/

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

Обертки занимают место. Это новость для кого-то?
Не надо миллиард интов хранить как
List<Integer>

Храните как int[]. И никакого оверхеда.
Из базы такие объемы надо грузить руками. ORMу тут не место.

А вот тысячи интов храните как удобнее. Объем в любом случае будет смешной.

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

Только ваша фраза была "Данные занимают ровно столько же места. Инт, он везде инт. Стринг, он везде стринг. И занимают места одинаково на любом языке."

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

Весь код, где в расте будут торчать лайфтамы?.. Сюда же заморочки с DST (просто боксим всё), impl Trait (до этой фичи возвращать итераторы иногда было весьма неприятно). Попадалась ещё хорошая статья почему в расте нельзя сделать do нотацию, но сейчас что-то найти не могу.


Заранее соглашусь, что в некотором "среднем в вакууме" коде это не особо чувствоваться будет.

Попадалась ещё хорошая статья почему в расте нельзя сделать do нотацию, но сейчас что-то найти не могу.

Потому что сигнатура функций не монадическая. Нарпимер у итераторов:


должно быть map : (a -> b) -> f a -> f b
что есть по факту: map : (a -> b) -> f a -> Map f b


Конечно есть "псевдомонады", типа линейные монадки и т.п., то есть можно было рассахаривать как скала — без проверок типов, просто адхоком, но чет не захотели. Наверное потому что у разных типов по-разному называется: где-то flat_map, где-то and_then, ...

Потому что сигнатура функций не монадическая.

А почему?

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

В подовляющем большинстве случаев используется просто lifetime elision.

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

Почему бэкенд не заберет? Использую Rust на бэке много где (кое-где и на фронте), очень удобно. И вообще web-часть в экосистеме Rust значительна и хорошо развита.

Можно узнать название технологии которую вы используете на Rust во фронтэнде? И интересно увидеть примеры кода применения Rust во фронтэнд.

Подозреваю, что речь о yew.

Фронт написан с использованием Yew и компилируется в WASM.

Где это можно увидеть в продакшене?

Пока — нигде.

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


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

Переметнулся? )


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


А боров… он страшен только пока не наберешь опыта и не переключится мозг. Через полгода ежедневного программирования уже его не замечаешь совсем.

это императивный язык по-сути, он сильно проще, чем Scala


Так и скала вполне себе императивная.

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


А если применял — то начинает нехватать rank2, gadt, линз и прочих вкусностей сильных систем типов.


Все познается в сравнении. Ту статью я писал на впечатлениях после сравнения с шарпом. По сравнению с хаскелем все куда грустнее (но офк адопшн получше будет, хотя и не сильно. Но тренд лучше это точно)


А боров… он страшен только пока не наберешь опыта и не переключится мозг. Через полгода ежедневного программирования уже его не замечаешь совсем.

Совсем он не пропадает это точно. Достаточно написать достаточно сложню рекурсивную асинк функцию чтобы пины и лайфтаймы повылазили во все стороны :)

Достаточно написать достаточно сложню рекурсивную асинк функцию чтобы пины и лайфтаймы повылазили во все стороны :)

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

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

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

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


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


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

В скале ООП не больше чем в расте имхо. Если речь не про интероп с джавой, но про интером раста с си тоже можно много чего интересного сказать :)

Такое поведение имеется ввиду?


struct Comment {
    id: u64,
    children: Vec<Comment>,
}

impl Comment {
    #[async_recursion(?Send)]
    async fn walk(&self) {
        let content = get_content(self.id).await;
        println!("{}", content);

        for child in &self.children {
            child.walk().await;
        }
    }
}

async fn get_content(comment_id: u64) -> String {
    format!("Content of {}", comment_id)
}

Полный код

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


fn get_comments(node: Tree<i32>) 
    -> Pin<Box<dyn Future<Output = Tree<Comment>>>> {
 Box::pin(async move {
  match node {
   Leaf(x) => Leaf(get_comment(x).await.unwrap()),
   Branch(x, left, right) => {
    let result = get_comment(x).await.unwrap();
    let left = get_comments(*left).await;
    let right = get_comments(*right).await;
    Branch(result, Box::new(left), Box::new(right))
   }
  }
 })
}

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




Но мой поинт данный код тоже показывает) Я пишу раст с 2017 года, последние пару лет даже в прод. Сижу постоянно в мейне расточатика в телеге, ну и в целом интересуюсь статьями/гайдами… И при этом я вот этот #[async_recursion(?Send)] в первый раз вижу :)


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

Открою маленький секрет: если попытаться скомпилировать мой код без async_recursion, то компилятор скажет


error[E0733]: recursion in an `async fn` requires boxing
  --> src/main.rs:10:26
   |
10 |     async fn walk(&self) {
   |                          ^ recursive `async fn`
   |
   = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`
   = note: consider using the `async_recursion` crate: https://crates.io/crates/async_recursion

Так что в данном случае, наверное, такой код смогут написать почти все, кто вообще дошел до async/.await в Rust ))

Так нам надо не обойти дерево — а сделать второе дерево с той же структурой.


Чтобы просто обойти не надо никакой walk вызывать — достаточно сделать IntoIter и дальше форыч, джоин или ещё что угодно.


Так что в данном случае, наверное, такой код смогут написать почти все, кто вообще дошел до async/.await в Rust ))

Так фишка в том, что я асинк-авейт как раз направо-налево использую. Интересно, в какой версии этот note добавили.

НЛО прилетело и опубликовало эту надпись здесь
(квази-)монолитных
Это мимо. Монолитность можно начем угнодо создать и ява тут непричем

Что-то среднее между Java и Rust в смысле рантайма — это Go.

Оверхед есть, но не большой, там настолько все оптимально, что не все C и С++ программисты так смогут оптимизировать алгоритмы. У меня некоторые алгоритмы работают даже быстрее C++, засчет оптимизации jvm. Rust не решает проблему GC совсем, если вы работаете с гигабайтами и терабайтами данных в любом случае столкнетесь с необходимостью менеджера памяти, и со сборкой мусора и фрагментацией памяти. Все не так просто. Как таковой проблемы со сборкой мусора в JAVA нет, вся проблема, когда создается во время работы много переменных и удаляется, раньше всегда учили, что конкантенация строк в циклах это плохо так как там в цикле создавалась новая копия стрингбуфера и память утекала, вынесение переменных из циклов, и вообще объявление переменных наверху метода, и уменьшение числа переменных, уменьшает количество сборок мусора. Правда сейчас компилятор уже все это решает, и ошибки программистов легко прощаются. Вообще правильная архитектура приложениях в большинстве сводит проблемы сборки мусора на нет. При правильном написании кода и алгоритма количество сборок мусора можно уменьшить в десятки, а то и сотни раз. Например в одном довольно крупном проекте видел просто замечательный антипатерн, создавалось несколько тысяч инстанстансов класса, в классе был массив данных, и самый ужас, при работе это массив активно изменяли в размере. Там алгоритм можно было написать без массива, но главный разработчик не знал базовых алгоритмов. На такой случай есть замечательная книга «Алгоритмы на Java. Роберт Седжвик, Кевин Уэйн». Во вторых есть разные алгоритмы сборки мусора, у всех свои плюсы и минусы, вам стоит лучше с ними ознакомиться, чтобы не вводить людей в заблуждение. Менеджер памяти даже есть в ОС!

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


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

Никто не принижает преимуществ Rust. Это совсем разные языки и в принципе создавались для разных целей, один другого не заменит. Просто было замечание, что в Rust можно столкнуться с такими же проблемами, какой бы язык не был он не решает всех ошибок и проблем программистов. JVM дает удобную платформу для быстрой разработки и развертывания, и сразу имеет в себе решение большого количества кейсов для бизнес задач, и с отлично оптимизированными алгоритмами. В случае rust вам придется изобретать много велосипедов. Если вы не умеете пользоваться правильно памятью, и писать грамотно алгоритмы, то вас даже rust не спасет. Основная разница JAVA программистов от программистов C, С++, Rust, что вторые чаще всего более грамотные. Поэтому в JAVA можно встретить довольно много глупых и примитивных ошибок, которые не сделают вторые. С грамотным JAVA программистом, может даже быть так, что на JAVA приложение будет работать в продакшене даже быстрее написаного на Rust. Плюс скорость разработки сложных приложений значительно выше на JAVA, а потребности бизнеса очень быстро меняются. Это причина почему последние 20 лет JAVA находится в топе популярных языков программирования.
может даже быть так, что на JAVA приложение будет работать в продакшене даже быстрее написаного на Rust
Приведите пример, пожалуйста ;)
Плюс скорость разработки сложных приложений значительно выше на JAVA

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

Дело не в развитой системе типов. JAVA это в первую очередь платформа, инфраструктура и набор решений, технологий для бизнес задач, например Enterprise Java Beans, развиты фреймфорки типа spring и hibernate, есть сервера приложений. Java умеет делать Hot Swap! Есть ли что-то подобное для Rust?

Сравнивать экосистемы Java и Rust сейчас совершенно бессмысленно — у Java она просто гигантская.


Но вот о технологических фичах стоит поговорить: почему какой-нибудь Яндекс пишет добрую половину своих сервисов на C++? Почему не все на Java? Потому что когда начинают считать, во сколько серверов обойдутся фичи Java, все ее преимущества сходят на нет. Но C++ дороже в разработке и поддержке — вот и получается 50 на 50 (грубо). А Rust — он как раз в этой средней точке.

Вы точно уверены, что яндекс не использует Java? А может они не используют еще python? Вы пишете бред полный. Откройте яндекс вакансии. У яндекса куча проектов на многих популярных языках, конечно критический код пишут на C++ или C, и у них есть отдельно люди с хорошим знанием алгоритмов для оптимизации кода, тут к гадалке не ходи. По вашим комментария сразу становится понятно, что вы никогда не имели дело с крупными проектами, и в принципе не понимаете их специфику и какие задачи они решают. Вы пишете просто тут непонятные мифы...)))
Вы пишете бред полный

Я знаю ситуацию изнутри.

Думаю, основная причина — экспертиза существующей команды и имеющиеся многолетние наработки на С++. Дорого не производительность, а миграция и переобучение сотрудников. У Одноклассников практически весь бэкэнд на Java. У Twitter Скала. Нагрузки и там, и там тоже о-го-го.

lany лично по моему опыту язык программирования не так сильно влияет на производительность, значительно больше влияет на производительность опыт и знания программистов. Можно даже на nodejs найти очень тяжелые, большие и быстрые проекты. И вы правильно написали про миграцию, это самое дорогое. Во вторых те же же Java и nodejs можно спрофилировать на рабочем бэкенде с помощью утилиты perf, а дальше критический код переписать на C++ или C.
НЛО прилетело и опубликовало эту надпись здесь
Оно уже давно появилось — Go, отвоевавшись себе весь бэкэнд современный. Как раз в том числе у джавы, которую сейчас всеми силами пытаются облегчить и сделать молодежной современной, чтобы она наконец без стыда могла в контейнерах работать.
Проблема только в том, что GC тормозит. И некоторые большие компании переписывают код с Go на Rust, например как Dropbox переписал код хранилища файлов.

Встречный вопрос: сколько GC вы знаете? Вы в курсе, что их в Java как минимум 4:

  • serial

  • parallel

  • cms

  • g1

У каждого GC есть свои плюсы и минусы. А вызов подходящего GC можно запланировать, сведя "тормоза" практически к нулю - было бы желание и соответствующие компетенции.

Это вы всё про Java говорите. А в Go сборщик мусора всего один и толком не настраивается.

Да, вы правы. Был не внимателен, думал разговор про GC Java. И спасибо за информацию про GC Go, не знал - только начал изучать этот язык.

Не могу понять, какой из этих GC реализует счётчик ссылок

GC занимаются очисткой памяти уже имея информацию для идентификации мусора.

А информация для идентификации обычно создается за пределами GC во время непосредственной работы с объектами. Есть 2 самых популярных алгоритма для этого: подсчет ссылок и выставление флагов.

В Java используется как раз алгоритм выставления флагов. Алгоритм подсчета ссылок используется в некоторых других языках.

Чтобы немного разобраться в этой теме можно почитать википедию: https://ru.m.wikipedia.org/wiki/%D0%A1%D0%B1%D0%BE%D1%80%D0%BA%D0%B0_%D0%BC%D1%83%D1%81%D0%BE%D1%80%D0%B0

Неправда. В Java можно использовать и счётчик ссылок тоже. Но статьи, в которых это описывается, сравнивается, относятся к таким древним версиям JVM, что их и не установить-то уже, наверное, 16-битные ДОС реализации, на 64-битную Windows. И не запустить на Apple M1 версию для Motorola 68k Mac OS Classic. А я хочу счётчик ссылок для современной Java.

Тоже читал что в старых версиях JVM был доступен счетчик ссылок. Думал, что в современных версиях от него отказались полностью, перейдя на алгоритм выставления флагов. Хотя сейчас задумался, а вдруг алгоритм подсчета ссылок не выпилили и его можно как-то включить? Но зачем его включать? Это повысит производительность или решит еще какие-то проблемы?

Что в 90х джава тормозила, что сейчас. Божатся, клянутся, что вот теперь-то мы точно сборщик мусора не тормозящий сделали. А воз и ныне там. Тормозит как чёрт знает что. Диспетчер задач откроешь, и сразу понятно, где у нас трассирующая сборка мусора.

image

В Delphi IDE, угорев по дотнету, добавили дотнетовские компоненты, и оно затормозило. Хорошо, что нашлись умельцы, сделали Delphi Lite, и оно не тормозит, потому что всё, что со сборкой мусора, вырезано. Я сделал вывод: хочешь, чтоб не тормозило — делай без сборки мусора. Только так.

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

Кстати, для Java есть Javolution. Он не умеет инлайнить в JIT и прочее, но он быстр. Уж не связано ли это с тем, что там счётчик ссылок вместо трассировок по свопу?

Но Javolution не поставить так просто вместо java.exe. А было бы здорово, чтоб прямо java.exe ключики в командной строке прописать, и трассирующий сборщик мусора пошёл нафиг.

Расскажете какой трассирующий ГЦ у файрфокса который на 10 табах сожрал мне почти 3 гигабайта памяти?


img

У джаваскриптового движка в файрфоксе разве не трассирующий gc?

У жс движка да, только отключение жс не то чтобы сильно помогало (на тех сайтах где без ЖС хоть что-то работает офк). А остальное там — всё плюсы.


Ну и о чем речь — недавно на расте пробовал писать — хелловорлд гуй с одной кнопкой и канвасом сожрал 300 метров памяти. Никакого гц офк там нет даже близко.

А если бы этот фаерфокс переписать на Яве, сколько бы он памяти требовал бы для работы?
Если вы отключили JS на странице, это не значит, что он не используется в браузере для каких-то внутренних целей. И настройки браузера во вкладке about:preferences с ЖС, а не нативное окошко системы, как раньше...

Забавно видеть, что каждый комментатор живёт в своём пузыре. У вас вот вселенная, где весь бэкэнд на Го.

Прошелся по нашему стеку. Новые бэкэнды пишутся на: PHP, Kotlin, GO и Phyton. Язык выбирается в зависимости от задачи

Так уже… Kotlin/Native, Kotlin/Js.
kotlin/js мало юзабельный. пихает весь код в один файл и чтоб запаблишить его в нпм нужны адске костыли medium.com/swlh/kotlin-to-jar-and-npm-87a5b0ca2dff (с абзаца implementing js specifics). и на него забили почти, за пару лет с момента публикации статьи ничего не изменилось

kotlin/js активно развивается. Над ним и над kotlin/wasm работает отдельная команда (пусть и небольшая). Подробности можно узнать в публичном роудмапе https://kotlinlang.org/docs/roadmap.html

Это изначально был мертворожденный ребенок… Честно говоря, он мне напоминает просто клон scala. Зачем нужен kotlin если есть scala? Не нравится в kotlin, что он некоторые вещи решает за программиста, что убавляет гибкости. В методах тип пишется справа, и еще добавляется двоеточие… Проблема многих языков это лишний символы, которые надо печатать, например begin end вместо {}, и присвоение переменной через <= или +=, $ перед переменной(в шаблонах это нормально), даже с автодополнением на это тратиться много времени. В контлин добавили сокращения, это прям плюс по сравнению с JAVA. Проблема многих языков многобукв! В котлин все убило лишнее двоеточие, и тип переменной справа… Тут у меня сразу вспоминается дико не удобный objective c, с которым Apple хотела поменять отношение к программированию, все закончилось тем что программистов не прибавлялось, и выпустили swift… Лучше синтаксиса С и JAVA нет, они хорошо читаются и хорошо соотносятся с математической логикой, не хватает синтаксического сахара как в C# и dart, например вместо extends просто :. Но как правильно написано JAVA развивается. Скорее всего котлин был выплюнут на рынок в связи с судебной баталией Оракла и Гугла по поводу JAVA, и нужна была альтернатива для Android. Но гугл создал свой язык dart, который имеет хорошую читаемость, гибкость и синтаксический сахар! Большим зло считаю как раз то, что типа справа, человека учат математике и тип всегда слева, и переменной значение присваивают через знак =, извращения на этом пути ни к чему хорошему не приведут. Конечно за это решение можно сказать один плюс, все нестандартное развивает нейроны. Еще проблема kotlin, что они не создали свою виртуальную машину, а просто сделали транслятор в байткод JVM. Язык надо было создавать с нуля со всей стандартной библиотекой. За 25 лет программирования, так и не увидел язык, который был мог переплюнуть своей выразительностью C, C++, JAVA, Python поэтому они и занимают ведущие позиции. И многие языки, которые якобы решают их проблемы, на самом деле добавляют кучу своих…
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
У него довольно чистый синтаксис, хорошо читается, мне нравится, даже написано было несколько проектов, но он у меня не задержался в основных так как там есть вещи, которые в других языках можно было решать несколькими строками кода, в python это решалось значительно большим, при этому некоторые вещи наоборот делаются меньшим. Плюс поведение некоторых стандартных вещей там отличалось от общепринятых.
НЛО прилетело и опубликовало эту надпись здесь
Не могу себе это представить. Это о каких языках вы говорите по отношению к Python?
Не могу представить себе более лаконичного решения любой задачи, чем на Python.
Приведите, пожалуйста, в пример эти нескольких строк кода. Просто интересно стало…

Груви. Причем это далеко не единственный пример

Груви написан на Python? Хм...

Речь вообще не про это была

Вот именно.

>Приведите, пожалуйста, в пример эти нескольких строк кода. Просто интересно стало…

>Груви.

-Петька, приборы!

-15, васильваныч!

-Что "15"?

-А что "приборы"?

>Это о каких языках вы говорите по отношению к Python?
Читать надо весь контекст. А не дергать последние слова

Ну, если вам кажется, что вы выросли из детских ассоциаций, давайте потеребонькаем вашу профдефформацию:
-Linux лучше, чем NT!
-Чем?
-Чем NT!

Большим зло считаю как раз то, что типа справа

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

Тут у меня сразу вспоминается дико не удобный objective c, с которым Apple хотела поменять отношение к программированию, все закончилось тем что программистов не прибавлялось, и выпустили swift…

Кому неудобный? ObjC дико удобен и намного читабельнее С/С++. Программистов эпл всегда хватало, это был единственный язык для их платформ. Им хотелось фич в языке, которые уже было невозможно добавить в ObjC по определению. В своем синтаксисе Swift все такой же сильно отличный от всех остальных с кучей заимствований у ObjC (внезапно, типы тоже справа через двоеточие. Потому что это читабельнее и одна из крутых фич ObjC). Теже лямбды дикость сплошная.

А типы слева это как раз одна из главных ошибок С подобных языков, которые ломают им всю логику парсера. Те самые извращения с указателями на функции в С именно от того такие. Это одна из причин, почему современные языки ушли от этого. Люди таки чему-то научились за многие годы.
А типы слева это как раз одна из главных ошибок С подобных языков, которые ломают им всю логику парсера.
Не могли бы привести аргументы, как происходит эта ломка? Какие трудности возникают у парсера?

Лексер становится контекстно-зависимым, что ведёт к штукам вида lexer hack

Такие вещи можно делать не сложно без извращений с типом справа.

Не могли бы Вы показать какой-нибудь известный Вам пример? Я не настолько погружён в контекст, чтобы найти его самостоятельно, но увидеть это самое "не сложно и без извращений" было бы интересно.

Так это разве мешает C++ развиваться и быстро компилировать? Это только частично упрощает разработку, что принципе нормально для оберточных языков типа Kotlin, где не хотят сильно усложнять язык и сильно вкладываться в разработку, добавить чуть синтаксического сахара, nullsafety и новый язык готов.
Язык в первую очередь должен быть удобен для программирования и не нарушать привычные паттерны, можно сделать совсем радикально и сделать набор кода справа на лево, но это кроме арабов никто не оценит…
Так это разве мешает C++ развиваться и быстро компилировать?

То есть, компилятор C++ сделан "не сложно"? Понял, благодарю.

НЛО прилетело и опубликовало эту надпись здесь
Проблема такая есть, еще лет 20 назад про нее слышал. Но она имхо раздута и преувеличена. Самое главное это никак не помогает kotlin он так же медленно компилирует.
Лучше синтаксиса С и JAVA нет, они хорошо читаются и хорошо соотносятся с математической логикой

Хм, а пруфы будут? Уж по мне, они как раз таки далеки от математики. Вот как мы записываем или читаем выражения в математике? Например, переменная: x ∈ ℕ — сперва имя, потом тип. Или функция: f: ℕ -> ℕ — имя, потом "тип аргумента", потом "возвращаемый тип".


И языки с постфиксными типами выглядят более консистентно. А с префиксными типами всегда выходят костыли. Вот на java:


public class ApiService { // публичный класс "апи сервис"
  private String prefix = '/api'; // У которого есть приватная строка "префикс"
  public List<Item> getItem(int Id) {} // У которого есть публичный список элементов "получить элемент"? А не, тут мы читаем сперва первое слово, потом середину, потом 2-е слово. Выглядит логично?
  public void someMethod() {
    String a = 'b'; // Строка "а", тут нормально.
    var b = 1; // А тут var уже не тип, а специальное слово
  }
}

А на typescript всё уже получше, как минимум всё выглядит логичнее и единообразнее:


export class ApiService { // публичный класс "апи сервис"
  private prefix: string = '/api'; // с приватным полем "префикс" типа строка
  public getItems(id: int): Array<Item> {} // с публичным методом "получить элементы", который на вход принимает id с типом "число" и возвращает массив объектов "Item". Очень похоже на математическую запись. Да и определения читаются всегда слева направо, а не скачут

  someMethod(): void {
    const a: string = 'b'; // константа "а" с типом "строка"
    let b = 1; // переменная b. И выражение с типом, и без него выглядит одинаково
  }
}

В котлине (да даже в том же питоне) же этот пример ещё более консистентен: там явно всегда указывается, что нечто перед нами — функция или же переменная (хотя в питоне для обозначения переменных нет отдельных слов). Но общая тенденция постфиксных типов хороша, а все языки с префиксными типами выглядят костыльно, когда пытаются внедрить type inference, или описать функцию (особенно когда функция возвращает функцию).


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


Еще проблема kotlin, что они не создали свою виртуальную машину, а просто сделали транслятор в байткод JVM.

И в javascript. И в нативный код для разных платформ. В чём минусы-то?

функция: f: ℕ -> ℕ — имя, потом «тип аргумента», потом «возвращаемый тип»

y = f(x)	// вызов функции f

Где тут находится возвращаемое? Возвращаемое находится слева! Значит, и при объявлении функции возвращаемое должно находится слева. Зачем нам такой стиль, что результат надо смотреть то слева, то справа? Надо придерживаться одного стиля. Либо справа налево:
тип f(тип)	// объявление
y = f(x)	// вызов
либо слева направо:
f(тип)	-> тип	// объявление
f(x) => y	// вызов
Где тут находится возвращаемое? Возвращаемое находится слева!

Да нет, оно справа, в самой функции. Не верете? Где тогда возвращаемое тут g(f(x))? Тоже слева? А ведь мы можем рассматривать = как функцию: set(y, f(x)), ведь у нас тут есть и "вызов функции f", и "оператор присваивания", то есть несколько действий.
Тогда слева в записи y = f(x) просто имя переменной, которой мы присваиваем значение справа от операнда (который есть функция от 2-х переменных, просто они в другом порядке записаны). И читаем слева направо. А сигнатуры типов (которых тут нет) читаются также: имя функции, потом типы. Тоже слева направо.

Если быть скрупулёзно точным, то возвращаемое кладётся вместо вызова функции. Ровно в то место, где и был вызов. Например:
g(f(x))			// до вызова f
g(первое возвращаемое)	// поле вызова f, но до вызова g
второе возвращаемое	// после вызова g
В строке
y = f(x)		// до вызова f
после вызова f будет
y = возвращаемое	// возвращаемое кладётся на место f(x)
Но потом операция присваивания двигает результат справа налево. Было бы логичнее эту операцию выразить так:
y <- f(x)
Но исторически сложилось так, что используют символ знака равенства. И получается так, что вызов у нас использует нотацию
y <- f(x)
(справа налево), а вот объявление (в Вашем варианте) — нотацию
f(тип 1) -> тип 2
то есть слева направо. И в этом нелогичность, поскольку символ «=» трактуется как «<-». Вот если бы присвоение делалось слева направо, как в первоначальных версиях языка Рапира
b + c -> a;		// слева — вычисляемое выражение,
			// справа — имя перезаписываемой переменной
то Ваш вариант был бы логичен.

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

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

Одно из больших преимуществ типа справа — синтаксическое разделение аннотаций на переменной и аннотаций на типе. Смотрите:


@Anno
var x : Int // аннотация на переменной

var y : @Anno Int // аннотация на типе

А теперь Java:


@Anno
int x; // аннотация фиг знает на чём

Я занимался поддержкой type-аннотаций в Java. Это лютейший ад. Осталось ещё много багов. А главное как ни сделаешь, всё равно недовольные найдутся, потому что это сломано изначально.

Хорошо, а зачем лишнее двоеточие? Можно было бы его выкинуть. Для токенизатора и лексера это наверное упрощает парсинг, но можно легко обойтись без :.
Меня всегда убивало, что в языках программирования ради парсинга исходников добавляли дополнительные символы, например в R дико не удобно использовать <= для присвоения значения, pascal go :=, где-то помню было +=. Зачастую подобные вещи просто убавляют читаемости.

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

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

У меня тоже немало. Для меня var: Type легче читать, чем Type var, несмотря на то, что я пишу в основном на C++.

Допустим, при копировании/мёрже/другим причинам, в нашем коде на stylus похерились отступы. Вы сможете, глядя на код, сказать, что будет на выходе?


body
    font: 14px/1.5 Helvetica, arial, sans-serif;
  #logo
    border-radius: 5px;
      .foo
   color: red

Вот и онлайн-компилятор не смог. Причём, меняя отступ, код то появляется, то снова ломается парсер. Например, вот такой код


body
    font: 14px/1.5 Helvetica, arial, sans-serif;
  #logo
    border-radius: 5px;
   .foo
    color: red

Компилируется в такой css


Сможете угадать в какой, не заглядывая под спойлер?
body {
  font: 14px/1.5 Helvetica, arial, sans-serif;
}
#logo {
  border-radius: 5px;
}
.foo {
  color: #f00;
}

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


Есть некая грань, начиная с которой уменьшение "мусорных" символов ухудшает ситуацию, а не улучшает. Stylus как по мне — отличный пример этого.

Как эти инструменты относятся к неоднозначности синтаксиса языка? Ну вот выровнял я код автоматом по отступам (при коммите, например). Но, получил вместо того, что я хотел:


body
  font: 14px/1.5 Helvetica, arial, sans-serif;
  #logo
    border-radius: 5px;
   .foo
    color: red

Вот это:


body
  font: 14px / 1.5 Helvetica, arial, sans-serif;
#logo
  border-radius: 5px;
.foo
  color: red

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

У вас code review запрещен на работе?

В нормальных проектах:

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

2. Есть автоматические системы проверки репозитория на соответствие правилам оформления кода. Если у вас где-то пробелы вместо табуляции, или у вас 4 пробела вместо 2, это сразу покажет. Это же покажут линтеры при загрузке конфига с проекта, и нормальный редактор загрузит c проекта автоматически editor config, чтобы форматирование производить по правилам.

3. Есть автоматические системы сборки и тестирования, чтобы быстро отловить кривые коммиты и их отклонить.

Вы уходите от ответа, (вопрос был: в чём плюс языка с раздолбайским синтаксисом, если из-за этого синтаксиса могут внезапно вылезти ошибки) и начинаете переходить на личности. Да, у нас запрещёны под страхом увольнения с позорной записью в трудовую и линтеры, и код ревью. Это хотите услышать?


Ещё раз, простая ситуация: я написал стили, проверил, что всё работает как задумано. У меня по какой-то причине (случайно нажал пробел) перед коммитом добавились лишние пробелы в stylus-код. Код при коммите отформатировался автоматом ([sarcasm]хоть у меня на проекте это и запрещено, но я смелый[/sarcasm]), но не так как я задумывал, так что в плане стиля кода всё ок. Так что


  1. У вас не примут коммит, если вы не придерживаетесь правил форматирования и оформления кода

Мимо. Ревью кода проверяет не правильность выполнения задачи (ждя этого есть тестировщики), а именно правильность написания кода. Зачем вы упомянули методологии и бем, вообще не понял.


Далее, код попал в систему сборки. Она тоже ничего не нашла, ведь код пришёл отформатированный, соответствующий всем настройкам линтера. Так что пункт 2 тоже пройдёт мимо.


Проект собрался, тестировщики заняты. В проект накидали уже много других коммитов, в сборках уже будет трудно найти косяк (да и как это поможет), но кривые стили всё ещё лежат, готовые выстрелить.


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

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

2. У вас код кривой и это сразу глазами видно, что не соблюдены отступы. Плюс редактор на него ругается! Видимо у вас майтенеру глаза выкололи и вы работаете по старинке в блокноте?

3. Видимо по вашему мнению миллионы пользователей python, стоит заметить, который входит в топ 5 языков по пулярности, настолько тупы, что у них все на отступах и они программируют на нем? По некоторым рейтингам python занимает 1 и 2е место. Мне в python лично не нравится только отсутствие строгой типизации, отчего там с производительность не все хорошо. В остальном он практически идеален.

Если честно не сильно понимаю чем "нажал пробел случайно перед коммитом" отличается от "случайно нажал точку с запяток после цикла перед коммитом". И то и то просто не происходит в реальности.


Скопировать же текст из непонятного источника с непонятным форматированием — неужели у вас правда такие проблеым возникают? Код на том же SO всегда отформатирован, даже если вы просто копипастите его то вам достаточно выделить кусок кода и нажать там (шифт таб) нужное количество раз чтобы поставить его на место.


Наконец, некоторые проблемы могут быть действительно из-за динамической природы языка (ваши стили вряд ли компилируются). Но если например такой подход применяется в компилирующемся языке то почти всегда у вас будет ошибка компиляции. Haskell/Scala3 и некоторые другие делают именно так.


Как раз переход Scala3 на бесскобочную запись вызван тем, что там проще читать код. в сколько-нибудь приличной компании в 100% случаевкод отформатирован и так, тогда зачем писать скобочки? Вот и оказывается, что незачем. Так же и точки с запятой по большому счету не нужны, в 2021 году слава богу люди соблюдают правило "1 действие на строку" (кроме мб сишников). И смысла точки с запятой чтобы можно было писать i++; j++; в одной строке нет — так никто не пишет.


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

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

Скобочки "не там" нужно 2 поставить.
Хотя честно говоря я месяц назад при мердже вместо того, чтобы грохнуть лишнее начало цикла вставил лишний конец. Потом удивлялся.
Ну и я не представляю как вы ребята копипастой занимаетесь между разными уровнями. IDE разбирается?

Скобочки "не там" нужно 2 поставить.

Уже давно IDE закрывающую скобку сама автоматически ставит например. Так что не надо.


Ну и я не представляю как вы ребята копипастой занимаетесь между разными уровнями. IDE разбирается?

tab/shift + tab для выравнивания на нужный уровень. А внутри сниппета код отформатирован в 100% случаев. А достаточно умная IDE да, сама разбирается, когда у неё есть текст которй вставляетяся по позиции N то она все строки сниппета сдвигает на эти же N.

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

для изменения логики программы из-за "лишнего таба" есть тесты


а автоматически закрывающие скобки можно отключить в нормальных IDE

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

скобка менее заметна чем лишний отступ

Сомнительно. Скобку видно сразу, а 12 там пробелов или 13 на глаз врядли сразу сходу можно заметить.

Откуда у вас 13 пробелов возьмутся? По-вашему отступы пробелами в каком-нибудь виме руками набивают?

Извините, я не понял ваш вопрос.
12 пробелов — это третий уровень при 4 пробелах на уровень. Случайно нажать пробел не в том месте — и его врядли сразу заметят.

Ну вот поставил я пробел не в том месте: https://rextester.com/XALAV6976


Получаю ошибку:


1632113399/source.hs:5:4: error:
    parse error on input ‘let’

Каким образом я её случайно не замечу?

Это ide заметило что что-то не так, а не вы. А ide может не всегда такое заметить.
Я же изначально писал про "видно глазами".

Я согласен на то что "иде заметит за меня", как она делает с 99.99999% остального кода что я пишу, когда проверяет то что я в переменной не опечатался, что не написал List там где ожидается Array. Особенно если это экономит 2 строчки кода вертикального пространства за каждый блок.

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

то есть вот это


while (cond)
  foo();

совсем не сломается если записать так


while (cond) {}
  foo();

?

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


В вашем примере кстати ему разве не подчеркнет лишние две скобки с предложением вставить пропущенную точку с запятой?

почему в крупных компаниях очень любят stylus

Разве он не вымер? Мне кажется его доля на рынке в районе нуля. Хотя судя по Google Trends он ещё чуть-чуть барахтается.

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

Это вполне нормально. Когда язык обрастает конструкциями и меняет сильно облик, то его становится значительно сложнее поддерживать. К примеру в Clang еще не полностью поддерживается C++ 20, а некоторые вещи портят производительность. Поэтому многие языки не редко переписывают с нуля и переход всегда болезненный. К примеру, за 15 лет perl даже не решились выпустить perl 6, в итоге люди разделились и выпустили как отдельный язык raku. Видимо побоялись участи python.

И языки с постфиксными типами выглядят более консистентно. А с префиксными типами всегда выходят костыли.

А меня наоборот ломает когда тип в конце. Когда я читаю код (а читать его приходится чаще чем писать даже если это твой код) мне важнее тип переменной чем её имя. Это настраивает на понимание того что там дальше.

Как я читаю Java:

переменной целого типа по имени N присвоить результат выражения;

Как приходится читать Kotlin:

переменная N ...ХРЕНАКС!!!ТИП!!!... блин, чо там было-то?...

С функциями ещё хуже. Задалбывает искать возвращаемый тип когда много аргументов. Самое главное - то что функция вернёт, а уж потом список аргументов. Мы же идёт от цели к способу её достижения. Значит возвращаемое значение - самое главное и оно должно быть в начале! Тут модификаторы немного портят малину, но это "стандартные слова", в них мозг не "вчитывается", а берёт целиком.

С написанием то же самое: "так, мне нужен метод, который вернёт Стринг, а из чего он его сделает - а вот из этого".

Хороший пример - перечень элементов. Надо писать сначала существительное, определяющее элемент, а потом всё остальное:

  • Конденсатор электролитический, ...

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

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

Ну, можно возвращать Object или интерфейс, или дженерик. Возможно, в других языках можно ещё как-то извернуться. Но в любом случае, конструируя функцию, я сначала думаю что она делает. Делает => Возвращает => Что возвращает? Какой тип?

И этот ход мысли ломает объявление типа где-то там, в подвале.

Ну даже с переменными. Сначала объявляем, потом присваиваем. Т.е.:

"Мне нужна переменная, ага... А посчитаем мы её так..."

Можно и так записать: 1 + 2 = int n; (наверно где-то можно). Но это будет ломать принцип "сначала цель <== (потом средства)"

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


Проблема многих языков это лишний символы, которые надо печатать, например begin end вместо {}, и присвоение переменной через <= или +=, $ перед переменной(в шаблонах это нормально), даже с автодополнением на это тратиться много времени.

Java: extends/implements вместо простого ":", ага.


Тут у меня сразу вспоминается дико не удобный objective c, с которым Apple хотела поменять отношение к программированию

Objective-C #History:


  • Objective-C was created primarily by Brad Cox and Tom Love in the early 1980s at their company Productivity Products International (PPI).
  • In 1988, NeXT licensed Objective-C from StepStone (the new name of PPI, the owner of the Objective-C trademark)
  • After acquiring NeXT in 1996, Apple Computer used OpenStep in its then-new operating system, Mac OS X.

Т.е. это одна из первых попыток скрестить С и ООП. Apple его взяли как готовое решение.


Скорее всего котлин был выплюнут на рынок в связи с судебной баталией Оракла и Гугла по поводу JAVA, и нужна была альтернатива для Android.

Google LLC v. Oracle America, Inc.: Prior Oracle Am., Inc. v. Google Inc., 872 F. Supp. 2d 974 (N.D. Cal. 2012);


Kotlin (programming language): First appeared July 22, 2011


человека учат математике и тип всегда слева, и переменной значение присваивают через знак =

В школьной математике типы вообще не пишутся. Это так, к слову. Порядок присваивания тоже никто не менял. А тип слева — наследие семейства С/С++, которое ещё и усложняет парсер и грамматику. Если вы пройдётесь по современным языкам, у большинства аннотации типов именно справа.


мог переплюнуть своей выразительностью C, C++, JAVA, Python

Выразительность языка — грубо, отношение "количества смысла" в вашем коде к количеству этого самого кода.


Python

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


Java

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


C

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


C++

О да. Его пожалуй можно назвать выразительным. Но до появления С++20 обратной стороной этой "выразительности" были километры write-only шаблонного кода, порождавшие такие же километры ошибок.


Вообще же, довольно неплохо видно, что именно наличие сильного конкурента подстёгивает развитие. Активное развитие Java пошло именно в последние годы, когда у неё появился сильный конкурент Kotlin. Активное развитие С++ (выпуск нового стандарта каждые три года) началось, когда его начали активно заменять на другие языки во многих нишах, где С++ исконно доминировал.

Такое чувство, что вам не нравится язык только из-за типа справа. Но ведь это малая издержки крутой фичи с неизменяемыми переменными Val var.

Что мешает писать final?

Динозавр детектед.
Я уж думал, что люди, кидающиеся на котлин, вымерли к 2021 году, а оказывается нет.
Человеку не хочется на старости лет становиться учеником и он будет постить портянки текста, высасывать что-то из пальца, цепляться за старьё себе же во вред, только чтобы прикрыть этот элементарный факт. Но мы то видим, откуда ветер дует… )
Ого! У моего поста есть красный счетчик выживших динозавров!
Это удобно. Заодно и посчитаем.

Сломаю статистику — не динозавр и с сутью сказанного в общем и целом согласен, но минуснул за раздувание конфликта.

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

Очень спорный аргумент. Новые фичи Kotlin также тщательно обсуждаются в рамках KEEP. А на счет "продуманности", скорее наоборот =). В существующий синтаксис Java сложно что-то добавлять, не ломая что уже есть. Посмотрите доклады Тагира (https://www.youtube.com/watch?v=qurG_J81_Cs) про то как встраивался pattern matching.
К тому же все, что появляется в Java никак не мешает Kotlin. Data class можно использовать с record. Как выйдет Valhalla то value классы тоже можно будет использовать.


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


Думаю, что в будущем Kotlin будет больше позиционироваться как Java 2.0, поддерживая все новые фичи, что появляются в Java и добавляя новый функционал поверх. Возможно в какой-то момент и настанет критическая точка что Java разойдется сильно с Kotlin, но ничего не мешает тогда появится Kotlin 2.0 c поддержкой миграции всего и вся из Kotlin 1.0. Kotlin ведь не Java, он может себе позволить куда более критичные изменения.

Использовать data class с аннотацией @JvmRecord имеет смысл только для interop, ИМХО, иначе это какое-то знатное извращение получается)


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

Ой, не уверен. Есть плохой пример Python 2 => 3, было больно и грязно. Golang упорно держится за версию 1.x, потому что понимает, что версии 2.x придётся отчаянно сражаться за аудиторию, и при этом останавливать работу над 1.x тоже нельзя.

Сейчас появился еще один пример, Scala 2 => 3. Можно посмотреть что у них получится и сделать правильные выводы =)

НЛО прилетело и опубликовало эту надпись здесь
А расскажите, в чем боль и грязь перехода python 2 -> 3?
Лет 10 работаю с пайтоном и впечатление, что более плавного и нативного перехода представить сложно

В том что они, внезапно, несовместимы намного сильнее, чем синтаксисом print

Э, а где вторая половина комментария :(

НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Есть плохой пример Python 2 => 3, было больно и грязно.

У меня сложилось впечатление, что проблема была скорее в интерпретируемой природе питона. Т.е. для плавного перехода требовалось, чтобы один интерпретатор понимал оба диалекта, умел различать файлы на разных диалектах в одной программе и умел их комбинировать. В случае с компилируемыми языками (в машинный или байткод) это тоже может быть болезненно, но не в такой степени. Если сильно припрёт, можно работать в сторону совместимости на уровне межмодульных бинарных интерфейсов. Тогда скомпилированные модули версий языка 1.х и 2.х вполне могут жить вместе. Пример этого — взаимодействие модулей одной программы, написанных на разных языках, через C ABI. Сложно, да. Но не неразрешимо. А в случае с питоном вы в принципе не могли бы скрестить в одном месте условную Django для 2.х и условный Numpy для 3.х.

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

Кстати, их не то, чтобы совсем сложно распарсить. Это на самом деле protobuf, proto-файлы находятся в репозитории Kotlin. Их можно аккуратненько скопировать себе и сгенерировать код, который парсит данные. Там остаются кое-какие нюансы, которые можно узнать, почитав код компилятора Kotlin, но в целом задачу "прочитать метаданные Kotlin" я в своё время осилил.

На андроиде до сих пор Java 1.7 (или 1.8 c оговорками), поэтому новые фичи джавы мы увидим ну очень нескоро, в отличии от котлина, который есть здесь и сейчас.
мы увидим ну очень нескоро

Если вообще увидим. Котлин стал стандартом уже в мобилках.
А те, кто писал на 7 и 8 java не успеют апгрейднуться до 16+, потому что в kotlin уже всё это есть.

Не знаю как вы, а я уже 2 года работаю на Android с Java 1.8, а в последнем обновлении Android Studio 4.2 подвезли Java 11

Но под капотом у вас все-равно используется API Java 6 (если только не используете minApi 26). Языковые фичи новой версии языка заменяются на этапе работы D8. Расширение "стандартной библиотеки" до восьмерки только через отдельные "костыли" от Гугла (ссылка)

Возможно. В работу D8 я не погружался. Я про то, что исхолный код пишу с использованием стандартов Java 8 (лямбдами, функциональным программированием и т.д.), а скоро начну использовать новшества Java 11. А то, какие костыли используются при компиляции мне не важно. У меня компиляция идет меньше 1 минуты.

Вставлю свои 5 копеек, почему Kotlin может быть хуже Java


  1. Нет адекватной замены annotation processors. В Java процессоры подтягиваются в IDEA и когда я жму build, они автоматом запускаются и (пере)генерируют нужный код. Если меняются классы, на которые смотрит процессор, то мне не надо запускать какую-то специальную тулзу — я просто жму run на нужной run configuration и магия сама работает. Конечно, из-за того, что Sun (а теперь Oracle) в своё время не продумали возможности работы с IDE, которая инкрементально запускает javac, это в редких случаях ломается, но в целом всё в разы лучше, чем в Kotlin, где единственная альтернатива — вручную запускать kapt.
  2. Скорость работы компилятора. Сколько бы не говорили про то, что она приближается к работе javac, на деле там отставание не в 3 и не в 5 раз, а раз в 10-20. Это на реальном коде, с которым мне приходится работать, а не на каком-то синтетическом примере, для которого приводят бенчмарки для сравнения скорости компиляторов. Конечно, Kotlin умеет компилировать инкрементально, НО! Инкрементальная компиляция часто ломается во всяких интересных случаях (например, когда Kotlin модуль зависит от Java модуля, в котором сделали совсем небольшое невинное изменение).
  3. Производительность сгенерированного кода. В подавляющем большинстве случаев это вообще не является проблемой, но есть специфические сценарии, где производительность важна и даже на Java пишут в C-стиле (потому что оптимизатор JVM слишком туп), и порой то, как генерирует код kotlinc, так же вносит свои 10-15% в снижение производительности. Особенно это важно для сред, которые плохо умеют в оптимизацию и имеют слабое железо (Android). Например, все JVM-декларации функциональных типов объявляют параметры Object и возвращаемое значение Object. Поэтому даже если функциональный тип в конкретном use site параметризован non-null kotlin.Int, мы всё равно наступим на boxing.
  4. Nullability в некоторых случаях мешает. Например, мы можем какое-то время иметь частично инициализированную структуру, но потом мы в какой-то момент её достраиваем и точно знаем, что что-то — гарантированно не null. Java вообще никаких гарантий не даёт, так что все такие вещи делаются на уровне комментариев, документации в коде и т.д. Kotlin даёт гарантии, при этом!!! считается как бы дурным стилем и его принято стараться избегать. В этом ключе описанный мой случай приводит либо к обилию использования этого самого !!, либо к злоупотреблению lateinit, который может давать странные эффекты.
  5. Отсутствие package private. Тут всё неодназначно, потому что в Java отсутствует internal, а порой его так же не хватает (но есть всякие OSGi, которые в каком-то смысле решают эту проблему).
  6. Правило final by default. Конечно, про это уже 1000 раз говорили, для spring написали модуль, для jackson тоже, так же для Kotlin написали allopen. Однако, всё же всплывают то тут то там какие-то проблемы. Я понимаю благородные намерения авторов языка, однако, тут сложно сказать что лучше — сделать, как правильнее или как совместимее.

Короче, мне, как разработчику, не слишком интересно, запишу я код метода в 3, 5 или 10 строк. Мне важно, как удобно со всем этим будет работать в связке с другими инструментами из экосистемы Java. И у Kotlin с этим, пусть всё и хорошо, но не на 100% безоблачно.

1. github.com/google/ksp + время от времени всплывают обсуждения АПИ для плагинов, которое бы работало с IDE. То есть, в каком-то обозримом будущем улучшения в этом вопросе будут
2. Компилятор переписывается. Не уверен, что декларировалось что старый компилятор приближается по скорости к javac. В докладах признается отставание и рассказывается, что с новым компилятором будет лучше, например тут www.youtube.com/watch?v=GEqgkaiBPdA

upd. Про АПИ для плагинов mobile.twitter.com/relizarov/status/1387833892497932297

Первое упоминание об IR появилось году так в 2017-м, когда его запилили для нужд Kotlin Native. С тех пор команда плавно переписывает все бэкэнды на IR, параллельно этот самый IR допиливая. К тому времени, как Kotlin 1.5 будет с нами и как все бэкэнды окончательно переделают в IR, и когда этот IR стабилизируется и появится стабильное же API для работы с ним из плагинов, и всё это ещё аккуратно поддержат в IDEA, вот тогда и поговорим (сколько ещё ждать, год, два три?). Тогда я признаю, что одной проблемой в Kotlin меньше. А пока мы имеем дело с тем, с чем имеем, и пункты 1 и 2 заставляют меня не переходить на Kotlin в тех проектах, где эти пункты являются критичными.

Хм, но ведь Kotlin 1.5 уже с нами (: Вместе с IR бэкендом для JVM. Но а так, да, очень многие проекты/улучшайзинги в стадии разработки, это немного огорчает. Я вот дождался Compose для ПК, теперь сижу и радуюсь. Надеюсь новый компилятор и вас порадует поскорее хд
Поддерживаю. У Jetbrains так во многих продуктах. Себя каким-то бета тестером чувствуешь.
Вроде все супер с одной стороны, начинаешь работать, всплывают косяки, которые мешают работать или просто убивают работу. Вот к примеру взял свой проект на C# решил перенести на Rider, сыпет ошибками, работать не возможно. В CLion добавили qt и embedded для st, открываю qt проект статический анализатор не работает и сыпет ошибками, автодополнение не работает, открываю проект st, он открывается, но CLion его не может распарсить, компилировать, отлаживать не возможно, редактировать нормально C++ файлы тоже, так как не смог служебные файлы распарсить.
  1. Вообще в IDE все настраивается и с kapt. Но в целом да, альтернатива annotation processors нужна и пока планируется что это будут компиляторные плагины.
  2. Она медленее, но не в 10-20 раз как вы говорите. Работы по улучшению постоянно идут и новый большой скачек будет с релизом FIR.
  3. Но местами можно и быстрее написать. Есть inline, tailrec, корутины. С боксингом действительно можно напороться, но это, пожалуй, единственное.
  4. Мешает он, как правило, в тех местах, когда делаются такие хаки, как вы описываете. В таких местах можно вполне жить с!!! или чем-то аналогичным. Но зато nullability расширяет систему типов значительно упрощая код.
  5. Есть такое, но в планах писали что package private появится.
  6. Нет идеального решения, к сожалению. Final by default правильней, но исторически в java все было open и много существующих инструментов используют это.
Вообще в IDE все настраивается и с kapt.

Можно ссылку? Просто я с ходу не нашёл. А для IDEA вообще ничего не надо настраивать — она сама при импорте проекта из maven/gradle обнаруживает annotation processors и подключает их.


Есть inline, tailrec

Никогда не понимал смысла в оптимизации хвостовой рекурсии. Есть же нормальные циклы. Это, конечно, очень увлекательное упражнение для ума — переписать всякие map/filter/fold на чисто функциональном языке, где циклов нет и нет ленивых вычислений, так, чтобы они были tailrec. Ещё было в студенческие годы не менее увлекательно написать библиотеку функций на SK комбинаторах. Однако на практике я вообще не встречал ни единой ситуации, когда написать функцию с хвостовой рекурсией было бы более просто и наглядно, чем написать банальный цикл.

В IDEA нужно только включить "Enable annotation processing" и все должно работать точно также как в Java (так как механизм используется точно такой же). По крайней мере у себя я не помню, чтобы что-то дополнительно настраивал. Проект с gradle. Единственное что все gradle, kotlin и IDEA самые свежие. При запуске build запускается и annotation processing.

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

Для того, чтобы утвержать такое, надо вначале определиться, что мы называем ФП, потому что какого-то единого чёткого критерия нет. Если мы договоримся, что среди наших критериев есть ленивость, то да, с данным тезисом я соглашусь. Однако можно долго спорить, включать ли критерий ленивости в определение ФП. Всё-таки Ф — это про функции, а не про ленивость (иначе бы у нас был ЛП). А так получится, что только Haskell можно назвать полноценным ФП, а какие-нибудь OCaml или SML идут лесом.

НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Про производительность есть и обратная сторона, когда код, сгенерированный kotlinc будет более оптимальным, чем javaс. Примеры:
  • Наличие inline-функций. Тот же forEach на коллекции в kotlin будет заинлайнен в байт-коде, вместо вызова метода в Java.
  • Java-путь для null-safety(Optional) вообще создает доп. обертку над полем/переменной. В Koltin же null-safety реализовано по-человечески, на уровне компилятора.
Насколько я понимаю, JIT умеет инлайнить. Не во время компиляции, ясное дело. Ну т.е. в итоге возможно разницы в оптимальности (после прогрева) не будет.
либо к злоупотреблению lateinit, который может давать странные эффекты.

Какие эффекты? Либо оно работает, либо у вас случится UninitializedpPropertyAccessException там же, где раньше случалась NPE.
НЛО прилетело и опубликовало эту надпись здесь

Да условному синьёру не сложно выучить Kotlin. Может, он его уже отлично знает. Просто оказывается так, что из-за ряда факторов Kotlin вместо того, чтобы увеличивать эффективность сеньёра, снижает её. Лично для себя я просто выделил кейсы, когда Kotlin помогает, а когда мешает, и использую или не использую его в конкретной ситуации, исходя из этого понимания. Речь о том, что Kotlin на данный момент не может покрыть 100% (или даже 90%) ситуаций, когда он был бы однозначно лУчшим выбором, чем Java.

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

Ах этот призрачный null-safe. В проекте java и kotlin, вместо NullPointerException начинаем получать в рантайме Fatal Exception : что-то must not be null.

А чем Fatal Exception: что-то must not be null в рантайме хуже NullPointerException (без подробностей) в рантайме?


У меня в синтетическим примере передача null в метод который не ожидал null в Kotlin даёт ошибку java.lang.NullPointerException: Parameter specified as non-null is null: method package.Class.method, parameter output и в ней видно и полное имя класса+метода и имя параметра.
В Java-же обращение к методам переменной, содержащей null, возвращают java.lang.NullPointerException без текста и только по трейсу можно узнать имя класса, метода и строку в исходниках — а переменную нужно угадывать самому. И только с JEP-358 включённого в Java 14 будет писаться имя null-переменной.

включённого в Java 14 будет писаться

Не будет писаться, а уже пишется! Java 14 больше года назад вышла =)

Да, "уже".
Только в проде обычно используются LTS-версии и хорошо если там вообще Java 11, а не Java 1.8.
И в андройде есть только 1.8.
И исходный вопрос был про то что "так ли один райнтайм эксепшн хуже другого рантайм эксепшна?".

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


Кстати, у JetBrains есть инструментатор для NotNull-аннотаций, который тоже делает более понятные сообщения типа "java.lang.IllegalArgumentException: Argument 1 for NotNull parameter of Scratch.test must not be null".

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

Потому что иногда тяжело прогнуть бизнес на изменение версии JVM на проде, тогда как код на Kotlin компилируется под 1.8 со рассматриваемыми фичами.


Ну про Андроид не говорим.

Потому что там именно такой вариант?

Потому что там именно такой вариант?

Нет, потому что в случае с Андроидом я с вами согласен. Там действительно без Котлина совсем тухло.

Всё нижесказанное IMHO.
Я, как джавист с 13-ти летним стажем, конечно предвзят, но когда я вынужден смотреть/править код на Котлин (в одном из наших проектов его активно форсят вместо Java, а в другом я активно сопротивляюсь этому) мне становится невыносимо приторно от этого бесконечного сахара.
Совершенно не интуитивный синтаксис некоторых вещей. Синтаксис Java строг и прост: если вызов функции, то должны быть скобки и не важно, есть у вас там лямбда или нету, если конструктор, то у него только такой синтаксис, а не primary/secondary/с ключевым словом constructor/без ключевого слова. И т.п.
Вообще не понимаю этого подхода — «давайте сократим всё! меньше букв! заменим всё символами! function — слишком длинно! fun/fn или ещё короче надо!», особенно в условиях, когда код за тебя давно пишет IDEA, а для лёгкого чтения кода как раз таки должны быть нормальные слова, чтобы легко читать код как текст (а не как какой-то шифр). Компилятор и редактор Котлина безбожно тормозит в IDEA (sic!) по сравнению с оными Java.
Стандартная библиотека в Котлине хороша.
НЛО прилетело и опубликовало эту надпись здесь
Да наверняка привычка, я с этим не спорю.
Я не согласен с «как Java, только лучше». Не лучше.
Scala, всё-таки, это другое (с)

По поводу Google vs. Oracle, насколько я понимаю выиграл Google.

Если теперь Android получит полную поддержку текущего Java API (11 или новее), то будет ли смысл писать Android приложения на Kotlin в будущем? Выбор Kotlin для Google возможно был отходным путем, если бы они проиграли суд.

Распространение Kotlin за пределами Android (и самой JetBrains) под большим вопросом, не очень понятно, например, зачем backend разрабы станут тянуть еще одну технологию в проект, когда преимущества не очевидны.

Ради эксперимента, два года назад я попробовал ktor.io и SQL Exposed для небольшого проекта на бекенде и не увидел ощутимых плюсов. Наоборот, из-за того, что фреймворк тогда еще активно развивался каждая попытка обновиться до новой версии ломала проект, Exposed тоже был очень сырой. Плюс как разработчик я бы писал код быстрее и качественнее на более знакомой Java. Хоть проект и закончил, но желания использовать ktor где-то еще больше не возникало.

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

Возможно кто-нибудь помнит, как Google позиционировал Dart когда они только запустились? Насколько я помню звучало это как похороны JavaScript. Но как в последствии мы увидели, JavaScript даже не заметил Dart и за пределами Google (возможно и внутри) язык не получил распространения до того момента пока не запустился Flutter. Возможно тоже как путь отхода от Google vs. Oracle. И будущее Flutter тоже не очевидно.

Поэтому ощущение будто Kotlin останется языком для разработки JetBrains и возможно Android, до тех пор пока Android не решит поддержать последние версии Java.

На мой взгляд, сейчас единственным драйвером распространения Kotlin является Android и если Google вдруг решит, что теперь Android first язык и Java тоже, то прирост новых разрабов будет сокращаться.

Я согласен с выводами в статье и еще бы добавил, что один из вариантов развития это искать партнерство с какими-нибудь крупными компаниями (возможно даже университетами) кроме Google.

Update: помните как Scala была на волне популярности, а потом ее вообще перестало быть слышно? Правильно ли будет сказать, что с добавлением в Java 8 возможности писать функциональный код, Scala как-будто начала отмирать.

Насчет похорон JavaScript не было такого, они как альтернативу продвигали, так как JS костыль на костыле, и фундаментальные его проблемы не решить не переписав язык, про это говорили разработчик v8, что они столкнулись с кучей проблем на пусти оптимизации JS движка, и многие вещи не возможно решить из-за обратной совместимости. В dart перешла команда лучших и опытных разработчиков из v8, чтобы создать ООП язык легкий для изучения как JS, но не имеющий его фундаментальных проблем, и по мне они справились со своей задачей. Язык приятный для программирования и довольно продуман, жаль что не так популярен еще, но популярность растет благодаря flutter, и гугл на нем уже делает не мало проектов своих.

Ставку на Dart в 2012-2013 году делали большую. Даже добавили в Chromium mode в котором можно было писать на Dart нативно, без компиляции в JavaScript. Я даже не очень помню, была она с самого начала или ее добавили потом. И еще обещали включить поддержку в релизную версию Chrome (разве не звучит как заявка на похороны JavaScript? =D). Но этого не произошло и они даже сделали официальное заявление, что поддеркжи Dart в браузере не будет.

По наивности тогда мне казалось, кто если не Google, но по факту они воскресили Dart только с вместе Flutter.

Продвинуть в другие браузеры dart было сложно, и видимо они побоялись, что язык не такой популярный, добавление нового движка усложнила бы разработку и поддержку chromium. Лично не оставляю надежду, что все же dart сделают как замену JS, или сделают нормальную альтернативу JS без костылей. Лично написал не мало на JS(Даже PNG картинки генерировал на JS) хорошо понимаю разработчиков dart и почему они решились на такой смелый шаг.
НЛО прилетело и опубликовало эту надпись здесь
Почему, про него тут пишут. Не так часто, ну так и новостей особо не много. Scala 3 пожалуй основная новость, и ей было посвящено несколько обзорных статей. По-моему их автор где-то тут отметился.
НЛО прилетело и опубликовало эту надпись здесь
Ну, смотрите — мне как Spark разработчику эти новости вообще не интересны. Подозреваю что таких как я немало. Это не мешает нам скалой в целом интересоваться.
>Scala как-будто начала отмирать.
Есть такое. Java 8 сняла многие ограничения, и упростила многие вещи.

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

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

НЛО прилетело и опубликовало эту надпись здесь
Ну почему сразу не надо? Получилось хорошо (я не много знаю аналогичных продуктов такого масштаба). Не без недостатков, это да.

У вас на картинке Джава и Котлин подписаны наоборот: Джава же более древняя, а Котлин — молодёжь.

НЛО прилетело и опубликовало эту надпись здесь
>И проблемы как бэттер джава у него будут те же.
Ага. Ну разве что ниша возможно будет другая. Как-то несколько лет назад я уже задавал тут вопрос в статье про котлин — а чем, собственно, он лучше того же груви? Заменяем груви на скалу — и получаем тоже самое. Это другой язык, со своими преимуществами, и своими недостатками. Часть из них тут перечислены. Часть из перечисленных — для кого-то вполне возможно недостатками вообще не являются, как и часть преимуществ для кого-то не являются преимуществами.

Чуть условный пример — у котлин в теории лучше с null. Это если забыть про то, что нам нужно взаимодействие с Java, или с другими языками на платформе JVM. Откуда к нам может прибежать нулл все равно. И никаким способом мы при компиляции это не проверим вообще. Нуллы на уровне байткода — это фича JVM, а не Java. Решит ли ее еще один язык на той же самой JVM? По мне — так нет. Если у меня в проекте есть не только легаси код на Java, но еще и JNI/JNA — дает ли мне эта фича котлина что-то полезное? Не факт, нужно попробовать и оценить, весьма вероятно что нет.

Так это, все манипуляции с null сделаны с одной целью: проверки на null в compile time при условии, что идёт работа котлина с котлином. Ни о каком null safe вообще везде речи и не идёт. Поэтому да, если у вас проект на джаве, то у вас будут проблемы с null в тот момент, когда вы начнёте добавлять котлин. Со временем же, когда нового кода на котлине станет больше, проверки уже будут выполняться в compile time, в этом и основной смысл. Насчёт JNI/JNA чутка не понял. Если код для того же JNI уже написан на джаве, то получаем взаимодействие котлина с джавой, если на котлине, то получаем взаимодействие котлина с котлином, тем самым сводя ситуацию к ситуации с исходным интеропом

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

Да, всё так. Я лишь привёл пример, когда "эта фича котлина даёт что-то полезное" - при работе котлина с котлином (ещё есть работа котлина с аннотированный джава, но тут уже польза чуть более субъективна)

Я поясню — не имелось в виду, что она не дает ничего. Я привел пример ограничений, когда у вас ваш кусок на Java (на самом деле неважно на чем) написан не вами. А скажем это JavaEE контейнер, или там JDBC драйвер. Который слишком большой, чтобы его переписывать или заменить, и одновременно важный для проекта. В итоге у вас нет и не будет проверки во время компиляции для этого куска. И на котлин вы его тоже вряд ли перепишете.

А, ну если не имелось, тогда всё ок, ограничения действительно есть, тут не поспоришь

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

Ну скала из той же жвм корзинки, но при этом система типов у нее +- уровень хаскеля (причем в каких-то вещах даже мощнее)

НЛО прилетело и опубликовало эту надпись здесь
Ну, давайте я попробую с нуля пояснить, как я вижу проблему. В JVM на уровне байткода есть нуллы. Пусть у нас проект написан на чем угодно, любой язык, со сколь угодно мощной системой типов. Но при этом используется компонент, ну для простоты пусть будет JDBC драйвер, проприетарный, от Оракла, или скажем от MS. И он нам при каких-то условиях может вернуть нулл.

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

Ну и пусть есть язык с мощной системой типов. Мы на нем пишем. И у нас по прежнему есть часть проекта, написанная на языке с менее мощной системой типов. Что мы тут можем сделать самое полезное, считая что наш язык все может, а вызываемый компонент нам для модификации недоступен?

И никаким способом мы при компиляции это не проверим вообще

Неправда. Джаву можно помечать всяческими @Nonnull/Nullable, и это прорастает в котлин.

Вы правда не видите разницы между проверить автоматически и попросить программиста поставить аннотацию?

@NonNull
private String foo() {
   return null;
}

А еще вы (и походу в комментарии чуть выше) почему-то считаете, что вся ваше кодовая база состоит из вашей Java и вашего Котлина. Что наверное бывает, но скажем у меня обычно процентов за 50 составляют сторонние пакеты, которые а) не аннотированы, и никогда не будут б) тоже умееют возвращает нуллы. Впрочем, хватит и одного такого — скажем, поставьте мне аннотацию на JDBC драйвер от оракла (любой проприетарный jar, на самом деле)?
@NonNull
private String foo() {
   return null;
}

ССЗБ.
а) не аннотированы, и никогда не будут б) тоже умееют возвращает нуллы.
Прекрасно, в котлине они видны как platform type («String!», например), вы можете проверять их на null, и дальше компилятор будет понимать, что тип нуллабельный. Никакой проблемы в этом нет.
>ССЗБ
Ну, если это мой код — то где-то да. Но я человек, и мне свойственно ошибаться, и не только мне. И эта аннотация — по сути не более чем @Мамой_клянусь_тут_не_будет_нулла. Вы серьезно считаете, что она что-то гарантирует?

И тот факт, что это может быть jar от вендора — вы игнорируете?
Нет, я верю, что варнинги в IDE и проверки на CI спасут отца русской демократии.
Поэтому я не верю в jar от вендора, в котором есть аннотации, и в то же время настолько тупые ошибки. Но, в целом, если вы об этом знаете, это можно починить отдельно.
>Но, в целом, если вы об этом знаете, это можно починить отдельно.
Я в принципе совершенно с вами согласен. Но — у меня есть такой jar. И я даже примерно знаю, где ошибка. Но проблема в том, что кодовая база этого jar-а где-то на порядок больше моей собственной. Если не на три порядка. У меня два с половиной человека пишут, а там 1662 контрибьютора. При этом они про баг знают — но чинить не хотят. Поскольку workaround есть, условия появления нулла понятны, и мы умеем их избегать, то так и живем. А вот чинить продукт — ну его нафиг. Хотя был бы он чуть поменьше, или времени чуть побольше — возможно и починили бы.

Ну в общем, это я о чисто практической стороне дела, против аннотаций-то я ничего вообще не имею. Да и против котлина тоже.

Идейка поддерживает внешние аннотации в xml-файлах. Котлин их тоже поддерживает. В принципе можно аннотировать сторонние библиотеки из интерфейса IDE и шарить аннотации вместе с проектом. Мы в исходниках IntelliJ IDEA этим пользуемся. Внешние аннотации для JDK поставляются с самой IntelliJ IDEA.

Ну я бы тут так сказал — это может быть большая работа, эффект от которой не очевиден. Особенно если внешние библиотеки (как в моем случае) сильно больше, чем наш собственный код. Ну т.е. я не возьмусь аннотировать JDK или спарк, для примера. И кстати, скала вообще в этом плане поддерживается?
Кстати, перестановка местами типа и имени переменной… не кажутся хорошими идеями.

Это прекрасная идея, которая позволяет изящно опускать тип и дать type inference делать его работу.

Это скорее не то, чтобы прекрасная идея, это back to roots. Потому что в своё время странная идея "а давайте писать тип переменной перед её именем" под влиянием языка, который (по другим причинам, а не из-за этой идеи) стал популярным, пошла в массы. Кажется, до народа дошло, и новые языки как раз возвращаются к нотации, появившейся чуть ли не раньше компьютеров (например Kotlin, TypeScript, Rust, Swift).

Ну, я не говорил, что они это изобрели:)

И первое время я плевался "что за паскаль тут развели", а потом как понял... Котлин продуманный язык, мне он этим нравится.

Ох уж это паскалефобство

Фобство это боязнь;)

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

Синьоры стали синьорами не потому, что все свои 10-15 лет в индустрии потратили на изучение синтаксиса и идиом конкретно взятого языка. Они изучали такие вещи как:


  1. Несколько других языков, хотя бы на базовом уровне. JS, чтобы что-то на фронте быстро подправить, не дожидаясь фронтэдеров (а то и вообще стали сами full stack). C++, чтобы написать performance critical код. C#, потому что в своё время успели на несколько лет переметнуться в .NET.
  2. Обширный набор фреймворков и библиотек для языка (стандартная библиотека Java, Spring, Hibernate, Jackson, log4j и т.д.)
  3. Базовые алгоритмы, структуры данных, паттерны, архитектура корпоративных приложений, объектно-ориентированный дизайн, принципы (SOLID, YAGNI, KISS, причём умение их использовать/не использовать на практике)
  4. Хотя бы общее знание предметной области (не одной).
  5. Инструменты для разработке на языке: отладка, профилирование, сборка, развёртывание.

Что приходится из этого проапдейтить при переходе с Java на Kotlin? Синтаксис. Ну может пару библиотек специально для Kotlin написанных посмотреть (ktor, exposed). Ну может научиться подключать модули к Spring, которые нужны для облегчения жизни Kotlin-истам. Ну просмотреть быстренько стандартную библиотеку Kotlin, увидеть, что она почти один-в-один является подмножеством стандартной библиотеки Java, плюс несколько расхождений (Sequence вместо Stream), плюс горстка удобств. Ну какие-то идиомы, которых нет в Java. Профайлеры те же. Отладчик тот же. Maven и Gradle те же. Поверьте, человеку с опытом в 10-15 лет в отрасли, всё указанное не так долго изучить. Вот перейти с Java на C++ или с Java на Python сложно. С Java на Haskell ещё сложнее.

Всеми руками поддерживаю. Не редко тут можно встретить, что люди считают себя сениор разработчиками, когда знают весь синтаксический сахар в своем языке программирования и стандартную библиотеку, а при этом пишут медленный код и допускают довольно серьезные ошибки. А по факту сеньором делает только знание алгоритмов, умение их реализовать и скомпоновать. Мне лично без разницы на чем писать, первостепенен всегда алгоритм. С или С++ знать надо всем разработчикам, некоторые алгоритмы довольно лаконично решаются именно на них, и с ними приходит понимание как работает компьютер, и почему некоторые вещи работают медленно.
Data-объекты могут быть заменены более богатым функционалом record

Что? Каким функционалом? Private модификаторы для полей, неявное наследование от базового класса, остуствие copy метода, невозможность добавить instance variables и это более богатый функционал?
А дискуссия в комментариях тут в целом напоминает «у меня тут свой комфортный Java мирок, а для всего остального я придумаю тысячу аргументов, почему Java круче».
Кстати, а корутины когда подвезут в Java? А хотя зачем они, можно же докопаться до всего.
В целом просто удивительно, как люди независимо от сферы в большинстве своём, закрыты к чему-то новому и всячески пытаются нахваливать то, к чему они привыкли.

Пожалуйста, чуть-чуть полегче. Тут такая джентльменская дискуссия, не испортите её.


Невозможность наследования и добавления instance-переменных я считаю плюсом records, благодаря этому они больше отвечают семантике "я строка в базе данных/элемент в очереди". Употребить слово "богатый" наверное было неправильно, скорее "строгий".

благодаря этому они больше отвечают семантике "я строка в базе данных/элемент в очереди".

ИМХО, data классы и record-ы совсем не для этого были созданы. Как раз для строк в БД очень редко нужна специфическая семантика equals. Лично я считаю, что data class нужны ровно в двух ситуациях:


  1. Объявить иммутабельные штуки вроде Color, Vector2/Vector3, Rect, Point, Complex и т.д.
  2. Объявить кастомный составной ключ для Map/Set в случае, если Pair/Triple по какой-то причине не устраивают.

Собственно, поэтому мне на практике приходилось использовать data class-ы ОЧЕНЬ редко. Не понимаю, почему все бездумно лепят модификатор data на всякие DTO и entity (особенно на DTO)? Потому что есть ассоциация "данные == data"?

Дебажить print'ом удобно :)

Собственно, поэтому мне на практике приходилось использовать data class-ы ОЧЕНЬ редко.

Использую их постоянно, потому что
Объявить иммутабельные штуки

Мутабельные данные — отличный способ отстрелить себе задницу, ящитаю. Ну а раз в любом случае это будет POJO с final-полями, то отчего бы не обмазать его префиксом data и не получить сахарок в виде copy-метода?
Мутабельные данные — отличный способ отстрелить себе задницу, ящитаю.

Ахаха, вы это скажите сотрудникам Kotlin team, которые ловеринги пишут не путём "я пересоздам все IR элементы от рута до текущего элемента", а путём старого доброго изменения мутабельного свойства. Думаете, они там дураки сидят, которые не знают всех преимуществ иммутабельных данных и не могут в ФП? Боюсь, если бы они делали IR иммутабельным, kotlinc работал ещё раз в 100 дольше, чем он работает сейчас.


Ну а раз в любом случае это будет POJO с final-полями, то отчего бы не обмазать его префиксом data и не получить сахарок в виде copy-метода?

Так если это иммутабельный класс, то бога ради. Я просто вижу, как на вполне мутабельных расставляют. Впрочем, в Kotlin не всё так хорошо с иммутабельностью. Вот вам маленькая задачка от меня. Что выведет следующий код?


fun main() {
    val trollList = mutableListOf(1)
    val a = A(foo = trollList)
    val s = mutableSetOf(a)
    trollList += 2
    s -= a
    println(s)
}

data class A(val foo: List<Int>)
Думаете, они там дураки сидят,

Я думаю, что при выборе инструментария надо думать головой, а не упомянутой задницей. Для разработчиков Kotlin team важно выжать максимум перформанса, поэтому они переиспользуют объекты, чтобы снизить нагрузку на GC, но берут на себя сложности управления мутабельным состоянием. Мне важно иметь стабильный код без волшебных багов, поэтому я использую иммутабельность. Problems?

Что выведет следующий код?

Ничего удивительного для человека, который знает, что переменная в котлине — это ссылка на объект, а параметры передаются по значению. Умение сломать японскую бензопилу не означает, что валить лес надо топорами.
Если честно, ни в самой статье ни в комментариях не увидел ни одного стоящего аргумента против Kotlin. Все очень субъективно. Что, как ни странно, логично. Потому что критериев сравнения настолько много, что в одной статье или комментарии их в принципе невозможно все перечислить. Тут целый научный трактат нужен. Поэтому субъективное ощущение «лично мне нравится/не нравится» остается единственным критерием выбора для нормального человека.
Я для себя выбор сделал. После 18 лет разработки на Java перешел на Kotlin — и очень этим доволен. Джаву хорошо знаю, люблю и уважаю, но вряд ли к ней когда нибудь вернусь. Для меня это пройденный этап. А от программирования на Kotlin лично я получаю огромное удовольствие — что для меня в миллион раз важнее, чем все «логические» доводы за и против :) В конце концов на работе мы проводим 80% жизни, если не считать время сна, и очень важно, чтобы работа приносила только положительные эмоции.
Поэтому, ИМХО, абсолютно не важно — справа тип от переменной объявляется, или слева… Есть null safety или нет… Ну и так далее по списку… Важно другое — лично вам это нравится или нет. Вот и все :) Не нравится — оставайтесь на джаве, и будьте счастливы. Нравится — добро пожаловать в Kotlin :)
Не очень понимаю, как может нравиться или не нравиться язык, ну если это не совсем уж что-то упоротое. Я даже после прекрасного C# писал на джаве 7. Конечно удивляло, как все неудобно, но от кривой Идеи подгорало гораздо больше. В конце концов должно быть удобно код писать и отлаживать, а не синтаксис. Лично я думаю как делать побольше, чем типы привожу или конструкторы использую.
НЛО прилетело и опубликовало эту надпись здесь

Не знаю насчет правильного аргумента. Видел много раз, когда челове которого прям "штырит" от плюсов начинает на нем писать типичный круд, и потом ты сидишь разгребаешь: что POST не работает (потому что тащящийся от плюсов разраб смог реализовать только GET), зато все данные можно передавать мегабайтными урлами. От чего сносит крышу уже nginx и некоторым либам, которые читали стандарты и знают, что урл не должен быть длиннее 16кб. Ну и так далее.


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

передавать мегабайтными урлами… что урл не должен быть длиннее 16кб

И оно правда работает? HTTP запрос с 1 MiB URL доходит до адресата не поломавшись?

Работает-работает. Правда пришлось nginx'у лимиты поднять на внутренние урлы, но что поделать.

НЛО прилетело и опубликовало эту надпись здесь
Я для себя выбор сделал. После 18 лет разработки на Java перешел на Kotlin — и очень этим доволен. Джаву хорошо знаю, люблю и уважаю, но вряд ли к ней когда нибудь вернусь. Для меня это пройденный этап.

Категорично, меньше не скажешь. То есть, лагерь разработчиков разделяется, одни не перейдут на Kotlin потому, что тонна legacy и никто не хочет, другие не перейдут на Java, потому что им не нравится. Ну я понимаю, когда люди переписывают с С++ на Java и наоборот… Но чисто по человечески это даже не .NET и JVM, это по сути одна кодовая база и, вряд ли, Kotlin ее когда-то всерьез изменит, зато 2 воинствующих лагеря "отцы-и-дети" ...

Ну, я только про себя говорю :) За других разработчиков я не отвечаю. Так что делать выводы о 2х враждующих лагерях из за моего поста — ИМХО — это преувеличение. В IT места под солнцем всем хватит. На рынке труда жесткий дефицит. Так что если не устраивает стек — просто меняешь место работы, и все довольны. Это дело сейчас нехитрое.
НЛО прилетело и опубликовало эту надпись здесь
Нуууу…
Ctrl-Shift-Alt-K на каком нибудь открытом Java коде попробуйте.
А потом скопипастить кусок Java и вставить в Kotlin.

Мне кажется, вы весьма удивитесь.
НЛО прилетело и опубликовало эту надпись здесь
Писал на Kotlin с 2016 года, на Java с 2012, до сих пор поддерживаю кодовую базу на Котлине. Набил много шишек, и в итоге я один из (наверное) немногих кто перешёл обратно на Джаву и потихоньку переписывает уже написанное на неё.
У Котлина есть фичи которые очень хотелось бы в Джаве (final by default, when, coroutines, elvis operator, operator overloading, ...), но есть несколько dealbreaker'ов которые лично для меня перевесили (в порядке уменьшения важности):
  • До совсем недавнего времени — невероятно долгая компиляция и лаги IDEA по сравнению с джавой. Всё было довольно неплохо пока проект не разросся на сотни модулей, после чего с каждым новым файлом/модулем/строчкой кода IDEA становилась всё медленней, а компиляция всё дольше. Всё было настолько плохо, что открытие любого .kt файла в проекте заставляло IDEA полностью подвисать на 2-3 секунды, а анализ кода одного файла занимал иногда и по 15-20 секунд. Писать код было очень затруднительно, приходилось выгружать не нужные на данный момент модули, что хоть как-то спасало ситуацию. И это на i7 7700K в 2018 году, с 8гб Heap выделенного IDEA. С Java таких проблем с аналогичными по объёму когда проектах никогда не было. В последних версиях котлина и IDEA всё сильно лучше, уже почти не лагает, да и компиляция стала заметно быстрей, но с Джавой IDEA всё ещё работает намного отзывчивей, и компиляция выполняется на порядки быстрее.
  • Постоянно что-то ломается с каждым новым релизом Java или IDEA. Например, поддержку Java 16 добавляли чуть более месяца. В EAP-билдах IDEA вообще была полнейшная шиза — среда разработки поддерживает Java 16, а плагин Kotlin'а к ней поставляется старый, который Java 16 не поддерживает, притом что в стабильном релизе IDEA не поддерживает Java 16, зато Kotlin поддерживал. Также за эти 5 лет было много ситуаций когда после очередного обновления плагина или самой IDEA ломался автокомплит кода, просто весь код покрывался фантомными ошибками (проект отлично собирается, редактор весь в ошибках, очистка кэша не помогает), ломался сам компилятор, возникали странные проблемы с тем что Kotlin не увидел зависимости когда они явно были в настройках модуля указаны, и в итоге приходилось всё откатывать в ожидании фикса, и это на стабильной ветке. Сейчас такого рода баги происходят довольно редко, но несколько раз даже за последние полгода получалось случайно ронять компилятор котлина с AssertionError и искать варианты как бы переписать код чтобы этого не происходило.
  • Из Котлина действительно можно использовать всё что написано на Java, но вот наоборот — конечно, тоже можно, просто выглядеть это иногда будет отвратительно. Из-за того что в Котлине нет static'ов без специальной аннотации приходится везде писать этот .Companion., или getInstance() для object'а, или ИмяФайлаKt для top-level деклараций. К слову, зачем в принципе нужен companion object вместо static'ов мне абсолютно неясно. Он не решает никаких проблем (разве что жёстко отделяет статическую часть от нестатической? Это можно и в Джаве добровольно сделать если хочется). Так как котлин дублирует довольно большую часть стандартной библиотеки Джавы, иногда приходится типы вроде Sequence превращать во что-то, что ожидают Java-библиотеки, и наоборот.
  • Бывает много случаев когда проверка и автокаст переменных от Nullable к NonNull не работает с мутабельными переменными (а иногда даже с иммутабельными полями), например, внутри if (var !== null), когда переменная внутри if'а не меняется, но зато меняется после. Приходится расставлять везде !!, что делает код намного менее лаконичным.
  • Очень не хватает тернарного оператора. Там где в джаве пишется a?b:c, в котлине мне приходится писать if(a) b else c в самой короткой записи. Мелочь, а очень бесило, особенно для языка который хочет быть лаконичным и коротким.
  • Нельзя быть уверенным что поле/переменная/возвращаемый тип/whatever будет примитивного типа, а не обёрткой над ним. Из-за того что Int, Double, Long и так далее у нас строго и всегда классы, и задать тип переменной чётко как примитивного типа нельзя, это может создавать проблемы с производительностью в горячих методах.
  • Возможно, я просто устал от краткого и лаконичного синтаксиса (кроме тернарного оператора), захотелось более красивый, хоть и чуть более громоздкий код :) Код на котлине мне кажется просто некрасивым, а Джава в последнее время довольно активно развивается и начинает перенимать в себя некоторые фичи с котлина.
я один из (наверное) немногих кто перешёл обратно на Джаву и потихоньку переписывает уже написанное на неё.

Интересно, вы это вручную делаете или какие-то инструменты есть, которые преобразуют Котлин в Джаву?

Инструментов таких я не знаю, да и не доверил бы им если бы они были :) К тому же это возможность пересмотреть некоторые решения в коде под текущие задачи.
Постоянно что-то ломается с каждым новым релизом Java или IDEA.

С этим должно стать лучше буквально со следующего релиза. Котлин-плагин затащили в репозиторий IntelliJ IDEA, соответственно он обновляться будет синхронно с основным кодом, интегрироваться только с конкретной версией Идеи, с которой поставляется, что упрощает разработку и тестирование. Ну и синхронные изменения в платформе и плагине делать проще будет. Плюс разработчики из Идеи будут чаще что-то исправлять в Котлин-плагине, если есть необходимость (например, чтобы избавиться от небезопасных устаревших вызовов). В общем, светлое будущее впереди :-)

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

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

Речь про IDEA, а не котлин…
Глобально в мире софта такие заявления делают все регулярно. Вот раньше было плохо, а в свежей версии все точно хорошо. Мы все наконец-то правильно переписали.

А потом принтеры перестают работать. И не чинятся продолжительное время.

Чтобы быть проближе к теме.
В свежей ИДЕЕ сломали окошко лицензии. Кнопка закрыть постоянно прячется ниже границы окна. Мониторы хаотично переключаются. Есть такое. Но кнопку зачем прятать? Там места вагон.

И вообще непонятно зачем меня засталять жать на нее? Сервер лицензий иногда пинговать и закрывать это окно автоматом когда он наконец нашелся.
Вот про «бета тестером за свои же деньги» прямо right in the feels. Я раньше IDEA обновлял сразу, как только выходил стабильный релиз, но каждый раз у них что-то ломается и пока не выйдет 2-3 минорные версии приходится страдать. И до сих пор есть куча проблем с производительностью, в частности на macOS, которые просто игнорируются годами.
По тем же причинам полностью отказался от котлина полгода назад, т.к. работать на нем было просто невозможно. Проблем практически никаких не решает, но создает кучу новых, которых не было бы при использовании джавы.
Писал на котлине с 16-го года. Тогда казалось, что это что-то модное и крутое, что за ним будущее. Сейчас же мне кажется, что фанаты котлина на бэкенде — люди, которые просто устали от работы и им нужны новые ощущения от использования нового для них языка. Подобный эскапизм саму проблему не решает. Котлин точно так же надоест через несколько лет и захочется перейти на какой-нибудь раст или c#. Только вся эта история уже не про языки и даже не про программирование.

if (var !== null), когда переменная внутри if'а не меняется, но зато меняется после. Приходится расставлять везде !!, что делает код намного менее лаконичным

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

var?.let { ... }

Ну и на помощь приходят всякие takeIf, also, apply. Но иногда они привносят больше сложности в понимании, тут важно не перестараться.

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

Тут не всё так просто. Представим ситуацию, что у нам многонитевое приложение на джаве


Пример кода
class Main {
  private static volatile String password = "1234";

  public static void main(String[] args) throws Exception {
    new Thread() {
      public void run() {
        password = null;
      }
    }.start();

    if (password != null) {
      Thread.sleep(100);
      System.out.println("Password: " + password);
    } else {
      System.out.println("Password is not defined");
    }
  }
}

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

С другим потоком всё понятно и вопросов не вызывает (кроме случаев когда поток вызывается строго после if-а), но я же говорю про банальные случаи. Вот например, вообще можно отнести к разряду бага, когда убирание !! приводит к ошибке компиляции, хотя не должно:
class Test {
    val v = if (ThreadLocalRandom.current().nextBoolean()) ClassWithInvoke() else null

    fun test() {
        var x: String? = null
        if (v !== null) {
            x = v!!()
        }
        println(x)
    }
}

class ClassWithInvoke() {
    operator fun invoke(): String = "..."
}

И зачем вот тут нужен !!?)

Кажется, баг)

Но можно написать v.invoke(), что уже скомпилится

Забавный пример с instanceof. Мне джавовский вариант кажется крайне странным, не соответствующим ожидаемому поведению. Хочется как минимум видеть при таком синтаксисе другое имя оператора.

Нормальный вариант. К слову, в сишарпе сделано точно так же, интересно кто у кого одолжил :)

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

Есть о чем задуматься конечно. Вместе с тем, «стратегия как Java, только лучше» будет ещё долго в силе, как минимум потому что большинство проектов и людей ещё работают на Java 8. Если представить сколько времени уйдёт на переход на версии Java 16+, то у Котлина еще много времени на манёвр.

Кажется, дотнет становится всё более привлекательным синтаксически

Он изначально превосходил JAVA, они первыми завезли лямбда выражения и кучу синтаксического сахара. Майкрософт же создали изначально свою Microsoft Java Virtual Machine, даже помню, как она ставилась вместе с Visual Studio 2003, но столкнулись с судебными исками по поводу торговой марки JAVA в названии. В итоге они жестко обиделись, обида подтолкнула их создать что-то более лучшее, и они создали C#, который имел схожий синтаксис, но еще имел кучу синтаксического сахара и большое количество улучшений. И честно говоря, если бы они изначально отказались от привязки только к в windows и создали свою .net платформу для всех основных ОС, то они бы жестко откусили рынок JAVA и возможно даже бы сместили его с лидирующих позиций. Основной плюс JAVA был, да и основная концепция, что напиши один раз и будет работать везде. Правда Microsoft к этому пришли только сейчас и уже активно продвигают .NET в другие ОС, и видимо пытаются все же откусить кусок от JAVA. Да и вообще свои продукты активно продвигают в опенсорс, и создают лояльную аудиторию.
Я не скажу про синтаксическую привлекательность, имхо сахара уже слишком много. А вот то, что .Net Core теперь опен сорс и перформанс уже намного лучше стандартного джава стэка это факт. Даже aspcore-mvc-ef-pg раз в 5 быстрее спринга.
А вот то, что .Net Core теперь опен сорс и перформанс уже намного лучше стандартного джава стэка это факт.

Прикольно! А как меряли?


Даже aspcore-mvc-ef-pg раз в 5 быстрее спринга.

Поделитесь линком на замеры?

Отличный пример, спасибо!


Для тех, кому любопытно, что тестируется и как замеряли.


Сделано веб приложение, которое вытаскивает все записи из таблицы (записей 12, но коду запрещено об этом заранее знать) и кладёт в лист. Потом в лист кладут ещё один объект и дальше лист сортируется по одному из полей. Сортировки в запросе заранее нет.


Далее этот лист скармливается шаблонизатору, который делает из объектов html таблицу из 13 строк.


Вот на этом сценации spring обрабатывает 23 тысячи запросов в секунду, а aspcore 105 тысяч. Спринг никто не тюнил, единственное, что расширили пул коннекшнов к БД до 2 * количество ядер. aspcore наверное тоже никто не тюнил, но специально это не оговорено.


Что интересно, если не ограничивать тесты спрингом, то джава работает быстрее, чем любой вариант C#, поэтому можно предположить, что дело действительно в каком-то из компонентов спринга.


Также, если измерять сценарий в котором каждый http запрос приводит к появлению нескольких запросов к БД, spring быстрее чем aspcore раза в 2, а если измерять только сериализацию в json, то aspcore быстрее spring раз в 10.

Вывод не совсем корректный. Конкретно в этом сценарии лучшая Java это jooby-pgclient c 423,234 и лучший C# это aspcore-ado-pg 400,987 так что разницы практически нет. Что такое jooby и кто на нем пишет вынесем за скобки.

Также, если измерять сценарий в котором каждый http запрос приводит к появлению нескольких запросов к БД, spring быстрее чем aspcore раза в 2, а если измерять только сериализацию в json, то aspcore быстрее spring раз в 10.


Ну 27 против 21 это явно не в 2 раза. Да и в таких сценариях, очевидно, больше упирается в драйвера БД. А вот какой-нибудь JSON позволяет понять насколько оптимизирована работа с памятью и IO.

А самое главное, что еще года 4 назад .Net отставал в разы.

спринг никогда не был эталоном производительности

У .NET синтаксис может быть такой же, как у JVM, если на Oxygene писать
Не согласен с автором, что современные фичи Java реализует лучше, чем Kotlin. Даже приведенный пример с instanceof на практике выглядет примерно так:
if (value instanceof String stringValue) {
    // код со stringValue
    processString(stringValue);
}

Пладим новую переменную, от первоначальной отличающуюся только типом.
Kotlin со своим smart cast позволяет этого не делать.
if (value is String) {
    // работаем с value как со строкой
    processString(value);
}

Это конечно вкусовщина, но мне приятнее второй вариант.

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

Для вычисляемых/изменяемых значений в Kotlin есть другие конструкции, например, inline-функции let и also. Будет что-то вроде такого:
getValue().let { value ->
    if (value is String) {
        processString(value)
    }
}

Эти всякие let — это ужасно. Код превращается в лапшу.

извиняюсь за оффтоп, но видел что JetBrains новую IDE пилят. есть где про это почитать? я когда узнал, удивился, сложно же будет наверстать столько всего, что успели вполотить в IDEA

Боюсь, у меня нет публичной информации на этот счёт. Официальных объявлений (когда они появятся) следует ждать в блоге JetBrains или в аккаунтах JetBrains в социальных сетях.

окей, просто увидел в вакансиях информацию об этом, думал есть какие-то публичные детали. спасибо :)

не нравится let, есть простое как дверь решение: разнести объявление переменной и проверку типа

val value = calcValue()
if (values is String) {
    processString(value)
}

Или на Java:


if (calcValue() instanceof String value) {
  processString(value);
}
ну хорошо, для вычисляемых значений Java ввела хороший синтаксис проверки типа с объявлением новой переменной.
Но на моей практике 90% случаев проверки типа происходит на существующей переменной, в этом случае в Java я обязан объявить новую переменную отличающуюся только типом, что выглядет убого (опять же на мой взгляд).

90% случаев проверки существующей переменной у вас только если у вас нет синтаксиса как в джаве :)
Я тоже так думал (я шарпист, правда, но там 1 в 1 джава, только кейворд is покороче чем instanceof), а потом начал пользоваться и как раз удобно что мусорное значение не засоряет скоуп. Ну вот например:


img


Обратите внимание на 55 строчку. Там логика "вызвали метод, если вернулся нулл то ретурн нулл сразу, иначе вот у нас есть переменная с каким-то значением". Вопрос — зачем мне мусорное значение которое вернула TryGetInitWithValue(type) в скоупе?


Модифицировать оригинальное значение (типа навесить знание что "оно не нулл") не всегда можно, см. например 61 строчку, где происходит сразу деконструкция, а держать переменную под тапл не особо удобно.


Хороший пример просто, что вот никаких 90% с проверкой существующей переменной (когда у вас есть выбор) нет. Когда выбора нет — тогда другое дело, конечно, тогда я думаю процент даже не 90 а 100 :)

Если често — ужас, не зная синтаксиса C#, сложно что-то понять.
Там логика «вызвали метод, если вернулся нулл то ретурн нулл сразу, иначе вот у нас есть переменная с каким-то значением». Вопрос — зачем мне мусорное значение которое вернула TryGetInitWithValue(type) в скоупе?

Если я правильно вас понял — вы хотите вызвать функцию и если ее значение нужного типа, что-то с ней сделать и не выносить переменную в основной скоуп. Ок, в Kotlin это делается так:
(calcValue() as? RequiredType)?.also { value ->
    //в этом скопе (и только в нем) есть value типа RequiredType
}

Хороший пример просто, что вот никаких 90% с проверкой существующей переменной (когда у вас есть выбор) нет. Когда выбора нет — тогда другое дело, конечно, тогда я думаю процент даже не 90 а 100 :)

А как бы вы реализовали такую функцию без создания доп. переменной?
fun addValue(value: Any) {
    if (value is ListenableValue) {
        value.onAdd(this) // onAdd есть у типа ListenableValue
    }
    set.add(value)
}

Создал бы переменную. Просто менять тип кмк на value не очень комильфо. Для таких случаях обычно нетрудно дать скоупед-переменной однобуквенное имя. В лямбдах вот никого не парит это никого обычно:


fun addValue(value: Any) {
    if (value is ListenableValue v) {
        v.onAdd(this)
    }
    set.add(value)
}
Java вариант:
if (calcValue() instanceof String value) {
  processString(value);
}

На самом деле идиоматичный Kotlin вариант намного функциональнее:
when(val v = calcValue()) {
  is String -> processString(v)
}

Функциональнее, потому что в Kotlin, в одном скоупе можно проверить не один тип, а несколько, и не только типы, но и значения, без создания дополнительных переменных. Попробуйте повторить в Java c вашими if/instanceof/switch:
when(val v = calcValue()) {
  is String -> processString(v)
  42 -> prosess42()
  is Int -> processInt(v)
  else -> processElse(v)
}

В Java 17 обещают завезти:


switch(calcValue()) {
case String str -> processString(str);
case 42 -> process42();
case Integer i -> processInt(i);
case Object other -> processElse(other);
}

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

ок. Если вам нравится придумывать названия переменных для каждой ветки, Java, C# — ваш выбор.
А мне нравится smart cast — отличная идея, которая сохраняет строгую типизацию в языке и позволяет не плодить лишних переменных.

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


var v = (calcValue(), calcValue2()) switch {
  (String s1, String s2) => processString(s1, s2),
  (SmthN smth1, SmthN smth2) => processSmthN (smth1, smth2),
  (se1, se2) => processElse(se1, se2)
}
про C# я вообще молчу, мне в силу ряда причин нужен язык на JVM.
И я скорее про пример из habr.com/ru/company/funcorp/blog/558412/#comment_23070268 — сами же сказали, что создадите дублирующую переменную (однобуквенную или нет — не столь важно).

Мы сейчас говорим про "Java vs Kotlin", оба — жвм языки. Я C# беру просто как пример, на котором можно показать что синтаксис джавы может дальше развиваться в сторону рекурсивных паттернов и они все будут естественным образом встраиваться в существующий (x instanceof Foo y). А дальше рассуждения на тему, что синтаксис котлина подобным образом расширить не выйдет и придется выдумывать что-то совсем иное.


Я в первую очередь смотрю на ортогональность фичей, и то что зная фичу Х и Y я могу легко их скомбинировать в XY. В данном случае у джавы потенциал в этом плане выше имхо.

Ну в шарпе это точно так же щас делатся:


var v = calcValue() switch {
  String s => processString(s),
  SomethingN smth => processSomethingN(smth),
  somethingElse => processElse(somethingElse)
}

И кмк то что в каждой ветке своя переменная со своим типом воспринимается проще. Думаю в джаве так же сделают.

Придумывать еще одни имена для уже имеющихся переменных такое себе =)


В идеале бы, сделать чтобы был возможен и тот и другой вариант.
Например, можно было бы в Kotlin поддеражать такое:


if (value is v: String) {
    processString(v);
}

Или можно сделать чтобы переменная неявно создавалась бы, если нужно (ну или явно, но опять же автоматом):


if (value is String) {
    // smart casting value to String, and if value is mutable, it saving to new variable 
    processString(value);
}
Но ведь в котлине есть ровно такая же возможность, только не в if, а в when
when(val x = someValue) {
   is String -> //use x as String
   is Int -> //use x as Int
   else -> //do something else

Что будем писать на джаве в этом случае? Портяночку ифов, ага.

Прикольно, конечно, пример искусственый. Если где-то появляется портяночка if на instanceof, значит, кто-то где-то не освоил ООП — 99% случаев.

Искусственный он до тех пор, пока не используются sealed classes. Выше были примеры для стрингов, я это просто продолжил. Мы очень часто используем sealed иерархии, и вот с ними мощь type inference раскрывается значительно.
sealed class Result {
    data class Ok(val data: SomeData): Result()
    data class VerificationFailed(reason: SomeReason): Result()
    data class UnknownError(exception: Exception): Result()
}

...

when(val result = getResult()) {
   is Result.Ok -> printData(result.data)
   is Result.VerificationFailed -> printReason(result.reason)
   is Result.UnknownError -> printStackTrace(result.exception)
}


Ещё оно умеет в exhaustive when, то есть компайл-тайм проверки, что все варианты перечислены и никаких else не нужно.

Нет, нормальный пример.

We expect that, in the future, general classes will be able to declare deconstruction patterns to specify how they can be matched against. Such deconstruction patterns can be used with a pattern switch to yield very succinct code.

То есть рекурсивные паттерны как раз затащат (Как в примере с шарпом ниже). Прикольно, спасибо

Возьмем сишарп:


if (GetUser() is User user) { ... }

или даже:


if (GetUser() is User {Name: "Alex"} user) { ... }

Вроде просто и понятно. А на котлине как?

GetUser().also { user ->
    if (user is User) {
        //....
    }
}


или например:

(GetUser() as? User)?.also { user ->
    //....
}

Ну субъектвно чуть менее приятно, но возможно вопрос непривычности.
Тогда два вопроса:


  1. А рекурсивные паттерны так можно? (как в примере с проверкой, что у нас не просто юзер, а с именем Alex)
  2. А в джаве как?
1. Такого нет. (И слава богу).
2. В Java 14, как уже отмечали, прямо как и в С#
if (getUser() instanceof User user) {
    //...
}

Насчет того, что для вычисляемых значений синтаксис чуть красивее получается в Java 14 — не спорю.
when(val user = getUser()) {
    is User -> ...
    is Admin -> ...
}
ну да, или так
Когда перешел в комментарии, по тому, что не знаком ни с Java ни с Kotlin

Спасибо за статью. На самом деле не понимаю хайпа вокруг Kotlin. Если IDE от JetBrains ещё в определённых рамках обоснованно, то с Kotlin... JetBrains прекрасно показали на сколько они качественно могут поддерживать язык и его развитие на примере Nemerle.

Не уверен, что там проблема была (в первую очередь) со стороны JetBrains. Хотя было бы интересно послушать описание событий с их стороны.

История о том как бросить кусок г-на на вентилятор и устроить саботаж в Jetbrains… Сотрудники Jetbrains активно пишут комментарии вместо работы…

Это так толсто, что даже бессмысленно оправдываться. А вы в какой компании активно пишете комментарии вместо работы?

В конкурирующей, которая заплатила за саботаж, разве не понятно?

Май 2021 года. Любой, кто никогда не имел дела с моб. программированием и ищет на чем бы написать новый проект с нуля, пройдет примерно такую цепочку: 1. Ну Java конечно для андройда, что ж еще. 2. Ой, вот какой-то Kotlin появился, и Google его в студии включил по умолчанию, серьезное что-то наверно. Но эти русские ребята отпугивают. Тем более, они еше и Idea делали, уж знамо что это, уже 10 лет пользуем... 3. Apple же еще! Ну там свифт наверно придется осилить с нуля.. 4. Xamarin, phonegap.. не, это будет тормозно и в никуда, как в 2010-х. 5. Flutter! Dart! Че за...? И через месяц у вас реальный проект уже в сторах продается обоих. (реальная история) Это если вы гугл поисковиком пользуетесь, он вам в таком порядке будет питчить. Поэтому перспектива у котлина плачевная.

Как всегда, все приведенные аргументы мелкие и несерьезные: у нас есть фича A, а у вас ее нет, либо она хуже и вообще плохая. Я тоже писал проекты на Kotlin, но до сих пор предпочитаю Java, и вот почему:


  1. Синтаксис. Котлин сложнее и оперирует бОльшим количеством конструкций. Язык и API зачастую создают впечатление перегруженностью сахаром. Да, это позволяет писать более "лаконичный" код (за что и ставят плюс), однако совершенно противоположно действует на читабельность оного. Многабукав в Java совсем не значит, что это труднее читать.
  2. Полиморфность кода. Для большинства задач в Java уже предусмортен джентльменский набор стандартных решений и паттернов проектирования. В Котлине, благодаря его "широким возможностям", количество способов для одной и той же задачи увеличивается сразу в десятки раз. И выбор "правильного" метода лежит на сугубо на индивидуальных эстетических критериях каждого программиста. Кроме того обилие implicit-ов (extension methods, пакетные функции) делает конкретный фрагмент абсолютно нечитаемым без контекста. В итоге в проекте отсутствует всякая унификация кода, если у вас больше 1 девелопера, что называется "кто в лес, кто по дрова". Это ухуджает в разы поддерживаемость проекта.
  3. Экосистема. Чисто котлиновская сейчас очень мелкая, поэтому так или иначе приходится использовать джаву и интегрироваться с ней. Несмотря на то, что много кто сегодня поддерживает Котлин, всегда при интеграции возникают швы и костыли ввиде kotlin.jvm.* и прочих. Не слушайте всех, кто "не испытывают в котлине проблем с java-библиотеками" — они нагло врут, а в голове постоянно держат "в какой джава класс скомпилируется данный кусок кода". Ну или не пишут ничего сложнее микросервиса к базе, хотя и тут будут проблемы с Jackson binding-ом.
  4. Киллер-фичи. Наиболее разрекламированное "чудо" зачастую оказывается бесполезным, а иногда даже вредным. Все сталкивались, что во многих случаях nullability тупо мешает, нежели помогает, портя собой код. Все потому, что nullability в большинстве случаев — это не статическое свойство, а контекстно-зависимое: программист знает, что конкретно здесь оно точно никогда не null, а вот там иногда может быть. Но описать такую конструкцию в Котлине нельзя (а вот в Java это как бы из коробки). Что там еще? Корутины? Очень интрузивное и тяжелое изменение, которое заставляет код выполняться совсем не так, как написано, разрезая сверху до самого основания ваш код на suspendable и не-suspendable. Loom гораздо более элегантен и прозрачен. Желание "улучшить" джаву приводит к проблемам совместимости и соответствующим костылям ввиде all open gradle plugin… Из позитивных фич я бы отметил коллекции (хорошо неинтрузивно переработали и сделали immutable), и properties.
  5. Позиционирование языка. Не понятно целевое назначение. С одной стороны это "улучшенная джава", с другой он претендует на инструмент для multiplatform-разработки и суется в чуждые ему ниши. Однако в каждой из них приходится жестко конкурировать с уже устаканившимися языками: если вы пишите под JVM, для Java вам нужно знать только Java, для Kotlin вам нужно знать Kotlin и Java. Для JS-таргета приходится конкурировать с нативным Typescript, и юзать костыли для интеграции с JS-экосистемой, ну естественно, также приходится знать JS. Для native тоже котлин не в моде — там сейчас Rust. Остается Android, но и тут он теснится Flutter/Dart. Реально же проекты, где необходима мультиплатформенность с единой кодовой базой, в природе не встречаются.
Реально же проекты, где необходима мультиплатформенность с единой кодовой базой, в природе не встречаются.

Ну почему же. Вот, например. Правда, кросплатформенность и без Kotlin бывает, на обычной Java. Для iOS был MOE, а сейчас GraalVM. На Android и на сервере нативно работает. На web — TeaVM. Правда, на сервере не надо запускать весь код клиента, достаточно только части, отвечающей за OT.


Очень интрузивное и тяжелое изменение, которое заставляет код выполняться совсем не так, как написано, разрезая сверху до самого основания ваш код на suspendable и не-suspendable. Loom гораздо более элегантен и прозрачен.

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

Ну почему же. Вот, например.

Игрался я с вашей TeaVM — вы маньяк каких мало (в хорошем смысле слова). Я в свое время активно юзал GWT, сейчас для энтерпрайз тулзов использую Vaadin. Однако сейчас в большинстве случаев типичный проект — это разные команды и разные кодовые базы для каждой платформы, плюс сервер. Во всей компании все, кто знают котлин, лабают исключительно под андроид, и абсолютно не секут в веб-фронтэнде ни в бэкэнде. Бэкендеры сидян на джаве и пайтоне. И ни один веб-фронтэндер, тоже не знает котлина (и не собирается). Вот такое разделение труда.

Не холивара ради, а интереса для. В этом топике не вы первый высказываете мнение, что nullability в Kotlin это зло. Я на Kotlin не пишу, но много пишу на TS. И решительно не понимаю как можно рассматривать nullability как зло?! Это какой-то холиварный вопрос или оно просто в Kotlin-е сделано из рук вон плохо?


TS (strict=true) заставляет вас убедиться в том, что значение !== null, перед использованием. И если вы "мамой клянусь, тут не null" (у нас всё хитрее и есть ещё и undefined на самом деле, ну да не суть), то вы можете:


  • написать assert guard (метод который вернёт переданный аргумент назад, проверив что внутри точно не null, или упав)
  • написать variable! (символ !). Но это часто запрещают линтером, дабы не повадно было срезать так углы
  • проверить совсем явным образом (скажем через if)
  • срезать угол, воспользовавшись чем-нибудь вроде ?. или ?? (аналогичные вещи есть, скажем, в C#)

Ну и предполагается что хорошо организовав типы в проекте, да и саму кодовую базу, вам не придётся регулярно упорно доказывать компилятору, что "да зуб даю, тут не null". Наш опыт показывает, что в ~10-15% случаев, когда программист думает "тут никогда не бывает null", он ошибается :) Поэтому мы предпочитаем assert guard, чтобы выловить ошибку в runtime на самой ранней стадии.


В Kotlin нет аналогов вышеописанному?

Ровно такая же система null-safety и в Kotlin. Люди, которые её ругают, делают это по 2ум причинам:
  1. В Java нет такого null-safety. И никто не мешает в Java записать в non-null поле этот самый null. Учитывая, что большинство используемых библиотек написано на Java, этот аргумент имеет место быть.
  2. Есть способы обойти null-safety через двойной восклицательный знак и lateinit.

Интересно. В TS тоже можно записать null в not-nullable переменную (ибо под капотом JS):


let a: boolean = false;

a = null as unknown as true; // double type casting
// @ts-ignore 
a = null; a = undefined; a = whatever;

Но такое случайно не напишешь. Это прямо диверсия :)

Не нужно никакой диверсии. В мире Java-бекенда вы будете использовать JDBC — это Java API для БД. Далее вы, как разработчик, сделали select, проверили, что искомый столбец not null и отметили поле в вашем DOA-объекте not-nullable.
А через месяц другой разработчик сделал alter на таблице, убрал not-null и стал писать строки с null.

Попробую объяснить. Лирическое отступление. Забудем сначала про null и зададимся вопросом что отличает языки со слабой типизацией от языков с сильной типизацией. В первых вывод типа происходит исключительно в рантайме. Во вторых же позволяют декларировать какой-то статичный контракт, подчиняющийся определенным правилам вывода, который может быть вычислим на этапе компиляции. Однако это не совсем не отменяет того, что в программе большинство типов остается вычислимо лишь в рантайме. Попытки внедрить и использовать более сильную систему типов (напр. ScalaZ), позволяющую иметь бОльший контроль на этапе компиляции, сталкиваются с проблемой, что описание типов для предметной области становится в разы сложнее, чем сама программа, и тем не менее все-равно будут появляться места, где тип вычислим лишь в рантайме. Поэтому важно сохранять некий баланс между контролем типов и простотой описания.


Теперь вернемся к нашим баранам. Java по дефолту не имеет способа объявить контракт по nullability, однако его все же можно по желанию дополнить аннотациями Nullable/@Nonnull, либо использованием Optional. Котлин же наоборот обязует для любого типа всегда использовать строгий контракт по поводу nullability без возможности послабления. Почему это плохо? Приведу пару демонстративных кейсов.


  1. Функция, которая конвертирует объект в строку, причем для null-ов она должна возвращать null.


    fun toString(a : Any?) : String? {
    return a?.toString();
    }

    Проблема в том, что она всегда обязана возвращать nullable String и обязует каждый раз делать проверку, даже когда поставляемый объект заведомо не null и описан в ситеме типов как не-null. Котлин не позволяет описать контракт "верни мне String? для Any? и String для Any", перегрузить функцию не получится — возникнет конфликт сигнатур.


    fun toString(a : Any) : String /* Platform declaration clash */

  2. Очень ленивая инициализация. Для nonnull полей Kotlin требовал сразу указать дефолтное значение. Логично. Но практически сразу же разработчики столкнулись с диким баттхертом при интеграции с различными библиотеками (DI, JUnit, сериализация, etc...), где значение поля вычислялось и заполнялось отложенно. Пришлось включить попятную и добавить хак ввиде lateinit, дабы как-то это сделать юзабельным. Пример: есть JPA Entity с полем id, которое заполняется автоматически при персистенции объекта. Nullable я его не хочу делать, т.к. null там только на этапе конструирования.


    @Entity
    class MyEntity {
    @Id @GeneratedValue 
    lateinit var id : Long
    fun isPersisted() : Boolean {
        return this::test.isInitialized
    }
    }

    И вот облом! Это не сработает, потому как при сохранении объекта JPA провайдер попытается прочитать из поля и получит kotlin.UninitializedPropertyAccessException.



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


Ну и предполагается что хорошо организовав типы в проекте, да и саму кодовую базу, вам не придётся регулярно упорно доказывать компилятору, что "да зуб даю, тут не null". Наш опыт показывает, что в ~10-15% случаев, когда программист думает "тут никогда не бывает null", он ошибается :)

Да ладно? Вы никогда со структурами не работали? Не байндили формочки к UI?
NPE самая частовстречаемая, но легко детектируемая и отлаживаемая ошибка. А статичными контрактами далеко не всегда удается вывести nullability. Вместо, чтобы вставлять nullability в контракт, просто поставьте Objects.requireNonNull() или лишний assert там, где это нужно и дело в шляпе.

Пункт 1. легко решается просто указанием JvmName для функции. В вашем примере будет:
fun toString(a: Any?): String? {
    return a?.toString()
}

@JvmName("toStringNotNull")
fun toString(a: Any): String {
    return a.toString()
}


про п. 2 согласен, lateinit — костыль, который вставили для поддержки существующих Java библиотек. Но даже в вашем примере, я бы не стал писать lateinit, а просто инициализировал Id нулем, т.к. нет смысла помечать lateinit примитивные поля.

Да, но например со стрингом не сработает. Есть неожиданный выход — описать Entity на Java, и все сразу заработает как надо :)

Понятно. Спасибо за экскурс в мир Java/Kotlin


В TS пункт первый вполне решаем. Этот метод можно написать так, чтобы результат зависел от исходных данных. Можно вернуть для nullable значений nullable string, а для остальных просто string. Правда сигнатура метода будет несколько замороченной. Без явной выгоды лучше написать два разных метода, чем морочить людям голову.


С late init тоже интересно. Понял что я даже не знаю как оно работает в TS, т.к. почти не использую классы и мутабельные структуры (а иммутабельным не нужна поздняя инициализация). Надо будет поиграться с этим.


Да ладно? Вы никогда со структурами не работали? Не байндили формочки к UI?

Какими именно структурами? И не очень понял какое отношение имеет binding к UI формам к обсуждаемому вопросу. Но при прочих равных я предпочту ошибку в compile time, а не в runtime. И предпочту работать с not-null значениями, чем с nullable. Обычно с этим проблем нет, в том числе и в web-формах. Ведь у поля формы ещё до bind-а есть значение (то что по-умолчанию). Поэтому и null не нужен. Возможно я не очень понял контекст.

Преимущество TS в том, что вам дают выбрать между строгой типизацией, нестрогой и динамической (всегда есть фоллбэк в голый JS). В Котлине (да и в Java тоже) такой опции нет — везде требуют строгие декларации, причем в котлине они более жесткие (тип dynamic не берем в рассмотрение — он был внедрен как пятое колесо специально для совместимости с JS). Сделано это с благими намерениями, чтобы обязовать пользователя писать "правильный" (по чьему-то мнению) код, однако как всегда там, где модель немного выходит за рамки, жесткие ограничения начинают жутко мешать.


И не очень понял какое отношение имеет binding к UI формам к обсуждаемому вопросу.

Как раз связано с nullable. Есть Entity, поля которой завязаны на UI-форму, и которая заполняется прогрессивно, например с веба. Вконце делается валидация полей (напр. при помощи JSR305), и все сохраняется в storage. Естественно, в Котлине все поля приходится описывать как nullable, и даже required-поля, которые никогда потом не будут null.


class User {
  @NotNull
  var username : String?
}

А затем уже на этапе использования везде расставлять "!!", либо пустые не-null проверки, что только увеличивает возможность ошибки. Многие скажут, что "правильный" kotlin-way здесь — это на каждую Entity создать еще один объект EntityDTO, в который делать меппинг формы, а затем уже замепить его в сам Entity. Но это сразу тупо в 4 раза увеличивает код практически без увеличения функциональной ценности.

Не очень понятно зачем описывать required поля как нулл — просто потому что фреймворк не умеет нормально инициализировать структуру? Ну, с натяжкой можно посчитать это проблемой котлина, но я предполагаю что для таких случаев есть бекдор (как null forgiving в C# к примеру)

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


В случае TS у вас, вероятно, будет что-то типа IO-TS, и вы сразу получите готовый DTO правильной формы с автовыводом типов по структуре валидатора. Без дублирования кода. Но тут уже нас выручает не null-safety, а algebraic types.

НЛО прилетело и опубликовало эту надпись здесь
Собственно, ИМХО, сила типизации — это спектр, который как раз и определяется, присутствие насколько сложных желательных (или отсутствие нежелательных) поведений можно гарантировать системой типов языка.

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


Более сильная система типов даёт вам возможность гарантировать больше вещей статически, но не требует этого.

Проблема в том, что как правило именно требует, благодаря чему делая простые вещи сложными в реализации. В Java вы не можете описать класс с динамическим набором полей, как в JavaScript — для этого приходится использовать Map. Еще более сложно иметь клас одновременно со статическими и динамическими полями. Котлине нет типа "contextual nullable" как в Java. Точнее он есть (Any!!), но это внутренний тип компилятора, введенный для совместимости с Java. TypeScript — да, позволяет использовать типы опционально там, где это нужно, имея fallback в JS.

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

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


Проблема в том, что как правило именно требует, благодаря чему делая простые вещи сложными в реализации. В Java вы не можете описать класс с динамическим набором полей, как в JavaScript — для этого приходится использовать Map.

А чем Map не является "динамическим набором полей"? Как по мне это одно и то же, разве что на объект можно ещё функций навесить — но вот объект с хз какими полями и ещё и функциями я бы вот видеть лишний раз не хотел.


Еще более сложно иметь клас одновременно со статическими и динамическими полями.

Не очень ясно что с этим сложного


Котлине нет типа "contextual nullable" как в Java. Точнее он есть (Any!!), но это внутренний тип компилятора, введенный для совместимости с Java. TypeScript — да, позволяет использовать типы опционально там, где это нужно, имея fallback в JS.

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

НЛО прилетело и опубликовало эту надпись здесь
>> Ну или не пишут ничего сложнее микросервиса к базе, хотя и тут будут проблемы с Jackson binding-ом.

Кстати, а с какими проблемами, специфичными для Kotlin, вам приходилось сталкиваться при использовании Jackson? Я вот пока не сталкивался с такими, хотя очень активно использую Jackson в Kotlin backend. Вот пример:
github.com/ermadmi78/kobby-gradle-example

Я реально уже не помню в деталях, раз как-то заставил работать. Общее впечатление — создаешь модель, она валится на сериализации из-за чисто котлиновских фич (конструкторы, nullability, immutable collections, delegates, vals, etc.), и приходится все перелопачивать. Для простых data objects проблем не возникает. Если интересно в деталях, загляните сюда https://github.com/FasterXML/jackson-module-kotlin/issues

> Корутины? Очень интрузивное и тяжелое изменение, которое заставляет код выполняться совсем не так, как написано, разрезая сверху до самого основания ваш код на suspendable и не-suspendable.

Эм… Так это ж фича а не баг. Действительно надо понимать где код suspendable а где нет. И да, изменение тяжелое — но этот геморрой стоит свеч, особенно когда доходишь до flows и начинаешь их понимать. Нам не нужны стейтмашины. Нам не нужны листенеры. Мы можем асинхронно запускать кучу зависимых друг от друга задач в параллель не переживая ни о том что это сложно будет останавливать случись чего, ни о том что мы переусложняем логику поведения настолько что это невозможно будет потом сопровождать. Это другая парадигма, но её изучение окупается сторицей — единожды это раскурив ты получаешь левел-ап, и твой код никогда не будет прежним.
Действительно надо понимать где код suspendable а где нет.

Вообще-то нет — это совершенно лишнее знание (да простит меня Роман Елизаров), требуемое конкретной реализацией асинхронности. Асинхронность появилась для того, чтобы обойти ограничение posix thread на масштабируемость путем избегания блокировок. Корутины — это лишь хак компилятора, где suspendable подменяет собой asyncrhonous callback. А любой хак, всегда несет с собой кучу побочки и проблемы интеграцией с уже существующей базой. Навскидку, вам под suspendable придется переписать весь стек до самого низкого уровная I/O и JDBC, многие фреймворки используют текущий контекст ThreadLocal в аспектах (напр. @Transactional), кторый не будет работать с suspendable (но и не выдаст ошибки), сложность дебага и стектрейса, etc. С другой стороны упомянутый мной Loom совершенно прозрачно реализует масштабируесомть для блокируемого кода, не требуя абсолютно никаких модификаций. Поэтому для JVM тут спорный выигрыш.


Тем не менее корутины как механизм хорош на других платформах, где нет suspendable threads, либо нет блокировок (native, JS, Android).

> Вообще-то нет — это совершенно лишнее знание (да простит меня Роман Елизаров), требуемое конкретной реализацией асинхронности.

Как минимум — оно дает понимание что вот в этом конкретном месте программы, где мы вызываем suspendable функцию — программа может воткнуть и вернуться к исполнению через секунды и минуты. Это легче читается чем код в котором функции которые будут работать милисекунды и код который может вызвать запрос на гигабайт через пол-планеты — выглядят одинаково (как в каком-нить олдовом RPC).

> Навскидку, вам под suspendable придется переписать весь стек до самого низкого уровная I/O и JDBC

Да, если у меня в коде есть вызов функции которая начнет синхронно читать файл в гигабайт через пол-планеты — то у меня все воткнёт. Ну так мы в самом начале пути, библиотечные вызовы внутри которых могут быть такие вот радости — мы можем вынести в отдельные потоки и играться с ними там, благо делается это на тех же flows в пол-пинка. А со временем все больше и больше API будут становиться полностью асинхронными (потому как тренд это нынче, не пишут сейчас чисто блокирующих API), и радостей будет только больше.
код который может вызвать запрос на гигабайт через пол-планеты — выглядят одинаково (как в каком-нить олдовом RPC).

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


А со временем все больше и больше API будут становиться полностью асинхронными (потому как тренд это нынче, не пишут сейчас чисто блокирующих API)

Мне бы ваш оптимизм, но увы. Еще даже нормального асинхронного JDBC стандарта на этот счет нет (и по ходу не будет). Весь низкоуровневый I/O-слой — это блокирующие API.

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

Конечно быстрее не выполнится, но зато — мы явно видим где наш код может затупить надолго. И это хорошо и правильно, ПМСМ конечно же. Да, я помню что в самом начале использования корутин саспенды расползались по коду как тараканы на свету — но это быстро проходит, чутка опыта — и с этим можно жить.
Как думаете, почему котлин не пойдет по пути свифта и не начнет в заранее запланированные даты ломать бэквардс компатабилити с автоматическим транслятором кода? Регулярно раз в год выходил мажорный апдейт, который ломал не только синтаксис, но вообще ABI — т.е старые либы отказывались линковаться.

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

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

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

Главное — Kotlin ушел от тяжеловесности выражений в Java, резко снижающей возможности представлять в уме, а значит и кодить более интересные конструкции (реализовывать более оригинальные алгоритмы)!
А как описаны в Kotlin массивы — это песня: не указывая длину, кратко и заполнение из любого места программы (как и работа с ним).
Есть серьезный баг в описании циклов и условных операторов: входящие переменные не проверяются на var, val и поэтому постоянно вмешиваются, мешая штатной работе. Надеюсь, они это исправят.
А если автоматизируют некоторые процессы типа: ручной работы с потоками, то им равных не будет!
Не это главное. «Дубовый» синтаксис джавы это как тяжелый черенок лопаты которой ты копаешь каждый день — через месяц ты его просто не замечаешь. Синтаксис — это роялит в основном при изучении языка, а поскольку мы вроде как профессионалы — то учим язык мы всегда (по времени) меньше чем им пользуемся. Ценность Котлина не в его современном синтаксисе (мы все равно все работаем в IDE и большУю часть дубовости джавы эти IDE скрадывают) — ценность Котлина в том что он умеет в асинхронность. Положите мои слова в банк — через 10 лет языки которые не умеют в асинхронность — будут пылиться в музеях. Да, джава тоже пытается пылить свою асинхронность — но ей это сильно сложнее потому что она тупо сильно старше, кода на ней — горы, и любой чих отзывается болью различных несовместимостей.
НЛО прилетело и опубликовало эту надпись здесь
С тем что современные программы так работают — процессор шустрый а данные лежат далеко, и часто — в разных местах. Т.е. нам нужно полезть, к примеру, одновременно по нескольким урлам, достать разные данные, да так чтобы данные полученные из одних могли отменить другие, или пользователь мог это отменить целиком или частично. Код на CompletableFuture для таких целей — это боль. Отдельные потоки на каждый запрос — отдельная боль. Реактивные подходы частично это решают, но у них своя боль в виде backpressure. По итогу — корутины самый чистый и правильный подход.

Майкрософт когда делала WinRT 10 лет назад уже выкинула на помойку синк — все ИО функции нового апи были асинронными.


10 лет прошло — воз и ныне там. Думаю ещё за 10 мало что изменится.

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

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

А перл все еще с нами? ;) Мне как раз казалось что он-то давно в музее пылится. Ну то ладно, не будем холиварить.

Booking.com все еще считают, что Perl — самое то.

ну вот именно что «все ещё». Мы ж не слышим о новых проектах на перле, его нишу давно и плотно занял питон.
Не стал бы так категорично: асинхронность, карутины… Ручная разводка потоков, с установкой «на глаз» времени задержки, тыкая пальцем в небо — по меньшей мере нелепость. Автоматизация иерархией с перебором, решение, но это работа не программера, а — обслуживающей платформы.
Не стал бы так категорично: асинхронность, карутины… Ручная разводка потоков, с установкой «на глаз» времени задержки, тыкая пальцем в небо — по меньшей мере нелепость. Автоматизация иерархией с перебором, решение, но это работа не программера, а — обслуживающей платформы.
Бегло пролистал и так и не нашел — где хоть кто-то вспомнил про асинхронность. Strict nullability и всякие языковые плюшки типа extension functions — это все замечательно, но без этого можно жить, это не дает level up к продуктивности разработки. А вот что дает — это корутины и их порождение flows, которые пабам — работают даже для самой древней джавы поддерживаемой Котлином (1.6? лень лезть смотреть). Т.е. если у вас есть проект на Джаве который вы хотя бы периодически меняете — есть смысл затаскивать туда Котлин вот прямо сейчас, потому что если на обычном синхронном коде Котлин будет +- один в один джава только покороче — то в коде асинхронном код на Котлине будет в разы (!) короче и в разы проще в поддержке. А где, скажите мне, в 21м веке синхронный код? У нас практически вся бизнес-логика — это микросекунду считаем что делать а потом сотни миллисекунд лезем в базу или сеть — и вот эти вот асинхронности Котлин решает КАРДИНАЛЬНО лучше. Да, в джаве пилят свою асинхронность — но ребята, жизнь коротка, ждать еще 2 года пока они ее допилят да пока ваш проект начнет на нее перелазить — нууу… выбор за вами.

В разы проще в поддержке, говорите? Знаю историю, когда весьма опытный и прошаренный программист написал серьёзный пласт логики на корутинах, затем настолько замучался их отлаживать, что выкосил их полностью, перейдя на более традиционные штуки типа CompletableFuture. Вы, конечно, можете сказать, что просто программист недостаточно умный, а умный бы всё быстро отладил. Но во-первых, это не так, а во-вторых, даже если вы гениальны и легко ловите находите любые баги в корутиновом коде просто посмотрев на него, то не факт, что тот, кто придёт после вас поддерживать этот код, будет настолько же прозорлив.

> перейдя на более традиционные штуки типа CompletableFuture

Я Вам одну вещь скажу, частенько пласт кода становится более простым и понятным просто потому что его переписывают. А с чего на что переписывают — это не так уж и важно. Но лично я год корутинами пользуюсь в хвост и гриву — но идеи «а может ну его и вернуться к родной лесенке на CompletableFuture» — не возникают ну вот совсем никогда.

Я кстати в начале этого века много подобных историй про классы слышал — вот взяли, навертели в системе классов, а потом все выкинули понаписывали обычных функций и норм стало работать. Корутины — это другая парадигма, и да — её придется научиться понимать, но выгоды слишком велики чтобы ее игнорировать.
Как мне кажется, управлять карутинами вручную — это анахронизм. Тем более, устанавливать величины замедления «на глаз». Лучше этот процесс автоматизировать, установив иерархию потоков, для прохождения пересечений. А если небольшой подпрограммой провести иерархический перебор, засекая время работы всех вариантов, то получишь наилучший вариант, не заморачиваясь.
Можно рассмотреть миллионолетний опыт природы, при создании двуядерного (сознание и подсознание) Homo sapiens. Постоянная иерархия, главенство сознания, и помощь подсознания при усталости (отдыхе сознания) или его перегруженности.

Начал в связи с работой изучать котлин. По сравнению с java 11+lombok он преимуществ не дает. При этом
1. Коротко написано
a+b.prop=19

в вашем коде может делать абсолютно что угодно и вам придется изучить код+все исходники что бы понять, что именно это делает. Самодокументация в джава что то вроде
a.addSaylary(b.getSaylaryIndex()).setDept(19) на деле требует намного меньших усилий для понимания. В котлин просто неверную метрику выбрали для оценки и правильно ибо хомяки ведуться массово. При этом так как есть автодополнение, что бы написать обе эти конструкции нужно нажать сопоставимое число кнопок, так что "быстрее набрать" тоже не катит.

2. Далее нал сейф конструкции. В java их можно спокойно заменить на Optional.ofNullable(X).map(x->x+1).orElse(y); и подобные однострочники, если хочется. При этом это медленнее работает, но в некритических местах видеть что то вроде (X?:1)+1 это прям глаза режет, так как ты начинаешь читать символы вместо простого английсого текста.
3. У них есть "крутая фича" extension functions на которой большая часть всего выстроена. Так вот как только в расширяемом так классе случайно сделают метод с такой же сигнатурой как функция расширения, ваш код молча, без ошибок и предупреждений начнет делать не то, что вы думаете :) Это вообще ржака. Никто, никогда, ничего отвественного на таком инструменте делать не будет...ну если он изучает нечто, а не бежит за хайпом

3. Так как котлин догоняет и обитает в jvm, то в java просто включат все самое вкусное, что уже и произошло, так как внига про котлин постоянно напоминает, что сравнение идет с java до версии 8 и котлин лучше чем она. Это уже просто факт, что котлин перегонял уже давно не поддерживаемую даже версию java.

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

Итоги прочтения пока 300 из 400 страниц книжки по котлину "Котлин в действии". Дочитаю скоро.

Публикации

Изменить настройки темы

Истории