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

Пользователь

Отправить сообщение

Про идеологические недостатки решения: было бы справедливо отметить что:


  • Использование исключений в данном случае лежит полностью на совести автора. При желании можно было бы организовать монаду и тогда было бы все "по функциональным канонам". Другое дело не понятно какой от этого выигрыш.


  • Ленивость вычислений в конкретно этой ситуации зависит не от языка, а от реализации. К текущему коду можно добавить небольшой кусок и выражения станут вычисляться лениво.
Если цель «придерживаться принципов функционального программирования», то все сделано верно. Но учитывая что Kotlin в основном объектно-ориентированный язык, то конечно операции типа `solve` и `toString` лучше делать с помощью наследования и полиморфизма вместо `when`.
Возможности сослаться на `it` уровнем выше нету, переменная полностью экранируется.
Не то чтобы мы от этого страдаем. Мне кажется предположение о неизменяемости само по себе неправомерно во многих случаях, например `List.size`.
Спасибо за статью, приятно почитать аргументированное и конструктивное мнение.

По поводу «проблем» которые не будут чиниться — то что затронуто в этой статье не больше и не меньше чем code-style. То бишь что тут чинить если это by-design заранее обдуманные случаи использования.

`it` в принципе не предназначен для callback-ов, в документации так и написанно — именуйте параметр кроме простейших случаев. Функция `let` действительно редко встречается в моей практике, но она незаменима для цепочек вызовов с функциями принимающими аргумент, например `mylist.let {LinkedList(it)}.filter {it > 0}`. В случае с `with` мне кажется очевидным что `getLatestComment()` не относится к `dbHelper`, но если это не так, то действительно лучше обойтись явными вызовами по старинке.

В общем, я согласен с автором что иногда неприятности встречаются в коде, но не согласен что это вина языка. Надеюсь давно обещанный продвинутый форматер решит подобные проблемы.
Фразой про необходимость (корректных) измерений я хотел сказать что совсем не очевидно что быстрее — программа на C++ или на Java.

Многие распространенные мифы про тормознутость Java строятся на (не совсем корректных) прикидках.

Ну вот давайте и прикинем. Известно что узкое место в работе (нормального) компьютера это доступ в память. Разработчику не жалко потратить десятки а иногда сотни тактов процессора чтобы избежать лишнего доступа в кеши процессора или в оперативку. 90% времени процессор пользовательского компа простаивает в ожидании подгрузки чего-нибудь из памяти.

Когда загружается программа на C, это более-менее полотно ассемблерных инструкций для всех возможных веток выполнения программы. Вроде понятно.

Когда загружается Java программы, она состоит из JVM байт-кода и интерпретатора JIT. А теперь фокус: байткод и интерпретатор зачастую вместе занимают меньше места чем соответствующий ассемблер. Этим экономится драгоценное место в памяти и кешах. Достигается это тем что JVM байт-код это хорошо упакованные высокоуровневые инструкции, которым могут соответствовать десятки команд ассемблера.

Вот так и получается что действия, которые выполняются относительно редко (95% всей логики), логично интерпретировать. Действия которые выполняются часто и влияют на производительность «распаковывают» из байт-кода в машинные команды различной степени оптимальности.

Когда Вы запускаете IDE вроде IntelijIdea, 5 минут в начале она подтормаживает, происходит тот самый «прогрев» — инициализация и распаковка кода. После этого она начинает ускорятся, и через полчаса летает (это мои собственные ощущения). Готов поспорить что если гипотетически скомпилировать ее в машинные команды (реально не получится ибо рефлекшн), то эти 5-20 минут разогрева потратятся просто на загрузку разбухшего кода в память и прогрев кешей.
На данный момент SpaceX планирует повторно запустить один из уже приземленных первых ступеней этой осенью. Если запуск удасться, это и будет доказательство целесообразности, так как они доставят полезную нагрузку без постройки еще одной ракеты. Будет интересно посмотреть затраты на починку и тестирование, но они должны быть сильно меньше чем $30M. Еще одна статья расходов для повторного запуска это увеличение страховых выплат для груза, но это решается многократными успешными полетами.
Про магию JVM лучше всего слушать Шипилева, рекомендую например вот это: https://youtu.be/nHiEKXpG_4M
Примерно в середине доклада вроде рассказывает про спекуляции с виртуальными методами тоже (тема статьи)
Тестов таких не очень много, насколько я понимаю. Сложно найти программы/проекты на Java/C++ которые бы делали одно и тоже. Не так давно я где то видел сравнение tcp/ip библиотек, там библиотеки на Java были в топе, но это не совсем то.
Если бы люди мерили реальную производительность реальных программ в реальных условиях, глупых холиваров и предубеждений было бы меньше
Ничего не будет. Я уже знаком со Smalltalk.

