пятница, 3 апреля 2020 г.

[software.thoughts] Интересно и толково про проблемы OpenSource

На RSDN-е всплыла интересная ссылка: https://youtu.be/YDBE7OM7-mM?t=35578. Это доклад Андрея Ситника на HolyJS 2019 Piter. Доклад как бы из двух частей: первая часть про OpenSource, а вторая, якобы, про Web. Но мне показалось, то обе части доклада посвящены одной и той же проблеме. И то, что автор доклада рассказывает про ситуацию c front-end-ом, можно без особых проблем перенести на любую другую область разработки софта.

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

Одна из основных мыслей, высказанных Андреем Ситником, а именно "популярность != надежности/качеству", может показаться провотиворечащей реальности. Но здесь я, скорее, склонен с автором согласиться. С той лишь поправкой, что для популярного инструмента гораздо легче найти в Интернете рецепты для простых задач и решения для простых, наиболее часто встречающихся проблем. Так что если вам с помощью популярного инструмента нужно решать какие-то типовые и несложные задачи, то вероятность сделать это "малой кровью" все-таки больше, чем если выбирать мало известный инструмент.

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

Еще очень важная вещь, которая проистекает из рассказанного Андреем Ситником -- это необходимость помощи в раскрутке малоизвестных OpenSource проектов. Может показаться мелочью, но каждая звездочка на GitHub-е, каждый лайк в соцсетях, каждый дополнительный +1 на Reddit-е или HackerNews, не говоря уже о ретвитах/репостах оказывают огромную помощь разработчикам малоизвестных OpenSource проектов. Т.к. отсутствие этих мелких признаков внимания очень сильно снижают мотивацию разработчиков. Поэтому если вам на глаза попадается новость о каком-то OpenSource проекте, который показался вам интересным или просто симпатичным, то не сочтите за труд, лайкните эту новость. А если вы еще и сделаете ее репост где-нибудь от своего имени, то реально сделаете большое дело.

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

Но, с другой стороны, у разработки OpenSource нет нормальной экономической модели. Т.к. если не брать 1% топовых открытых проектов, которые либо спонсируются (прямо или косвенно) различными компаниями, либо смогли выйти на окупаемость за счет модели двойного лицензирования или продажи техподдержки, то подавляющее количество открытых проектов -- это либо в прямом смысле one-man show, либо результат работы совсем небольших коллективов. И жизнеспособность таких небольших проектов в условиях кризиса является далеко не праздным вопросом.

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

Не факт, что такая тенденция уже сформировалась. И даже если сформировалась, то ощутимые последствия станут заметны в относительно отдаленной перспективе (лет через 10-15).

В общем, еще раз порекомендую посмотреть доклад. Он будет интересен даже тем, кто далек от разработки front-end-а. Т.к. рассказывает о более важных и общих вещах.

Я же напоследок дам еще одну интересную ссылку: Seven Stages of Open Software. ИМХО, имеет смысл с этими стадиями ознакомиться перед тем, как ввязываться в открытие своего кода и подумать, а до какой стадии ты сам хотел бы дойти.

четверг, 2 апреля 2020 г.

[life.cinema] Очередной кинообзор (2020/02-2020/03)

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

Холоп (2019). Мне зашел очень неплохо, посмотрел с удовольствием.

Джентльмены (The Gentlemen, 2019). Смотреть можно спокойно. Фильм добротный. А вот получить удовольствие от просмотра... Тут не знаю. Я ждал от Гая Ричи большего. Получилось разве что добротно.

21 мост (21 Bridges, 2019). Весьма смотрибельно. Динамично, в меру разговоров, в меру экшена. Хотя финал оказался немного предсказуем, но в целом это впечатления не испортило.

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

Пушки Акимбо (Guns Akimbo, 2019). Так плохо, что даже хорошо. Мне понравилось, но я и не ждал ничего кроме лютого трэша от данного произведения. И, как по мне, именно в качестве трешового ремейка "Адреналина", но не с крутым уголовником в главной роли, а с хипстером-задротом, и следует это кино воспринимать. Ну и, соответственно, воздержаться от просмотра, если подобная смесь вас не интересует.

Под водой (Underwater, 2020). Вот вообще ни разу не шедевр, но смотреть было интересно, не смотря даже на то, что подводный монстр в конце был как-то не к месту (имхо). Может быть потому, что нормальной фантастики на тему более-менее качественно снятых катастроф на подводных объектах давно не было.

1917 (2019). Ожидал от фильма сильно большего. Такое впечатление, что единственной целью его создателей было продемонстрировать исключительно выдающуюся операторскую работу. А на все остальное, включая здравый смысл, просто забили. Единственный хороший момент -- это показ того, как человек на войне в любую секунду может погибнуть: вот ты только отошел за водой, обернулся, а твой друг уже смертельно ранен, а через пару минут его и нет. Вот это, как по мне, в фильме показали здорово. Но это не стоит двухчасового просмотра.

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

Правосудие Спенсера (Spenser Confidential, 2020). Как-то все посредствененько. Есть ощущение, что это не полноценный самодостаточный фильм, а попытка забросить пробный шар на что-то вроде серии фильмов с одними и теми же персонажами. Спасает разве что наличие пары-тройки известных актеров, которые придают происходящему хоть какой-то вес и солидность.

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

Джуманджи: Новый уровень (Jumanji: The Next Level, 2019). Ну так себе. Первый фильм был неплох, а этот явная попытка заработать на успехе первого фильма не утруждая себя поиском чего-то нового и интересного.

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

