konsoletyper
+1

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

konsoletyper
+1
например благодаря тому, что котлин дает полный контроль над тем, как API библиотеки выглядит со стороны джавы

Ну даже "из коробки" тот API, который Kotlin отдаёт Java, выглядит достаточно удобным и естественным, за исключением классов, оканчивающихся на Kt, и необходимости явного обращения к companion object. Обе претензии больше эстетические, чем концептуальные, да и возникают подобные ситуации не очень часто.

konsoletyper
+6

Ну это интересный вопрос. Я, как один из разработчиков языка, должен бы по идее защищать язык. Однако, скажу честно: я не знаю. Я так понимаю, просто есть разные люди с разным мировосприятием, кто-то хочет стабильности и надёжности (и поддерживаемости кода конченными индусами), кто-то хочет чего-то с приятными синтаксисом. Так что пусть на вопрос "зачем" отвечают разработчики для самих себя. Как мы видим, достаточно большая часть разработчиков нашла ответ на этот вопрос, и Google даже пришлось пойти им навстречу.


Для себя я придумал такое объяснение, зачем мы делаем Kotlin — чтобы дать людям выбор. Ну и ещё одно — чтобы у людей была возможность писать fullstack-приложения. В мире JS есть node.js, почему в мире Java нет fullstack-решения? Есть GWT, но он в последнее время тихо загибается, плюс это сторонний инструмент от стороннего разработчика, а не официальная технология от разработчиков Java. Мы же в Kotlin координируем усилия между командами, разрабатывающими JVM, JS и Native бэкэнды. А некоторые внутренние продукты JetBrains уже пишутся на fullstack Kotlin.


когда есть обкатанная Java c миллионом библиотек и готовых решений под неё

Ваша ошибка в том, что эти библиотеки "для Java". Это не так, Kotlin прекрасно работает с библиотеками, созданными специально "для Java"

konsoletyper
0

Сборщик мусора можно и свой написать. Я уже частично портировал свой Java-JavaScript компилятор в WebAssembly: https://github.com/konsoletyper/teavm

konsoletyper
–1

Внутри у любого современного компилятора есть IR, да не один. У Java это — байт-код, у LLVM — биткод или текстовый IR, у gcc — какой-нибудь gimple и т.п. Над IR, в виду его простоты, достаточно тривиально делать подобные трансформации. В Kotlin есть свои IR, но они ещё не устаканились, так что мы пока не публикуем их. В данный момент трансформация в state-машины в реализации корутин для JS и JVM делается по-разному, возможно, когда-нибудь мы сделаем универсальную трансформацию. Основная проблема в том, что на уровне байт-кода (или любого подобного представления) трансформация делается тривиально, а на уровне AST (который удобен для генерации JS) та же трансформация выглядит значительно менее тривиальной, и оставляет в коде значительно больше мусора.


Вообще, наличие простого как пробка байт-кода у Java — это то, за что я так люблю эту платформу. Стоит лишь не полениться его выучить, овладеть такими инструментами как asm, и можно творить такую магию, что никаким lisp не снились (к сожалению, очень мало разработчиков знают о такой киллер-фиче и умеют её правильно готовить). По опыту работы с JS, как с целевой платформой, для него как раз такой фичи очень не хватает. Надеюсь, мы когда-нибудь дойдём до того, что сделаем этакий платформо-независимый kotlin bytecode.

konsoletyper
0

Вообще-то, JVM хорош тем, что синтаксис новый не нужен — достаточно просто поинструментировать байт-код. Собственно, мы в Kotlin так и делаем (аналогично делает какой-нибудь quasar).

konsoletyper
0

Как раз одним из главных приоритетов при разработке корутин и была бесшовная интеграция с существующими библиотеками. В отличие от .NET, Kotlin не привязывает реализацию корутин к конкретным классам вроде Task. suspend-функцию можно написать для любой имеющейся библиотеки.

konsoletyper
0