Вы рассматриваете языки сами по себе, без всего что их окружает. Такой подход совершенно не описывает реальную полезность технологий. Java как язык могла бы спокойно компилироваться в машинный код и это действительно был бы урезанный C++. Я (и некоторые другие) в восторге не от языка, а от JVM-the-platform, и мои комментарии в основном относятся к платформе, а к языку.
Вы хотите сказать что в статье предлагается изучить 8 (!!) языков и все это на стадии «новичок»?

Повторяюсь, я говорил про линковку библиотек, а не управление памятью. Как много людей по Вашему знают что происходит при динамическом подключении .o? Или еще лучше .dll на Windows? Ответ — единицы, остальные «воспринимаю это как данность» (и отлично живут и работают).

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

Ну или венец творения — что происходит при ошибках и крашах? В частности при обращении по NULL? Что, «система гарантирует корректность»? Нет, не везде и не всегда. Разные ОС делают это по-разному. И все это необходимо досконально знать чтобы написать минимально-надежную программу.

Простите за прямоту, но мне кажется Вы оперируете какими-то стереотипами что C/C++ сложнее или проще чем Java. В C полно магии на уровне операционки и/или процессора которые нужно хорошо понимать чтобы написать просто корректную программу, я уж не говорю быструю. И наоборот, хорошие Java программисты великолепно разбираются в процессорах, операционках, компиляторах и много в чем другом, что позволяет им выжимать максимум из JVM (те самые случаи когда Java программа быстрее C++ аналога 0_о )
Если под «гимнастикой ума» понимать то что предлагает например Ruby, то Java конечно не в той категории. Несмотря на ограничения синтаксиса, гибкость Java не подлежит сомнению именно из-за количества паттернов и фраймворков которые ее поддерживают. С академической точки зрения Java (JVM) интересна как первый язык решивший проблему линковки библиотек. Вся та мощь и гибкость которую предоставляют полноценная рефлексия, пост-обработка бутекода, аннотации и класслоадеры никогда не снилась C++ и подобным.
Невероятно, но Java вообще изучать не предлагается. Java является промышленным языком #1 последние 10 лет по количеству работы, проектов, и инфраструктуры. Кроме того, Java весьма интересна как язык своим дизайном, например Python и другие языки открыто заимствовали идеи библиотек и фраймворков. С академической точки зрения, JVM это предмет для обязательного изучения любого программиста-теоретика и/или перформансника. Одна JMM чего стоит!
Кажется мы расходимся в определении «сахара».

Замечу что если под «не сахарными» расширениями понимать например то, что есть в Swift, где расширение не сильно отличается от метода по свойствам и видно глобально, то получается забавная картина. Swift не имеет аналога Kotlin DSL ровно из-за глобальности их функций-расширений, то есть «хардкорные» фичи проигрывают «сахару» по функциональности. Постройка древовидных DSL очень важная фича Kotlin, и уж точно не является сахаром, так как обеспечивает статические гарантии структуры.
А, извиняюсь, не до конца понял исходный вопрос.

Про JIT я неточно выразился. Имелся в виду любой оптимизирующий компилятор который работает через границы модулей.
Я так понимаю речь идет о not-null ассертах. Кто-то замерял на сколько замедляется выполнение программы с ними? JIT вполне способен убрать лишние проверки из исполнения, если например они дублируют друг друга. К тому же если я правильно понимаю как JVM оптимизации работают, код с проверками может работать быстрее так как JVM не нужно эмулировать NPE в случае нулевых ссылок.
Под «синтаксическим сахаром» обычно понимается конструкции которые дублируют что-то еще, существующее в языки и/или абстракции, которые «протекают». Функции-расширения не могут быть заменены обычными функциями (в отличие от C#) и не являются методами из-за отличающихся правил диспатча (в отличие от Swift). Это отдельная логическая сущность в Kotlin которая не может быть выражена через остальные примитивы языка.

Расширения не дают доступ к приватным членам класса из вне, пожалуйста проверь это утверждение на коде
«Сахарные примеси аспектного подхода в (Kotlin)» — такого ругательства я еще не слышал. Ни к сахару, ни к аспектам функции-расширения Kotlin особого отношения не имеют, IMO.
Спецификатор `inline` в Котлин гораздо сложнее чем например в C++. Он меняет семантику функции, например влияет на вывод типов, поведение generic параметров или на вид публичного Java-api. Прирост быстродействия в случае с лямбдами это только один из эффектов.

Информация

В рейтинге
Не участвует
Откуда
Санкт-Петербург, Санкт-Петербург и область, Россия
Дата рождения
Зарегистрирован
Активность