Ангелы Чарли (Charlie's Angels, 2019). Мог бы получится недорогой аттракцион из категории "Телохранитель киллера" или "Гемини", если бы не желание девочек снять про девочек и для девочек с режиссером-девочкой. И да, для подобной фигни сексизм в критике вполне уместен.

Герой (2019). Редкая бредятина и Александр Петров, как обычно, местами сильно выбешивает. Но картинка класcная. Местами офигенно классная. Настолько, что очень обидно становится, что к такой картинке прилагается такая муть в довесок.

Звериная ярость (Primal, 2019). Николас Кейдж, к сожалению, в нормальных фильмах уже не снимается. И "Звериная ярость" лишь подтверждает это. Так что смело можно проходить мимо.

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

суббота, 28 марта 2020 г.

[prog.actors] Почему я не считаю упомянутых в статье на Хабре акторов настоящими акторами

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

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

Это вообще достаточно сложная проблема, с которой я регулярно сталкивался будучи тимлидом. Делаешь code review подчиненного и явно ощущаешь, что реализация переусложнена, что можно проще. Говоришь "здесь что-то слишком сложно, должно быть проще", а на встречный вопрос "А как проще?" сходу ответ дать не можешь. Потому что для того, чтобы дать такой ответ, нужно самому сесть и плотно поработать над этой задачей. А это значит, что ты мало того, что будешь вынужден переделать работу, которую должен сделать твой подчиненный, но еще и не успеешь сделать что-то другое, что ты никому не можешь делегировать.

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

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

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

среда, 18 марта 2020 г.

[prog.flame] Ай да молодцы в Dropbox! Взяли и переписали свой sync engine на Rust. Ну молодцы же, да?

Речь про вот этот пост: Rewriting the heart of our sync engine. Dropbox переписал часть своей системы, отвечающей за синхронизацию, с Python-а на Rust и выкатил на публику победную реляцию об этом достижении.

Вот казалось бы, имей голову на плечах и напиши все сразу на C++... И работало бы это все годами.

Не нравится C++, а Rust-а еще нет не свете? Но ведь есть Ada, есть Eiffel...

Но нет. Сперва нужно написать на Python.

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

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

Ну и для тех, кто типа умеет читать между строк: это пост не про то, что C++ хорош, а Rust плох. Rust хорош. И для подобных задач его выбор ничуть не хуже, а может и лучше, чем выбор C++. Он про то, что выбор по принципу "пользуем то, на что надрачиваем, а ничего другого просто не знаем", в конце-концов приводит к потере времени и денег.

Да и еще не могу удержаться и не пройтись по любимой теме:

Almost all of our code runs on a single thread (the “Control thread”) and uses Rust’s futures library for scheduling many concurrent actions on this single thread. We offload work to other threads only as needed: network IO to an event loop, computationally expensive work like hashing to a thread pool, and filesystem IO to a dedicated thread. This drastically reduces the scope and complexity developers must consider when adding new features.

Это как раз то, что SObjectizer умеет делать с самого начала: распределять работу между сущностями, каждая из которых работает на нужной ей контексте. Хоть на общей рабочей нити, хоть на пуле потоков, хоть на выделенной отдельной рабочей нити. Собственно, для этого SObjectizer и создавался много лет назад.

четверг, 12 марта 2020 г.

[prog.c++.tiredness] Написал мета-функцию transform и чё-та приуныл...

Сегодня с утра потребовалось реализовать мета-функцию transform для списка типов в C++. Т.е. в transform передается мета-функция трансформатор и список типов, а на выходе получается преобразованный список типов. Типа такого:

using T = transform_t<std::decay, type_list<int, int&, const string&>>;
// T == type_list<int, int, std::string>

Задался целью сделать этот transform самостоятельно, опираясь только на детали реализации других мета-функций, которые написал где-то в начали осени 2019-го по следам прочитанных в Интернете материалов.

Убил часа полтора. Тупил невероятно. Но сделал. Не заглядывая в Интернет.

Никакого удовольствия от решения этой частной задачки не получил. Зато возникло ощущение, что чего-то для меня уже слишком много. Либо конкретно C++. Либо программирования вообще...

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

Либо специализацию, поскольку C++ реально подза*бывает, чем дальше, тем больше. И сам язык, в котором невероятная мощь сочетается с невероятной кривизной и, имхо, слишком уж высоким темпом развития в последние годы. И фрагментированное коммьюнити с чрезвычайно сильно развитым NIH-синдромом.

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

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

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

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

вторник, 10 марта 2020 г.

[prog.c++.bicycle] I'm working on the first draft of experimental type-safe router for RESTinio

The express-like router is available in RESTinio for several years. I think it is a very easy to use tool, that is familiar to many developers. But it has some congenital defects I wanted to repair for a long time.

The congenital defects of express-like router

The propensity to errors

The first defect is that express-like router is error-prone and isn't friendly for repeated cases. Let's look at one of the examples from RESTinio, express_router:

пятница, 6 марта 2020 г.

[prog.c++] Реинкарнация procxx под именем procyy

К сожалению, библиотека procxx выглядит окончательно заброшенной своим автором. Поэтому я решил не отсылать PR в procxx, т.к. его вряд ли приняли бы, а сделал форк под другим именем:

https://github.com/eao197/procyy

Этот форк лежит, в общем-то в том же виде, в котором и procxx. Никаких тестов, продвинутых примеров, проектных файлов для CMake или чего-нибудь еще. Как взял, так и оставил :)

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

Нет и планов добавить procyy в conan, vcpkg, hunter или какой-нибудь другой менеджер зависимостей. Лично мне это не нужно, а если кому-то нужно, тот пусть и берет на себя все эти заботы. Простите.

PS. Кидаться в меня помидорами по поводу качества кода нет смысла, программист из меня так себе. Получилось как получилось. Конструктивные соображения по поводу улучшения кода продуктивнее оформлять в виде issues.

среда, 4 марта 2020 г.

[prog.c++.actors] Обновленная версия презентации "Actor Model and C++: what, why and how?"

Обновил свою презентацию более чем трехлетней давности. Поскольку что-то в ней уже устарело за это время. А что-то все еще актуально. Так же добавил в презентацию ссылки на малоизвестные широкой публике разработки actor-zeta и rotor. Ну не CAF-ом же единым, в конце-концов...

Так же эта презентация доступна на SlideShare, а PDF-ку отдельно можно скачать с SourceForge.

Я сделал пост на Reddit-е и у себя в LinkedIn. Если кто-то сочтет возможным опубликовать ссылку на SlideShare еще на каких-то ресурсах, то это будет здорово.

[prog.c++.actors] Довелось еще раз посмотреть в сторону CAF

Решился намедни обновить свою старую уже презентацию Actor Model and C++: what, why and how?, поскольку за прошедшее время многое уже изменилось. И, наверное, впервые с 2016-го года еще раз посмотрел в сторону главной на данный момент реализации модели акторов для C++, библиотеке CAF (она же C++ Actor Framework).

Несколько прифигел.

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

Во-вторых, похоже, уже нет шансов хоть как-то побороться с CAF-ом за популярность в C++ мире. Больше двух тысяч звезд на github-е против шести десяков (именно десятков) у SObjectizer-а. На HackerNews посты про CAF собирают под сотню поинтов, тогда как аналогичные для SObjectizer-а -- в лучшем случае 2-3 поинта.

Что называется, почувствуйте разницу.

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

Собственно, вывод из этого простой: никогда SObjectizer не станет популярным и широко востребованным инструментом среди C++ников.

Следовательно, нет смысла пытаться двигаться в этом направлении. Значит SObjectizer будет развиваться дальше без оглядки на то, чтобы кому-то понравится. Или чтобы добавить в SObjectizer что-то, что позволит ему "конкурировать" с чем-то еще.

Это означает, что в последующие версии SObjectizer-а будет добавляться только та функциональность, которая потребуется нам самим. А так же те фичи, которые у нас попросят. Не более того. Нам SObjectizer нужен как относительно небольшой (а по сравнению с нынешним CAF-ом он реально небольшой), практичный и мощный инструмент.

Ну, например, мы используем SObjectizer в тестах RESTinio для проверки поведения RESTinio в условиях многопоточности. И этот сценарий использования SObjectizer-а выглядит вполне себе естественным. Поскольку SObjectizer относительно небольшой. Тогда как применение для этих целей CAF-а мне сложно представить... Наверное, можно. Но, блин, как из пушки по воробьям.

Так что постараемся сохранить небольшой размер и сложность SObjectizer-а. А создание комбайна на все случаи жизни оставим разработчикам CAF-а.

В-третьих, в очередной раз пришел в выводу, что у меня лично, видимо, совсем другие представления о разработке софта, нежели у авторов CAF-а. Поэтому SObjectizer получается именно таким, какой он есть: многословный и несколько старомодный, базирующийся на ООП из конца 1980-х и 1990-х. Ибо я на собственном опыте неоднократно убеждался, что в таком стиле можно писать софт, который развивается в течении многих лет, который вбирает в себя все больше и больше функциональности, разрастаясь в объеме в разы, если не на порядок. И который, при этом, все еще остается обозримым и поддающимся сопровождению.

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

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

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

Ну и, если вспомнить "во-вторых", остается надеятся, что SObjectizer станет выбором для тех немногих, кто, как и я, не очень хочет писать сложный прикладной код в стиле CAF-а.

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

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