Вот мне кажется, что лучше уметь порождать точный source map, чем стремиться к 100% читаемости сгенерированного кода. А для тех случаев, если всё же пришлось подебажить сам сгенерированный код, мне кажется, Kotlin порождает достаточно читаемый код.

konsoletyper
–1
Kotlin же тянет с собой мегабайтную библиотеку

Я же уже писал — мы постепенно решим эту проблему


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

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


Далее, а зачем генерируемый год должен быть читаемым? Вы часто смотрите на машинный код, сгенерированный каким-нибудь gcc?


Кроме того, TS на порядок проще.

И про это можно подробнее? Опять же, хотя бы несколько пунктов.

konsoletyper
0

Да, такие планы есть.


видимо как раз из за того что не хватает информации о типах.

В том-то и беда, что "видимо". GCC достаточно плохо работает на stdlib Kotlin, и пока не вполне очевидно почему. Возможно, дело в типах, возможно, в чём-то другом. Это вопрос требует исследования, и мы планируем потратить на них какое-то время.

konsoletyper
0

WebAssembly ещё очень далеко до того, чтобы на нём сделать полноценную реализацию движка JS. Сейчас там нет ни GC (и сложно сделать свой, т.к. нет доступа к стеку), ни вообще какого-либо способа пропатчить код в рантайме или повыставлять защиту страниц памяти.


По поводу эффективности бинарного формата в плане размера. Если интересно, у меня есть свой экспериментальный транслятор байт-кода Java в WebAssembly, вот работающий пример приложения. Так вот, размер JavaScript — 274 кб, размер WebAssembly — 488 кб.

konsoletyper
0

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

konsoletyper
0
Тут все просто — Frontent разработчики используют React/NG2/Vue и тд. Зачем им GWT и подобные абстракции? Все и так отлично.

Во-первых, я же уже сказал — ИМХО, компилятор из Kotlin в JavaScript больше нужен Kotlin-разработчикам, которые захотели ещё писать фронтэнд, а не фронтэнд-разработчикам, которые уже счастливы с JS.


Во-вторых, если так мыслить, то вообще никогда ничего нового не будет появляться. В 80-е разработчики прекрасно жили с Cobol. А сейчас люди прекрасно сидят на Java, так что, теперь из этого следует, что Kotlin не нужен? Нет, оказалось, что на это есть какой-то спрос, нашлась ниша. Возможно, найдётся ниша для компилятора в JavaScript. Пока самая очевидная — это та, которую я назвал, но реальность как всегда такова, что выстрелить язык может там, где никто этого не ожидал. Глупо не попытаться использовать шанс, если он есть. Ведь хуже будет, если Scala.js выстрелит, в этом случае Kotlin придётся запрыгивать в уходящий поезд.


Еще и WebAssembly завезли

А это вообще мимо кассы. WebAssembly — это средство для бородатых дяденек, пишущих на C и C++ запускать свои шустрые программы в браузере. Мне кажется, пересечение с "традиционным" фронтэндом и всей его экосистемой — минимальное. Вот это отличный шанс туда запрыгнуть новым многообещающим языкам.

konsoletyper
0
JavaScript без своей экосистемы — не очень вкусен.

GWT прекрасно живёт в своей экосистеме. Сборка — Maven, хранилище артефактов — тот же maven central или jcenter, линтеры — checkstyle и PMD, библиотеки и фреймворки — специально написанные для GWT или портированные с "большой" Java, либо обёртки вокруг JS-ных библиотек. Минификацию делает сам (причём сильно лучше новомодных webpack-ов), модульность на уровне модулей Maven.


Постоянно поддерживать интеграцию с ней то же мало приятного.

Мне кажется, это утверждение из разряда "у страха глаза велики". Там достаточно много всего, но интегрироваться с этим не так сложно, есть вещи более-менее устоявшиеся. Ну и да, всё "быстро меняется" в восторженных статьях на Хабре, а весь мир по-прежнему сидит на jQuery.


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