Надеюсь, что обновленную версию "Actor Model and C++: what, why and how?" получится опубликовать сегодня во второй половине дня.

понедельник, 2 марта 2020 г.

[prog.c++] Есть желание реинкарнировать библиотеку procxx

Тут такое дело... Жила-была себе небольшая, простая в реализации и симпатичная C++11 библиотека procxx для запуска дочерних процессов в Unix-ах. Мы нашли её года четыре назад и несколько раз за это время использовали то тут, то там. И даже отослали автору какие-то PR.

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

Проект procxx выглядит заброшеным. В репозиторий несколько лет ничего не коммитили, на issue нет реакции. Сам автор, судя по его мизерной активности на github-е, переключился на Rust. Так что, в принципе, можно было бы сделать pull-request для procxx, но смысла в этом я лично не вижу. Тем более, что подобный вопрос я открыл в качестве issue, но никакой реакции пока не последовало (вполне ожидаемо).

Тем не менее, выбрасывать procxx "на помоечку" (с) не хочется. Ну реально простая и удобная библиотека без каких-либо серьезных наворотов в реализации (по крайней мере до того, пока я не запустил туда свои шаловливые ручонки). Осваивается влет, буквально берешь и пользуешься.

Поэтому есть желание реинкарнировать procxx.

Но т.к. автор ничего на эту тему не сказал, то мне стремно использовать procxx в названии моего форка. Было желание назвать обновленную версию procxxrv (от procxx-revisited) или procxx-ng (от procxx-new-generation). Но с такими названиями получается, что я как бы пытаюсь заработать очки на популярности старой procxx. Что не есть хорошо.

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

Посмотреть на то, что есть в procxx-revisited на данный момент можно здесь (ветка revisited). Любые конструктивные замечания/предложения, естественно, приветствуются.

суббота, 29 февраля 2020 г.

[prog.flame] Наглядное подтверждение изречения про два типа языков программирования...

...которое, если я не ошибаюсь, звучит как-то так: "Есть всего два типа языков программирования: те, которые все ругают, и те, которыми никто не пользуется". И вот статья про язык Gо под названием "I want off Mr. Golang's Wild Ride" наглядно показывает, что Go принадлежит к языкам первого типа.

Вообще, как мне думается, данная статья является еще одним проявлением давнего вселенского плача под названием "worse is better". Может из молодежи кто-то не в курсе, но лет 15 назад вокруг этого самого "worse is better" в этих наших интернетиках были большие срачи. Хотя те, 15-летней давности срачи были всего лишь очередной волной подобных срачей после самой формулировки этого принципа в начале 1990-х.

Т.е. суть в том, что в реальной жизни "побеждает" не то, что "лучше" по какому-то абстрактному набору "хороших" критериев. А то, что позволяет "легко", "просто" и "дешево" решать насущные проблемы здесь и сейчас. При этом работающее решение может быть не самым красивым, эффективным и надежным. Но оно, определенно, является good enough.

Собственно, упомянутая статья наглядно это демонстрирует на примере косяков языка Go и его стандартной библиотеки. Да, косяки есть. Да и вообще сам по себе Go не столько прост или, правильнее сказать, примитивен. Это откровенно "тупорылый" язык.

Только вот те, кто гнобят Go и противопоставляют Go другим, гораздо более сложным в освоении языкам, не понимают простой вещи: именно эта "тупорылость" и делает Go мегаценным для определенной части рынка разработки ПО.

Потому что в этой части рынка ничего сложнее нынешнего Go и первых версий Java/C#, в которых еще и генериков не было, просто не приживается.

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

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

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

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

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

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

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

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

Ну и следствием из этого является то, что языки вроде Go, Java или даже чистого Си, находят гораздо более широкое применение, нежели что-то вроде Modula-2, Eiffel, Ada или Rust. Просто Go и Java гораздо ближе к народу, под которым прежде всего понимается множество "реалистов".

Отсюда и плач на тему "worse is better": если ты "пурист-прагматик" (не говоря уже про случай "пуриста-идеалиста"), то то, что для тебя "worse", для "реалиста" как раз таки "better". И наоборот. В общем, извечный спор "тупоконечников" и "остроконечников". Ну а упомянутая вначале статья, похоже, была написана "пуристом-прагматиком". Отсюда и ее содержание.


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

среда, 19 февраля 2020 г.

[prog.sadness] Чем больше шуму вокруг C++20 тем больше хочется уйти с C++ вообще

Да уж... Давно я не испытывал такого сильного желания свалить с C++ на какой-нибудь другой язык программирования, как после новостей о завершении работ над C++20 😒 😒 😒

Я даже не могу понять, что тому виной. Может быть то, что хочется держаться подальше от языка, в котором, в принципе такая хитровывернутая система модулей, что сходу в нее и не въедешь. Тем более после 35 лет вполне себе успешного существования без этих самых модулей... Как по мне, так C++ нужно было оставлять без модулей и дальше, а проблему долгой компиляции решать каким-то другим способом.

Может быть потому, что не хочется в очередной раз проходить путь адаптации кардинальных изменений в новом стандарте. Я уже через это прошел когда появился C++98, а потом и C++11. Оба раза это занимало годы и годы оглядываний на старые компиляторы, в которых стандартом либо еще не пахнет, либо же он реализован частично. Даже сейчас еще бывают случаи, когда приходится пользоваться компилятором с неполной поддержкой C++11... Так что впереди еще лет десять привыкания к C++20.

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

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

Может быть потому, что C++ реально начинает прогибаться до земли под собственной тяжестью, поскольку когда пишешь вот в таком вот стиле, то начинает казаться, что слишком уж много приходится указывать вручную:

class Demo {
  [[nodiscard]] bool empty() const noexcept;
  ...
};

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

Может быть это старческая боязнь перемен...

А скорее всего все это в совокупности.

И хотя умом понимаю, что адекватной замены C++ все равно нет. И у меня нет особых проблем с решением на С++ тех задач, с которым приходится сталкиваться...

Но все равно есть какое-то подсознательно-неосознанное ощущение "а не пора ли свалить с этого перегруженного корабля, у которого на мостике творится одно, в машинном отделение -- другое, а в трюме все вообще по-другому?"

воскресенье, 16 февраля 2020 г.

[life.cinema] Как бы я попробовал бы сделать продолжение Терминатор-2

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

Итак, идея в том, что в рамках рассказанной в первых двух фильмах истории Skynet отправил в прошлое не двух T-800, а трех. Второго из них уничтожили в первом "Терминаторе", третий стал главным героем "Терминатор-2". А вот первый был отправлен Skynet-ом в прошлое еще раньше, еще до действий первого фильма. Его задачей было отследить происхождение Джона Коннора.

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

[prog.c++] Пришли вести об окончании формирования C++20, только вот...

...почему-то вспоминается старое проклятие: "Да шоб ты жил в эпоху перемен!"

Возможно, на мне сейчас сказывается усталость после нескольких непростых рабочих недель, но грядущее пришествие C++20 я воспринимаю как непростую историю с Python2 и Python3. В этом посте постараюсь объяснить почему у меня такое ощущение.

Мне думается, что только вот сейчас, к 2020-ому году в большинстве своем состоялся уход от C++98/03 к C++11/14/17. Т.е., несмотря на то, что где-то еще живут большие кодовые базы на C++98, все-таки нормой становится современный C++. И это хорошо.

Хотя еще много мест, где современный C++ -- это в лучшем случае C++11 на уровне gcc-4.8.