Нет, это попытка сделать инструмент для тех, кто хочет fullstack на Kotlin. Кому нормально писать фронтэнд на JS, тот и дальше будет писать на JS.

konsoletyper
+1

Разумеется, так сделать можно, и на первых порах мы возможно так и поступим. И тут придут апологеты TypeScript и начнут сравнивать размеры npm-пакетов. В перспективе, возможно, удастся скомпилировать kotlinc с помощью какого-нибудь AOT-компилятора или полностью вырезать из компилятора все зависимости от Java.

konsoletyper
0

Насчёт Silverlight не знаю, а вот GWT я успешно использовал в production на протяжении трёх лет и очень был доволен. Но у GWT есть фатальный недостаток — он не понимает Kotlin. Хочу пояснить — я хорошо знаю JavaScript и вполне способен писать приложения на каком-нибудь Angular. Проблема в том, что я этого делать не хочу:


  1. Мне JavaScript банально меньше нравится.
  2. Язык — это не только сам язык, но и ещё целая куча технологий вокруг него — библиотеки, системы сборки, IDE, линтеры и т.п. Лично мне неприятно всё время переключать в голове контекст с одного на другое. Да и объём знаний там немаленький, пришлось кучу времени потратить, чтобы переключиться с Java на JavaScript. И собственно язык — это пара дней работы, вся остальная куча времени пришлась на ту самую пресловутую экосистему.
konsoletyper
+5

Жертвы действительно есть:


  1. Компилятор (пока) работает на JVM, соответственно, чтобы полноценно компилироваться в JS, не хватит только node.js/webpack, нужно ещё ставить JVM. Для JS-разработчика, у которого стоит нода, но не стоит JVM, это может стать препятствием.
  2. У нас (пока) нет лоадера для webpack. Т.е. нужно настраивать gradle для компиляции Kotlin и webpack для всего остального. Это, конечно же, не касается пользователей какого-нибудь google closure compiler.
  3. Система типов Kotlin изначально проектировалась с прицелом на JVM, система типов TypeScript — с прицелом на JS. В итоге, не всегда Kotlin так же хорошо ложится на JS, как TypeScript. Например, в Kotlin поддерживается перегрузка функций по типу параметров, чего нет в JS (и следовательно, в TS). Таким образом, по умолчанию Kotlin при компиляции функций с параметрами дописывает к их названию некий суффикс, полученный страшным алгоритмом. Конечно, есть аннотация @JsName, которая позволяет явно задать имя функции в JS. Другой пример — отсутствие union types в нашей системе типов.
  4. Мы тащим с собой жирный рантайм (1,2 мб), и (пока) не умеем из него вырезать неиспользуемые части.
  5. Мы (пока) не умеем компилироваться инкрементально.

Как видите, часть проблем здесь из разряда "пока не успели сделать" (в основном по тулингу, у нас 1.2 как раз будет на нём фокусироваться), а часть "ничего нельзя поделать". В первом случае надо подождать, во втором — мы пытаемся минимизировать боль от последствий.


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

konsoletyper
+2

Я так понимаю, возможность писать на одном языке бэкэнд и фронт-энд для Android, iOS (скоро) и веба. TS компилируется только в JS. Конечно, можно TS на ноде гонять, но не всем подходит нода. Опять же, можно TS гонять на Cordova/React Native, но нативное приложение должно шустрее работать. Плюс синтаксические вкусности, которых нет в TS:


  • declaration site/use site variance;
  • нелокальные return-ы (например, можно взять и сделать return из вызывающей функции прямо из лямбды, переданной в функцию map);
  • смарткасты;
  • богатые возможности для построения DSL;
  • навороченные корутины

Ну и не забывайте про тех пользователей, которые уже используют Kotlin на JVM, и хотят на нём же писать и веб-клиент (либо с нуля, либо переписать на нём имеющийся JS-клиент).