И поэтому даже сегодня, в 2020-ом году, при разработке C++кода, которому грозит либо применение на широком спектре компиляторов, либо же который разрабатывается под специфические нужды конкретного заказчика, то и дело приходится ограничиваться C++11... Если честно, я на этом фоне даже думаю, что в прошлом году сильно ошибся, переписав SObjectizer-5.6 сразу на C++17, а не на C++11 (ну или хотя бы на C++14).

И вот что тут важно: в принципе, даже проект, который был написан на C++17, при необходимости можно переделать под C++14 или С++11. Понятно, что делать это неприятно, но если за это платят, то почему бы и нет.

Механика такого даунгрейда так же понятна и уже неоднократно проходилась. Вещи типа [[nodiscard]] или [[fallthrough]] помещаются под макросы, фишки типа constexpr if или structured binding не используются, fold expression разворачиваются вручную... Да, объем работы увеличивается. Но все-таки он не превышает некоторого психологически-приемлемого уровня.

Но C++20 вносит в язык несколько принципиально новых возможностей. Навскидку: модули, концепты, короутины и гораздо более продвинутый constexpr. Как отказаться от их использования так, чтобы разработанный код можно было использовать и в C++11, и в C++20, я не представляю.

А это означает, что C++20 вводит еще более строгий и жесткий "водораздел" между старым и новым кодом, чем это было даже после появления C++11. Т.е., если код начал писаться под C++20, то только под C++20 его и можно будет использовать. И простого даунгрейда написанного под C++20 кода под старые C++ стандарты (пусть даже старым будет C++17) уже не будет.

Для разработчиков прикладного кода на C++ это вряд ли будет представлять проблему. А вот для разработчиков библиотек, вроде нас, это будет проблема. Ведь если портировать библиотеку под C++20, то ее не смогут использовать те, кто вынужден оставаться на C++11/14/17. А таких в ближайшие 4-5 лет, а то и больше, будет большинство.

Что, как мне кажется, для библиотеко-писателей означает одно: если хочешь, чтобы твоя библиотека использовалась широко, то сиди на C++11 и не рыпайся. До C++32. Потом можно будет на C++20 перебраться.

PS. Сам в последнее время для одного из клиентов вынужден оставаться в рамках C++11. И не смотря на то, что между C++14 и C++11 изменений не так уж и много, мне кажется, что даже по сравнению с C++14 одиннадцатые плюсы уже неюзабельны :(

среда, 12 февраля 2020 г.

[prog.mistery] SObjectizer имеет настолько сложный и непонятный API...

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

С того самого момента, как мы начали рассказывать на публике о SObjectizer-е, постоянно приходится читать вопросы из категории "Почему все так сложно" или "А почему у вас такое плохое соотношение signal-to-noise?". Эти упреки в сложности SObjectizer-а и его API преследуют нас настолько давно и долго, что я сам почти уже поверил, что так оно и есть. И что не смотря на все усилия по упрощению SObjectizer-овского API ничего путного не получается. Вероятно, проблема в ДНК авторов этого API и тут уж ничего не поделать, остается только посыпать голову пеплом, платить и каяться регулярно приносить свои извинения, мол, хотели как лучше, но нешмогли...

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

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

И вот как это понимать? SObjectizer настолько сложен и непонятен, что можно взять и написать на нем работающую систему ни разу не обратившись с вопросами к разработчикам SObjectizer-а?

Больше похоже на то, что кому нужно, тот берет и делает. А кому не нужно, тот звиздит на форумах о непонятном API и о недопустимости использования snake_case нотации, да еще с суффиксом _t в именах типов.

воскресенье, 9 февраля 2020 г.

[prog.c++] Вероятно, проблема управления зависимостями в C++ не настолько проста, как может показаться

За прошедшие две недели довелось порешать несколько разных задачек и еще раз задуматься о некоторых вещах, связанных с разработкой на C++. Одна из этих вещей -- это подтягивание зависимостей в C++ проект.

Бытует вполне обоснованное мнение, что у современного C++ есть две большие и, по-моему, взаимоувязанные проблемы, касающиеся наполнения C++ проекта зависимостями.

Первая из этих проблем в том, что для C++ нет официальной стандартной системы сборки. Де-факто стандартом потихоньку становится уёбищный CMake. Но именно что становится, однако таковым еще не является. Поэтому запросто можно наткнуться на нужную тебе библиотеку, которая должна собираться древним make вкупе с autotools. Ну да ладно, этой проблемы сейчас касаться не будем. Просто напомним о ее существовании.

Вторая проблема -- это отсутствие де-факто стандартного механизма управления зависимостями для C++ проектов. И чтобы не лезть совсем уж в глухие дебри, проще поговорить о разработке некого прикладного софта под одну платформу. И, поскольку под Linux-ом у C++ вполне себе неплохие перспективы, то за основу возьмем именно Linux, а не Windows или macOS.

Как мне представляется, для некроссплатформенных разработок, заточенных под Linux, сейчас самими распространенными подходами являются: использование штатного менеджера зависимостей конкретного Linux-репозитория, Conan и vcpkg.

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

Поэтому остается вариант с использованием ортогональных к операционной системе менеджеров зависимостей типа Conan и vcpkg. Целью которых, как мне представляется, является снижение сложности управления зависимостей до уровня запуска одной единственной команды, вроде conan install или vcpkg install.

Что, безусловно, хорошо. Но, разве что для проектов уровня HelloWorld-а.

Т.е. если вам нужно быстренько набросать прототип, в котором нужно несколько сторонних библиотек, то Conan/vcpkg как раз то, что нужно. Ну вот, скажем, захотели вы попробовать RESTinio или SObjectizer, написали свою простенькую программку и воспользовались Conan/vcpkg дабы не тратить свое время на настройку зависимостей. Все хорошо.

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

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

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

В Conan-е можно фиксировать версии сторонних библиотек, тогда как vcpkg версионирования зависимостей не поддерживает. И может показаться, что в этом плане vcpkg полное говно.

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

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

Например, в X версии 1.2.3 нет важной для нас фичи и мы сделали форк X в который и добавили новую функциональность. Функциональность, которая нам нужна здесь и сейчас, но которую не факт, что примут в X, а даже если и примут, то еще непонятно когда. Соответственно, нам нужно уметь одним легким движением руки заменить оригинальную X 1.2.3 на пропатченную нами X 1.2.3-our-critical-new-feature.

Другой пример: в X версии 1.2.3 мы обнаружили какую-то проблему и сообщили о ней разработчикам X. Те начали разбираться с ней и в отдельной ветки разработки X сделали, как им кажется, исправление этой проблемы. Но прежде чем выкатывать это исправление в master, они хотят, чтобы мы погоняли исправленную версию у себя. Соответственно, нам нужно добавить к себе в зависимости какую-то промежуточную версию X из какой-то bug-fix-branch.

В случае с vcpkg для этого есть решение -- мы клонируем vcpkg и правим в этом клоне portfiles так, как нам нужно. Запросто можно заменить оригинальный X 1.2.3 на X 1.2.3-our-critical-new-feature, либо же указать в portfile в качестве источника конкретный коммит из конкретной bug-fix-branch.

А вот в ситуации с Conan, как мне представляется, нам нужно будет поднимать собственный сервер Conan, на котором нам нужно будет публиковать свои варианты чужих библиотек. И для промежуточных версий X из bug-fix-branches нужно будет делать какие-то собственные "левые" релизы X.

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

Что, боюсь, означает, что единый репозиторий зависимостей, вроде JavaScript-ового npm, Ruby-нового RubyGems или Rust-ового Crates, будет служить больше целям обеспечения низкого порога входа в C++ную экосистему, нежели для упрощения разработки коммерческого софта на C++.

Но кроме этих двух моментов есть и еще один...

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

BitBucket вот через несколько месяцев тупо удалит все Mercurial репозитории. Перестанут быть доступны не только репозитории с исходниками, но и все tarball-ы, которые размещались в Download-секциях.

Или, скажем, нашумевшие истории с авторами популярных проектов, которые в один прекрасный момент решили послать всё и всех куда подальше и удалить свой проект к херам. Полагаю, случай с leftpad и недавняя история с травлей автора Actix-Web благодарными Rust-оманами -- это хорошие примеры.

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

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

При этом, опять же, выясняется, что системы управления зависимостями, в которых мы сами можем "опакечивать" чужие библиотеки, дают нам большую безопасность. Мне думается, что править время от времени portfiles в собственном форке vcpkg будет несколько проще и удобнее, чем держать собственный Conan-сервер с опубликованными там собственными версиями чужих библиотек. Но, может быть, это просто потому, что Conan-ом я, к счастью, не пользуюсь и мало что про него знаю.

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

суббота, 1 февраля 2020 г.

[life.cinema] Очередной кинообзор (2020/01)

За минувший месяц накопился более-менее объемный список просмотренных фильмов, которым не стыдно поделиться. Что и делаю :)

Как обычно, в начале идут фильмы, которые понравились больше. В самом конце, традиционно, откровенный шлак.

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

Ford против Ferrari (Ford v Ferrari, 2019). Не смотря на то, что тема "производственной драмы" мне не близка, да еще и к автомобилям я совершенно равнодушен, фильм все равно доставил массу удовольствия. Особенно некоторые моменты, связанные с корпоративными дрязгами в большой компании. Наверное лучший фильм из вышедших в 2019-ом.

Идеальный пациент (The Perfect Patient, 2019). Мне понравилось. И история сама по себе интересная, и рассказана хорошо, и европейцы кино как-то по своему снимают, не так как в Голливуде. Так что посмотрел с удовольствием.

Мистер Олимпия (Bigger, 2018). Очень незамысловатый, простой, прямолинейный, но почему-то отлично зашедший мне фильм. Наткнулся случайно и посмотрел потому, что ничего другого на глаза не попалось. Был приятно удивлен. Но, вполне возможно, подобное кино на любителя и понравится далеко не всем. Мне же понравилось как актер, игравший главного героя, сумел передать образ фанатично увлеченного своим делом человека. Из тех, кто слегка "не от мира сего".

Коррупционер (The Corrupted, 2019). В общем неплохо. Но мне не понравился финал. Такое ощущение, что его специально сделали помягче, чтобы не превратить фильм в совсем уж мрачную криминальную драму.

Мидуэй (Midway, 2019). Красочно, мощно, известных актеров подтянули. Однако воспринимается все это как не очень дорогой аттракцион. И картинка на экране видно, что нарисована, и некоторые персонажи раздражают, и повествование какое-то поверхностное. В общем, явно хотели переплюнуть "Перл-Харбор" от 2001-го года, но не смогли.

Решала. Нулевые (2019). Простенько, недорого. Но можно посмотреть. Хотя несколько лет назад выходил другой фильм "Решала" из двух частей. Так вот как по мне, так лучше посмотреть первую часть именно того "Решалы".

Девятая (2019). Снято дорого и красиво. Но не цепляет.

Роман Израэл, Esq. (Roman J. Israel, Esq., 2017). После просмотра трейлера ожидал совсем другого. Поэтому был разочарован. Как по мне, так фильм скучный и неинтересный.

Безумный куш (Danger One, 2018). Фильм разочарование. Первая половина зашла просто отлично. Казалось, что за небольшие деньги сняли что-то стоящее и цепляющее. Но бездарно слитый финал все напрочь испортил.

Последняя пуля (Disturbing the Peace, 2020). Дешевый отстой. Смело можно не смотреть.

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

Как ни странно, но в этом "Терминаторе" мне понравились две вещи:

среда, 29 января 2020 г.

[prog.c++] Почему люди выбирают RESTinio

Давеча мы внезапно получили неплохую реакламу на reddit-е в виде комментария от ned14 (известного, например, как автор Boost.Outcome). Позволю себе процитировать этот комментарий здесь полностью:

I recently had to choose a lightweight modern C++ web framework, and the choices came down to oatpp or https://github.com/Stiffstream/restinio.

I ended up choosing restinio because:

  1. Writing C++ for restinio is much more C++ idiomatic - no macros, one uses {fmt} to append to responses, string views and zero copy are pervasive, it leverages as much of C++ 20 including proposed standard feature reference libraries as possible. This makes sorting out dependencies messy, but it's a once off investment, and https://github.com/cpp-pm/hunter hand waves away the dependency problem in any case.
  2. restinio exposes the ASIO it wraps, which makes the rest of the team feel much more comfortable. ASIO is widely understood, whereas custom internal async i/o frameworks are often sources of surprise. Also, we know how to hook and extend ASIO to do custom stuff, that's team embedded knowledge.
  3. There were recent comparative benchmarks for restinio not written by the author https://github.com/ngrodzitski/test20171219 which showed restinio can be class leading in performance for the thing tested, even marginally edging out Beast for that test.

I don't want any of this to diss oatpp. I just wanted to explain what motivated me to not choose it, which may aid its authors in telling a better story to improve adoption.

For the record, restinio adoption has gone okay so far, a bit of resistance from some team members about some of its design choices, but everybody is just loving {fmt} for efficiently generating responses. The team is literally benchmarking our REST server for production right now, so far looks promising, it definitely can max out a 1Gb NIC, still awaiting the 10Gb and 40Gb NIC results.

Т.е., если не дословно, но по сути:

  1. Работа с RESTinio происходит в более идиоматическом для C++ стиле, нет макросов, применяются fmt, string_view и вообще сделан упор на библиотеки, которые должны стать частью будущих стандартов C++.
  2. RESTinio дает доступ к ASIO, а у команды есть большущий опыт правильного приготовления ASIO, и это как-то безопаснее, чем иметь дело с самодельным фреймворком для асинхронного I/O.
  3. Были найдены сравнительные бенчмарки, которые показывают, что у RESTinio вполне себе конкуретноспособная производительность.
  4. Пока что RESTinio более-менее хорошо зашла проектной команде. Были недовольные теми или иными проектными решениями в RESTinio, но всем нравится применять fmt для формирования ответов на запросы. И прямо сейчас проводятся бенчмарки разрабатываемого командой REST-сервера. Пока что результаты выглядят обнадеживающими.

Было очень приятно получить такой отзыв. Значит не зря мы над RESTinio работаем. Ну а может кому-то этот отзыв поможет сделать правильный выбор ;)

От себя добавлю, что в случае с RESTinio мы еще более открыты к предложениям, чем с SObjectizer. Поскольку RESTinio еще совсем молодой проект, который даже до версии 1.0 пока не добрался, то мы с удовольствием прислушаемся к пожеланиям пользователей для того, чтобы наполнить RESTinio той функциональностью, которая сделает разработку RESTful приложений на C++ простой и приятной.

вторник, 28 января 2020 г.

[prog.c++] Перевел демо-проект so5-dining-philosophers на свежие версии SObjectizer, so5extra, fmtlib