В принципе, тот факт, что мы не сможем поспеть за TS в плане лёгкости интеропа и тулинга (да и TS уже банально прочно занял нишу), лично мне понятен. Мой персональный приоритет — это создание именно такого языка, который позволял бы легко бы писать fullstack-приложения. К сожалению, это пока не совсем так, но я надеюсь, мы движемся в правильном направлении и скоро Kotlin станет полноценным языком для fullstack-разработки.


С другой стороны, мы не сможем перегнать TS, но нам есть, куда расти. Задачей к 1.1 было стабилизироваться, т.е. задизайнить минимальный набор необходимых фич, причём так, чтобы потом не ломать совместимость. Ну и конечно, пофиксить баги и реализовать недостающие языковые фичи, доступные в Kotlin JVM. Некоторыми вещами в интеропе пришлось пожертвовать (например, теми же строковыми enum-ами), но никто не мешает их сделать к следующим версиям языка.

konsoletyper
0

(промахнулся)

konsoletyper
+1

В документации не раскрыта вся суть. А суть в том, что корутины в Kotlin не привязаны ни к конкретным библиотеками, ни к конкретным типам. async/await из примера — это просто библиотечные функции, можно писать свои для различных фреймворков. И ещё — generate/yield — это тоже библиотечные функции, реализованные поверх того же механизма корутин. Подчеркну, что там нет никакой внутренней магии специально для разработчиков stdlib, кто угодно может написать свои реализации generate/yield и async/await.

konsoletyper
+2
Чего можно ждать в обозримом будущем от KotlinJS?

Инкрементальной компиляции, минификации aka dead code elimination (так же известный под названием tree shaking, которое меня немного выбешивает), куча примеров кода, работающего с современными фреймворками (такими, как React) и документации. Это совсем ближайшее время, буквально несколько месяцев. Дальше пока не планировали (или по крайней мере, я не в курсе). Так же надеюсь, что будет время немного улучшить интероп, например, завести правильные external enum. Ещё есть пользователи, которые очень хотят генерацию микромодулей и ES6, мы держим это в голове, и активно обсуждаем, но конкретных сроков у нас сейчас нет.


Ещё в Kotlin есть такой минус, что достаточно неудобно разрабатывать проект, в котором есть общая кодовая база между JS и JVM. Этот момент непосредственно к JS не относится, там больше по части общекомпиляторной работы и всякого тулинга. Я так понимаю, что мы над этим будем работать в ближайшее время, но по срокам пока непонятно, скорее всего, в обозримом будущем удастся выпустить common-модули в экспериментальном режиме.


Будет ли возможность помечать методы интерфейса как уже реализованные?

Не вполне понятно, что вы понимаете под этим. Можете пример из мира JS (и по возможности, пример деклараций в TS)?


Библиотека kotlin.js — 1Mb, планируется ли существенно сократить его размер?

Сократить — нет, подружить вывод компилятора с различными минификаторами или разбить на кусочки поменьше — возможно. Конечно, мы понимаем, что такая здоровенная библиотека — это плохо. Кстати, после uglify она где-то в 2 раза ужимается, а после gzip и того более.


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

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

konsoletyper
0

Ну а толку-то? По сути, не нужен для этого никакой цикл. Это будет эквивалентно какому-нибудь if..else if… else. На уровне синтаксиса это можно подсахарить. Вон, в Kotlin есть when, который по сути является сахаром для if..else if. Но чуда не ждите, на рантайме от этого быстрее не станет. Когда в Java 7 вводили switch по строкам, задизайнили фичу так, чтобы её можно было эффективно реализовать.

konsoletyper
+1

Я так понимаю, это всё-таки не документируется в спеке языка. Т.е. компилятор может реализовывать switch по строкам в принципе как ему захочется. А вот в JDK это поведение чётко описано. Просто так особенности реализации в javadoc-ах не описывают, т.е. именно такой способ вычисления String.hashCode — это всё-таки публичный контракт. Учитывая особенности публичного контракта JDK, компилятор может порождать эффективную реализацию (что и делает javac).

konsoletyper
0