Год назад на Хабре была опубликована большая статья "«Современные» обедающие философы на C++ посредством акторов и CSP", в которой рассматривалось несколько реализаций решения задачи "Обедающих философов" на SObjectizer (как на базе агентов, так и на базе голых нитей с mchain-ами).

За прошедшее время многое поменялось: вышли новые версии SObjectizer-а (5.6 и 5.7) несовместимые с SO-5.5, на котором были написаны примеры для статьи. А Atlassian принял решение удалить в 2020-ом году с BitBucket-а все Mercurial репозитории. Эта участь ожидает и исходный репозиторий, в котором были собраны примеры кода для статьи.

Так что этот демо-проект подвергся модернизации. Во-первых, он переехал на GitHub: so5-dining-philosophers. Во-вторых, код был переведен на свежие версии зависимостей: SObjectizer-5.7.0, so5extra-1.4.0 и fmtlib-6.1.2.

Поэтому теперь для so5-dining-philosophers нужен C++17. Старая версия под C++14 и SO-5.5 доступа под тегом 20190129.

Несколько слов про адаптацию старых решений под новый SObjectizer:

  • потребовалось исправить сигнатуру метода state_watcher_t::changed. Этот метод в SO-5.6/5.7 должен быть noexcept. В данном демо-примере noexcept означает не то, что changed() не будет бросать исключений, а то, что нет возможности продолжить работу, если исключение все-таки выскочило, поэтому нужно грохнуть все через std::terminate;
  • потребовалось исправить сигнатуру метода do_deliver_message в собственном типе mbox-а. В SO-5.6/5.7 этот метод уже не помечен как const, а в SO-5.5 эта отметка долго сохранялась по соображениям совместимости;
  • пришлось изменить подписку у некоторых агентов. Ранее использовалась нотация state.event<Signal>([]{...}), теперь она не поддерживается и нужно использовать унифицированный вариант: state.event([](mhood_t<Signal>){...}). Это было одним из ломающих совместимость изменений в SO-5.6;
  • в нескольких вызовах receive для чтения входящих сообщений из mchain-ов потребовалось указать handle_all(), поскольку SO-5.6/5.7 требуют, чтобы для receive/select было указано количество обрабатываемых сообщений (т.е. нужно вызывать handle_n/handle_all/extract_n явным образом). Контролируется это во время компиляции. О том, как этого удалось достичь была отдельная статья на Habr-е;
  • потребовалось поменять создание диспетчеров. Вместо вызовов вида create_private_disp(env)->binder() начиная с SO-5.6 нужно писать make_dispatcher(env).binder(). Собственно, это одно из принципиальных отличий SO-5.6 от SO-5.5.

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

Но важность сохранения совместимости все равно осознал. Постараюсь больше ломающих нововведений в SObjectizer не вносить и держать совместимость в рамках SO-5.7 как можно дольше.

четверг, 23 января 2020 г.

[prog.c++] Стали доступны SObjectizer-5.7.0 и so5extra-1.4.0

Главное нововведение в SObjectizer-5.7.0 -- это поддержка send_case в функции select(). Т.е. теперь select() может не только читать сообщения из нескольких каналов, но и отправлять сообщения в каналы как только целевой канал оказывается готов для приема нового сообщения. Увидеть это можно в новом примере mchain_fibonacci, сделанного по мотивам аналогичного кода из A Tour of Go.

Фичу эту хотелось добавить в SObjectizer уже давно. Но вот только сейчас сошлись звезды. И по этому поводу я даже решился пойти на то, чтобы поломать совместимость с не так давно выпущенной версией 5.6. Поломка, правда, не такая уж и серьезная, старая функция case_, которая ранее использовалась для чтения входящих сообщений из канала в select(), теперь называется receive_case. Так что перейти с SO-5.6 на SO-5.7 можно посредсвом банального Search-and-Replace. Но формально совместимость сломали, да.

А в so5extra-1.4.0 самое важное -- это смена лицензии. Если предыдущие версии распространялись под двойной лицензией и для использования в закрытом коммерческом ПО нужно было покупать лицензию, то теперь so5extra распространяется под BSD-3-CLAUSE лицензией и может использоваться бесплатно.

Полный список изменений для SO-5.7.0 можно увидеть здесь, для so5extra-1.4.0 -- здесь.

Думаю, что нужно специально подчеркнуть то, что разработка SO-5 и so5extra окончательно перехала на GitHub. Вскоре на BitBucket поудаляют Mercurial-репозитории, так что жить приходится с git-ом на GitHub-е. Я, хоть и плююсь постоянно от git-а и отдыхаю душой и телом, когда представляется случай воспользоваться Hg, но вынужден смирится :(

Отдельно пару слов о будущем SObjectizer-а.

Проект живет. Если кто-то столкнется с какими-то проблемами, то дайте нам знать, обязательно постараемся помочь. Если кому-то нужна помощь с SObjectizer-ом, то смело обращайтесь. Собственно, это наша работа, так что без поддержки не оставим. В том числе расскажем нужен ли вам SObjectizer или нет. Поскольку мы клиентов не накалываем, то можно быть уверенным в том, что продавать слона мы вам не будем. Если SObjectizer вам не подойдет или вообще C++ не нужен в вашей задаче, то так и скажем. Благо такое уже случалось.

А вот вопрос о том, когда будут выходить новые версии SObjectizer-а является открытым. Большие фичи, которые хотелось сделать в SO-5 лично мне, уже сделаны. Поэтому больших релизов на горизонте не предвидится. Мелкие корректирующие релизы будут выходить по мере надобности.

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

В завершении скажу немного про свои ощущения от применимости SObjectizer-а.

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

Так что не на правах рекламы, а просто в порядке "поделится опытом": если у вас есть необходимость работать с многопоточностью в C++, то возьмите что-нибудь типа SObjectizer-а. Не обязательно SObjectizer. QP/C++, CAF, Boost.fibers, да что угодно, что может дать вам акторов и/или CSP-шные каналы... Но лучше, конечно же, SObjectizer ;)

среда, 22 января 2020 г.

[prog.c++] Шаблоны, но уже не против копипасты.

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

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

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

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

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

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

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

struct testing_traits_t {
   using client_type = testing_client_info_t;

   static first_property_type get_first_property(const client_type * cln) {...}
   static second_property_type get_second_property(const client_type * cln) {...}
   ...
};

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

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

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

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

PS. Желающим поговорить про то, почему все это неправильно и что правильнее было бы разделить приложение на отдельные модули со строго определенными интерфейсами, что позволило бы использовать mocking при тестировании и пр. правильные вещи, могу сказать одно: добро пожаловать в реальный мир.

PPS. Если вы сами владеете старым C++ным или C-шным проектом и испытываете сложности с его поддержкой/развитием, то вам сюда. Возможно, мы сможем помочь ;)

понедельник, 20 января 2020 г.

[prog.rust.flame] "Говорил я вам. Не прислушались. Так и получилось. Как говорил я вам..."

На выходных, лениво пожевывая попкорн почитывал срачик на Habr-е, в котором светлые рыцари ордена safe Rust-а громко доказывали, что писать код так, как сделал автор Actix-Web, ни в коем случае нельзя. Занимательное чтиво, аж душа пела.

Пела потому, что когда лет 5-6 назад первые упоротые в своей воинственности Rust-оманы начали бегать по профильным форумам и убеждать всех тех, кому Rust вообще не был интересен, что Rust -- это самое лучше, что произошло с софтостроением после изобретения перфокарт, некоторые скептически настроенные старпёры сердито ворчали: "Ну подождите пару-тройку лет, в этот ваш Rust обязательно придут люди, которые начнут использовать unsafe, скажем так, весьма творчески. Вот тогда и посмотрим, насколько Rust окажется safe в реальной-то жизни".

Ну вот и дождались.

Вполне ожидаемо оказалось, что это во влажных мечтах оторванных от реальности фанатов в боевом коде на Rust-е unsafe либо не будет вообще, либо он будет локализован, тщательно оттестирован и аналь огорожен.

Просто одно дело, когда ты в свободное время пишешь pet project на своем любимом языке для души. Совсем другое -- когда у тебя есть жесткие цели, сроки, бюджеты, конкретные люди со своими проблемами и куча других факторов, которые и отличают настоящую разработку от экспериментов с перспективной технологией. Вот автор Actix-Web-а столкнулся с задачей выжать из своего Web-сервера максимум производительсти и был вынужден прибегнуть к unsafe. И это еще был весьма квалифицированный и мотивированный разработчик. Что уж говорить об писателях индусокода (всех национальностей), которые неизбежно будут пихать unsafe в код, потому что дедлайн, а времени ублажать компилятор нету.

PS. А для всех свято верующих в то, что в реальной жизни unsafe в Rust будут использовать исключительно правильно, а прецидент Actix-Web-а -- это досадное исключение, ВИА "Громыка" исполняет свой незабвенный шлягер, строчка из которого была вынесена в заголовок заметки.

суббота, 18 января 2020 г.

[prog.open-source] Автор Rust-ового фреймворка Actix-Web: "I am done with open source."

На HackerNews разгорелся один из самых больших срачей, который попадался мне там на глаза: A Sad Day for Rust (steveklabnik.com). Этот срач посвящен блог-посту "A sad day for Rust" (как я понимаю, за авторством кого-то из именитых Rust-евангелистов). В свою очередь этот блог-пост посвящен эмоциональному решению автора Rust-ового фреймворка Actix-Web закрыть свой проект. На GitHub-е по адресу https://github.com/actix/actix-web сейчас размешен только относительно небольшой README-файл, озаглавленный как "Actix project postmortem".

В "Actix project postmorten" автор пишет о том, как он задолбался бороться с борцунами с unsafe. Что работа над Actix-Web перестала приносить удовольствие. И что он решил послать все и всех куда подальше:

It’s been three years since I started actix project (time flies). I learnt a lot, i meet new people, I found language that I really like and want to use it fulltime, I found fun job. But damage to the project's reputation is done and I don’t think it is possible to recover. Actix always will be “shit full of UB” and “benchmark cheater”. (Btw, with tfb benchmark I just wanted to push rust to the limits, I wanted it to be on the top, I didn’t want to push other rust frameworks down.) Everything started with actix, then actix-web and then actix-net. It took a lot of time to design api and architecture. Each of this projects was rewritten from scratch at least 4-5 time. I hope I expanded some boundaries and found few new patterns, I hope other developers will check source code and find inspiration to move even further. Nowadays supporting actix project is not fun, and be part of rust community is not fun as well.

I am done with open source.

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

Любой проект может сдохнуть в любой момент.

Итак, первое впечатление, как это ни странно -- это вспомнившаяся откуда-то "мудрость": если долго сидеть на берегу, то можно увидеть, как мимо проплывает труп твоего врага. Так уж вышло, что мы так же пилим свой "типа Web-фреймворк", но для C++. Поэтому в какой-то мере RESTinio и Actix-Web конкуренты. В небольшой степени, но все-таки.

И вот один конкурент сходит с дистанции (по крайней мере в своем первоначальном виде). А мы остаемся. Мы живы, движемся вперед и это не может не радовать.

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

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

Се ля ви. Ничего не поделаешь.

Все вокруг все знают гораздо лучше тебя...

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

Собственно, то что эмоционально рассказал в "Actix project postmortem" Николай Ким -- это оно и есть. В чистом виде.

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

Rust-сообщество зачастую напоминает стадо упоротых разрушителей старого мира во имя новой религии, имя которой "safe во все поля".

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

Причем отдельным фетишем для упоротых Rust-оманов является safe. Который должен быть во все поля.

А если safe во все поля нет, то это ай-ай-ай, это все старый мир, который должен быть до основания... И далее по тексту.

Просто иначе я не могу себе представить причин происхождения тех волн агрессии на Actix-Web от сторонников safe Rust. Ну реально: вот есть проект, он сделан, он работает, он показывает крутые результаты. Ну есть там unsafe. Ну так не просто же так он там оказался. Да и если проект работает, покрыт тестами, новый функционал добавляется, баги правятся, так не все ли равно, есть там unsafe внутри или нет? Вам шашечки или ехать, в конце-концов?

Но вот оказывается, что шашечки важнее. <img src="СергейЛавров.jpg">

Так за чей счет сей банкет?

И, пожалуй, главное впечатление -- это актуальность моих недавних заметок про OpenSource и заработок на OpenSource (раз и два).

Отлично понимаю вот эти слова Николая Кима в его "Actix project postmortem": "Seems everyone believes there is large team behind actix with unlimited time and budget."

Как мне представляется, сейчас к OpenSource сложилось исключительно потребительское отношение. Т.е. все привыкли к тому, что используемые ими инструменты должны быть открыты. И не просто открыты, но и бесплаты. Более того, начинают звучать голоса, которые говорят о том, что пермиссивные лицензии, которые требуют указания факта использования OpenSource проекта (как это обязывает делать, например, BSD-3-CLAUSE лицензия), не есть хорошо. Что следует использовать лицензии типа Boost Software License, которые позволяют задействовать открытый проект и даже не упоминать об этом...

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

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

Так что за словами "I am done with open source.", как по мне, скрыт очень и очень большой смысл.

среда, 15 января 2020 г.

[prog.c++] Как много одна простая строчка может рассказать об эволюции С++

Вот в этой строке с декларацией простейшего метода:

[[nodiscard]] bool empty() const noexcept;

можно отследить насколько много C++ вобрал в себя за время своей эволюции:

  • изначально, насколько я помню, в C++ не было контантности для методов, она была добавлена уже после публичного релиза C++ в 1985-ом году. И очень выгодно отличала C++ времен 1990-х годов от первых версий Java (да и от последующих тоже);
  • специальный булевский тип bool, которого так же изначально не было, но который был добавлен на основании опыта хождения по доставшимся в наследство граблям языка Си;
  • noexcept как результат эволюции отношения к исключениям. Не то, чтобы это был уже тот результат, который хотелось бы. Но уже сильно лучше, чем выпиленный, к счастью спецификатор throw();
  • аттрибут nodiscard. Во-первых, просто само понятие аттрибута, чего на протяжении многих лет в C++ не было. Но которое появилось под влиянием опыта других языков программирования. И, во-вторых, собственно nodiscard, т.е. явное указание того, что возвращаемое значение нельзя просто так проигнорировать. Опять же, на основании опыта хождения по граблям.

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

Если дать себе время остановиться и порефлексировать на эту тему, то это внушаить :)

суббота, 4 января 2020 г.

[prog.c++] В SObjectizer-овском select() появляется send_case()

В черновой ветке SObjectizer-а появилась возможность делать select() не только для чтения входящих сообщений из нескольких каналов, но и для отсылки сообщений в канал. Так что совсем скоро SObjectizer-овский select() станет еще более близок к Go-шному. Естественно, с поправкой на то, что в SObjectizer-е все это сделано средствами библиотеки, а не вшито в язык намертво с оптимально причесанным под это дело синтаксисом.