Что "делается"? Инстанс объекта создаётся? Нет, ничего не создаётся, но вычисление hashCode требует знания, какое у объекта внутреннее состояния. Без знания логики конструирования объекта о внутреннем состоянии судить нельзя, следовательно невозможно вычислить hashCode.


Зачем компилятору вычислять hashCode? А как он сгенерит такое:


switch (str.hashCode()) {
    case FOO_HASHCODE: if (o.equals("foo")) { ... } else goto default;
    case BAR_HASHCODE: if (o.equals("bar")) { ... } else goto default;
    default: { ... }
}

Ну хорошо, мы можем и дальше так продолжать играть в вопросы. Давайте так, если есть что предложить — предлагайте (и даже можете кинуть JSR в JCP). Только не в духе "хорошо было бы сделать", а в духе "как ИМЕННО сделать" с учётом разных нюансов. Я уверяю, при попытке сформулировать предложение вы сами всё поймёте.

konsoletyper
+1

Отсутствие в компиляторе знания о том, как именно в этих объектах реализован hashCode. Отсутствие знания в компиляторе о том, как именно сконструировать экземпляр объекта в compile-time. Для частных случаев (например, строки, enum-ы) это знание есть.

konsoletyper
0

Внутри case будет цепочка if/else if, где с помощью equals проверяется каждый вариант.

konsoletyper
+3

Её менять нельзя из-за того, что в java 7 появился switch по строкам. А он как раз реализован через switch (str.hashCode()), и компилятор вставляет предвычисленные хэш-коды прямо в байт-код.

konsoletyper
+2
Глупые, детские хотелки. Язык — это очень серьёзный проект, такое не пилится школотой во время каникул!

Это да, вот только помимо языка (парсер, семантический анализатор, библиотеки, дизайн), ещё есть рантайм, а это тоже куча человеко-лет. Причём, ещё непонятно, что из указанного требует больше времени на разработку. Скажем, написать хороший оптимизатор, хороший JIT, хороший GC — та ещё задача.


Ясно. В третьем классе детям рассказали про ЯП.

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


Да зачем?? Причём тут вообще «язык» и все эти дебри из мира виртуальных машин? Кто вообще сказал, что нам нужна VM?!!!

Какие такие дебри. JIT и AOT — это всего лишь про рантайм. C++ обычно реализуется в виде AOT-компиляторов, Java — JIT, но может быть и наоборот (те же Excelsior JET — пример Java, компилирующейся AOT). И вообще, понятие VM — это достаточно расплывчатая штука. Вот есть какой-то IR у компилятора. Можно ли интерпретатор этого IR назвать VM? А AOT-компилятор в нативный код? А JIT? Что такое LLVM (у которого две последние буквы VM)? Таки VM или компиляторный бэкэнд? Почему GCC не содержит в себе буковки VM, хотя на деле он очень похож на LLVM?


Бред сивой кобылы. Таких «задач» — две на мильён, с какого перепугу нам в языке это нужно??

В языке это не нужно. Это нужно в рантайме. А нужно это с целью добиться лучшей производительности кода, написанного на языке. За счёт hot swap можно прямо во время исполнения собрать профиль и на основе профиля скомпилировать код более эффективно и заменить старую версию на новую.


Да нифига не хотим! Много из вас «накоммитило» в гитхабы? Единицы по десятку строк. Так зачем вам исходники, в которых вы всё равно ни черта не понимаете??

Это на уровне энтузиастов так. А на уровне компаний может быть иначе. Компании может стать интересен какой-то opensource-проект, и она может специально людей набрать, которые будут сидеть на з/п и в этот проект контрибьютить. Со всякими Linux и JVM примерно так дела и обстоят.


рисовать в небе пони и насиловать JVM в жалких попытках реванша перед .NET;

Это какой такой реванш перед .NET? Как бы мы живём в мире, где .NET всё ещё не убил Java, и вроде бы не собирается убивать. Наоборот, судя по объявлениям о работе у Java дела намного лучше идут. Если кто и убьёт Java (вместе с .NET в придачу), то какой-нибудь JavaScript, но мы же будем верить в лучшее, и понадеемся, что этого не произойдёт?

konsoletyper
0
А вот если код «писан индусами», не понимающими что, как и где вообще происходит (знаменитое «к пуговицам претенции есть?»), вот тогда — с GC всё будет тормозить и жрать память, как не в себя, а без GC — вообще развалится к чертям собачьим.

Есть одна контора, где код, видимо, писан индусами (хотя почему-то основной офис у них в Санкт-Петербурге). Только вопрос: а есть ли в природе хоть одна такая же крутая IDE, написанная крутыми мужиками на C++? Ах да, IDE крутым парням не нужны, vim хватает всем, а IDE — это костыль для индусов, которые не понимают, что они пишут.

konsoletyper
0
Так давайте определимся, уплотняющий GC или нет. А то получается, что преимущества приводятся для их объединения.

В современных рантаймах GC уплотняющие, и это подаётся как преимущество, а не как недостаток, вопреки тому, что уплотнение даёт оверхед.


А откуда вообще следует, что она, ну, есть? Ведь для пространственной локальности необходимо, чтобы, условно, следующий объект в памяти, к которому вы обращаетесь, лежал в вашем кешлайне. Как это связано с компактифицирующим GC?

Собственно, причины две. Во-первых, в survival space объекты будут лежать кучно, и они могут взять и влезть в кэш. Во-вторых, при выделении памяти в eden space она будет всегда выделяться строго последовательно, а не в дырках.


С generational GC, да, связано, но не с компактифицирующим.

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


В вышеупомянутом подходе их вообще нет.

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


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

konsoletyper
+1
И при уплотнении тоже никакого оверхеда?

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


Никаких локов, ничего, не нужно оно там. GC правда может эффективнее?

Кстати, я где-то видел презентацию, где в Graal добавили region-based memory management, и не получили ощутимого прироста производительности. GC не может эффективнее, но может в ряде случаев приближаться по эффективности. По крайней мере, аллокация и освобождение столь же дешёвые, минус расходы на обход графа объектов.

konsoletyper
0
А почему, собственно? Фактически это — те самые арены, которые так не любят некоторые.
Многолетний многомиллиардный эксперимент с Java/.NET — в общем и целом, провалился.

Пожалуйста, не пишите глупости, не позорьтесь, если не разбираетесь в предметной области.

konsoletyper
0

Ну так это сравнение между ручным и автоматическим управлением памятью. Подсчёт ссылок — это тоже вид автоматического управления памятью. И с ним у них был бы подобный оверхед по памяти. И вызван он был не GC, а тем, как представлены строки в CLR. А мой вопрос стоял не относительно памяти, а относительно влияния трассирующего уплотняющего GC на (пространственную) локальность, и как следствие — на производительность.

konsoletyper
–1
Вы хотите сказать что для языков с GC над этим думать не нужно? А для чего тогда целые библиотеки подобные Guice создают?

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


А тогда о чём мы вообще спорим?

Ну я где-то читал (точно не помню, но по-моему, это была последняя редакция dragon book), что уплотняющий GC даёт лучшую локальность, чем компенсируется его оверхед. Сейчас конкретных ссылок на конкретные исследования дать не могу.


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

Это так для legacy-мира. Но тем же Java и JS по 20 лет, .NET — 15 лет. Для них за это время написана целая куча библиотек, инструментов и "прочего". Опять же, есть средства интеропа нативных библиотек с управляемыми рантаймами. И да, разработчики обёрток, которые для managed-рантаймов заворачивают библиотеки, должны думать о явном освобождении ресурсов. Но 1) разработчики приложений об этом уже не думают 2) постепенно старые нативные библиотеки переписывают под новый рантайм.

konsoletyper
+2
Это с какого перепугу? Какие-такие накладные расходы при использовании какогого-нибудь unique_ptr?

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