Под катом традиционный для демонстрации Go-шного select-а пример: вычисление чисел Фибоначчи в отдельном потоке и отсылка их в канал. Отсылка автоматически приостанавливается, если в канале нет места. Так же вычисление прекращается, если из второго канала вычитали сообщение на завершение работы. Или если какой-то из каналов принудительно закрыли.

Примечательна история появления send_case для SObjectizer-овского select-а.

Сам select() в SObjectizer-е появился чуть менее четырех лет назад, в марте 2016-го. После чего я пытался сделать несколько подходов к реализации в select-е не только receive_case, но и send_case. Но каждый раз эти подходы завершались неудачей из-за отсутствия хороших идей по интеграции send_case в уже имеющуюся реализацию select-а.

За пару недель перед Новым Годом начался очередной, можно сказать, дежурный подход, в начале которого было полторы или две недели безрезультатного выкуривания бамбука. Пока, наконец, не пришло некоторое понимание и того, что хочется вложить в send_case, и того, как это поместить в уже имеющуюся схему работы select-а. После чего потребовалось буквально пара дней, чтобы реализовать это все. Тот самый случай, когда идея реально должна была вызреть и, кроме того, должны были сойтись звезды, чтобы появилась возможность качественно "подойти к снаряду".

Плохо то, что пришлось поломать API select-а, поэтому версия SObjectizer-а будет увеличена до 5.7.0. На подготовку новой версии к релизу потребуется какое-то время, так что доступно все это будет где-то через пару недель.

четверг, 2 января 2020 г.

[life.sport.darts] Послесловие к завершившемуся PDC-шному Чемпионату Мира 2020. И еще пару слов про дартс

Завершился Чемпионат Мира 2020-го года по дартсу, проводившийся организацией PDC. Победу в финале над Майклом ван Гервеном одержал Питер Райт. Что меня порадовало вдвойне, т.к. за Райта я болеюю последние несколько лет.

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

Много новых имен

Итак, главное впечатление от этого чемпионата (если не считать исторической, на мой взгляд, победы Райта) -- это четкое осознание того, что в ТОП-е мирового дартса происходит серьезная смена состава. Из тех ТОП-овых игроков, за которыми я следил и от игры которых пытался что-то брать в 2010-2012-х годах, остались считанные имена. Да и из тех, кто остался, далеко не все показывают игру достаточно хорошего уровня, чтобы претендовать на высокие места.

Карьера хорошего игрока в дартс может длится десятилетиями. На прошедшем ЧМ 2020 это можно было видеть на примере Стива Битона, которому сейчас 55 лет, а свою победу на BDO-шном ЧМ он одержал в далеком 1996-ом году. Но не смотря на то, что в дартс на высоком уровне можно играть и в 40, и в 50 лет, все-таки состав претендентов на победу за последние годы сильно обновился. Что хорошо для дартса. Что так же означает, что я сам слежу за дартсом уже настолько долго, что помню не только игроков, которые блистали 10 лет назад (Терри Дженкинс, например), но и тех, кто лет 6-7 назад вихрем ворвался в элиту дартса, ярко промелькнул на нескольких турнирах, а теперь лищь изредка заявляет от себе (Ким Хайбрехт и Стивен Бантинг вспоминаются в первую очередь).

Неожиданные прорывы

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

Наверное, в порядке вежливости, сперва нужно сказать о двух победах Фэллон Шеррок. Женщины вообще редко попадают на PDC-шный Чемпионат Мира. И раньше они никогда не проходили дальше первого тура. На ЧМ 2020 произошла настоящая сенсация: мало того, что Фэллон Шеррок выиграла в первом туре и прошла во второй, так она еще и во втором туре выиграла. И не у кого-то там, а у Менсура Сулловича, одного из тех, кто был в десятке потенциальных претендентов на звание чемпиона. Да и в третьем туре она смогла изрядно напрячь Криса Дабби, так что я бы не удивился, если бы Фэллон прошла и в четвертый тур. В общем, удивительно было наблюдать за игрой женщины против мужчин, да еще и показывающей средний набор в 90+ очков.

И, конечно же, нельзя не сказать о том, что Дариус Лабанаускас из Литвы сумел дойти до четвертьфинала, где его путь был остановлен не кем нибудь, а самим Майклом ван Гервеном. Проигрыш 2-5 в 1/4 финала ван Гервену -- это очень и очень достойно. И, мне показалось, что Дариусу помешал недосток опыта выступлений на таком высоком уровне и на арене с таким большим количеством зрителей. Было бы опыта чуть-чуть побольше, ван Гервену пришлось бы приложить значительно больше усилий. А так досадные промахи по удвоениям из-за волнения позволили выиграть ван Гервену с комфортным преимуществом в три сета. Тем не менее, у меня лично осталось ощущение, что прорыв Дариуса не случаен, поэтому буду ждать от нее еще более яркой игры в будущем.

Игра Эдриана Льюиса

Сильное впечатление на меня произвели две первые игры Эдриана Льюиса на этом ЧМ (третью я не смог посмотреть). Было ощущение, что Льюис сражается не за победу, а за свою жизнь.

Попробую объяснить почему мне так показалось.

Дело в том, что несколько лет назад Льюис был одним из самых талантливых и многообещающих игроков в PDC. Благодаря своему таланту он не только стал двухкратным чемпионом мира, но и выиграл ЧМ два раза подряд (что вообще-то мало кому удается). Но затем в его игре наступил спад, из которого Льюис не может выбраться до сих пор.

Наблюдая за игрой Льюиса на этом ЧМ у меня появилась версия, почему Эдриан не может вернуться на свой прошлый уровень. Мне думается, что это связано с техникой броска и манерой игры. Льюис очень быстро играет, бросает практически не целясь. И при такой манере игры чрезвычайно важна собственная уверенность в том, что ты попадешь. Вот в прошлом Льюис играл зная, что он не может промахнуться. А сейчас он играет зная, что он может промахнуться.

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

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

И мне бы хотелось, чтобы Льюис справился с тараканами в своей голове. Но, боюсь, для этого нужно, чтобы в жизни Эдриана произошло какое-то серьезное проишествие, которое заставит его пересмотреть свое отношение к дартсу. Поэтому я уже не сильно верю в возраждение Льюиса как ТОП-ового игрока. Хотя и буду очень рад ошибиться. Чем больше у ван Гервена сильных конкурентов, тем интереснее.

10 лет назад...

В начале 2010-го года на Евроспорте случайно наткнулся на трансляции BDO-шного Чемпионата Мира по дартсу. И с этого, по сути, началось мое приобщение к дартсу.

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

Это было интересно и неверно круто. Дартс помог лучше понять самого себя и справиться с одной из волн кризиса среднего возраста. В дарсе удалось понять, чем спорт отличается от физкультуры. Чем спорт отличается от простого увлечения. Да и почуствовать себя спортсменом в 40 лет -- это было, мягко говоря, неожиданно.

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

Тем не менее, немного греет мысль, что может быть я хоть немного поспособствовал популяризации дартса у нас в Гомеле и в стране в целом. Пусть это и самонадеянно, но думаю, что были какие-то вещи, к которым я приложил руку. Пусть даже это всего лишь логотип сообщества GomelDarts в VK :)

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

Вместо послесловия

А закончу я традиционно:

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