Что, с GC у вас ресурсы утегать не будут? Будут, ещё как будут, если вы запутаетесь в том кто и когда ими владеет.

Будут, но достаточно редко.


Иначе бы подобные ужасы были бы не нужны.

Эти ужасы только в узком слое интеропа с нативной библиотекой UI.


Какое, блин, достижение. А в цифрах — не, не покажите? Что именно вам это даёт? И как часто? С точки зрения конечного пользователя, пожалуйста.

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


Всё как раз наборот. Иначе вот этого бы не было. Поверьте — у Apple есть много недостатков, но умения создать красивые, приятные в работе, программы — у них не отнять. И вот для них — GC противопоказан.

Вот это как раз весьма и весьма спорное утверждение. Я так понимаю, вопрос memory management решался ещё во времена objective C, который является по сути макронадстройкой над C, т.е. требуется поддерживать семантику C, которая не предполагает наличие специальным образом сделанного рантайма. Отсюда, единственным возможным выбором для Objective C является консервативный GC, который, как известно, не умеет инкрементальной и параллельной сборки, т.е. тормозит.

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

Например, потому, что GC всё-таки даёт ощутимо меньшие накладные расходы, чем смартпоинтеры, в том числе по памяти (GC не требуют тащить дополнительные 32 бита на объект для счётчика). Особенно в многопоточном коде. А ещё у смартпоинтеров проблема с циклическими ссылками. А ещё GC уплотняют кучу, этим улучшая локальность доступа к памяти (знаю, современные алгоритмы malloc умеют частично решать проблему фрагментации памяти, но ключевое слово — частично).


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

konsoletyper
0

Как раз Common Lisp — это плохой пример. В нём ровно две фатальные проблемы: динамическая типизация и макросы. Именно они делают код на CL совершенно нечитаемым и трудноподдерживаемым, уж не говоря о его минималистичном синтаксисе.

konsoletyper
+8

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


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


3) Data Transfer Object Is a Shame
«DTO плохо» взамен предлагается переложить сериализацию/десериализацию на саму сущность, минуя DTO

Да, вот только есть ещё такой подход, как single responsibility principle, такой важный, что является частью SOLID, и статьи, расписывающие преимущества SOLID, не менее логичны, чем статьи Егора. Вот только практика (именно практика, а не маленькие игрушечные примеры) показывает, что SOLID работает, а подходы Егора — нет.


Другой пример — Егор предлагает заменять utlity-методы объектами, т.е. вместо CollectionUtils.sort делать класс SortedList, и сортировать список, создавая экземпляр этого класса. Я не вижу никакой разницы, т.к. всё равно ничего не инкапсулируется, и более того, конструктор — это фактически и есть вызов статического метода (называемого <init>). Ну а уж по поводу критических по производительности кусках кода я вообще промолчу.


Так вот, проблема в том, что действительно, приходится писать не самые "чистые" вещи в коде. И это проблема не глупых разработчиков, это проблема глупых средств разработки. Были бы языки программирования повыразительнее, можно было бы включить перфекционизм на 142% и писать бескомпромиссно чистый код. Однако, тут проблема в том, что излишне выразительные языки программирования обладают тем недостатком, что их сложно выучить и сложно эффективно реализовать компиляторы и тулинг, но что ещё важнее, — они слишком непредсказуемые.

konsoletyper
0

Я уже писал чуть выше, почему есть смысл писать на GWT, а не на JS. Незнание JS — это не причина использовать GWT, но зато за использование GWT есть много других причин.

konsoletyper
0
Вместо того, чтобы просто писать на js, часть логики будет на java(gwt), а часть на js

В случае с GWT (может, даже не с GWT, а со сферическим транспайлером Java -> JS в вакууме) писать JS-код нужно сравнительно редко. Даже в GWT, где всё плохо и действительно приходится частенько заводить JSNI, писать кода на JS приходится очень и очень мало. В моём проекте на GWT из 100 тысяч строк на Java на JS было написано о силы строк 50.