среда, 21 августа 2019 г.

[work.sadness] Поддержку Mercurial удаляют с BitBucket-а. Полностью. Что в этом самое плохое?

Вчера получил письмо счастья от Atlassian, в котором говорится об удалении поддержки Mercurial-а и всех Mercurial-репозиториев с BitBucket-а к 1-му июня 2020-го года:

After much consideration, we've decided to remove Mercurial support from Bitbucket Cloud and the API. Mercurial features and repositories will be officially removed from Bitbucket and its API on June 1, 2020.

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

Свое первое возмущение по этому поводу я уже высказал вчера в грубой форме в FB. Но это все лирика. Физика в том, что "just a business". Atlassian владеет BitBucket-ом, вкладывает в его поддержку свои деньги и имеет полное право делать то, что им выгодно, наплевав на мнение 1% своих пользователей. Тем более тех пользователей, которые пользуются этим сервисом бесплатно.

Но если приглушить эмоции, то самое плохое в этом то, что Atlassian тупо удалит все Mercurial репозитории, включая все, что там было, вроде issues, Wiki, артефактов в секции downloads и т.д. Т.е. исчезнет не только код, но и вся сопутствующая база знаний, которая была накоплена вокруг кода.

И вот эта сторона решения Atlassian-а мне непонятна. Хостинг исходных текстов -- это специфическая тема. Люди прибегают к подобным хостерам (будь то GitHub, BitBucket, SourceForge, GitLab или еще что-то) как раз для того, чтобы сделать результаты своих трудов доступным для всех желающих на долгое время. Какой-нибудь древний проект на SourceForge, который уже 15 лет не развивается, все равно доступен и информация оттуда может быть получена даже если автор этого проекта уже давным-давно от проекта отошел (а может автора уже и в живых нет).

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

В конце-концов, для OpenSource основной смысл хостеров типа SourceForge и GitHub именно в том, что там хранится все, что когда-то там было создано.

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

И вот этого вот решения я понять не могу.

Экономически не выгодно вам пилить поддержку Hg в своей хостинговой платформе? OK. Перестаньте это делать. Переведите все существующие Hg проекты на BitBucket-е в режим read-only. Пусть все, что люди ранее сделали на вашей платформе... Нет, даже не так, а вот так: все, что люди ранее сделали на ВАШЕЙ платформе останется доступным для всех желающих.

Понятно, что даже на саппорт read-only репозиториев придется тратить какие-то деньги. И если это для Atlassian-а настолько серьезные деньги, то можно было бы ограничить время существования read-only репозиториев. Скажем, всего 5 лет. Потом навечно в /dev/null. Но хотя бы в течении этих пяти лет ссылки на репозитории, issues, Wiki, тарболлы и пр., которые в невероятном количестве раскиданы по всему Интернету, будут оставаться валидными.

PS. Ну вот честно не могу даже вообразить себе степень эффективности менеджеров Atlassian-а, принявших решение тупо убить проекты с Hg репозиториями вместо того, чтобы перевести их в read-only mode. Хотя бы лет на пять. Какой-то, блин, контрольный самострел в голову.

понедельник, 19 августа 2019 г.

[prog.flame.c++] Dropbox выставляет свою Djinni на мороз

Кстати говоря, в делах и заботах упустил из виду вот эту публикацию: (Не очень) скрытые издержки общей кодовой базы iOS и Android

Между тем штука значимая.

Я вот несколько лет то тут, то там рассказываю про такую область применения C++, как написание "ядра" кросс-платформенных приложений. Типа того, что бизнес-логика пишется на плюсах, а GUI и какие-то штуки по интеграции с системно-зависимыми сервисами на родных для платформы языках (вроде Java на Android-е, Objective-C/Swift на iOS, C++ или .NET на Windows).

И в качестве примера приводил разработку Djinni от Dropbox-а.

А вот, оказалось, что Dropbox такой подход к кроссплатформенности запарил и они от него отказались.

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

Остальные же причины, в частности, про оверхед пользовательских фреймворков и библиотек, вызывают недоумение. Никто не заставлял Dropbox делать свою собственную библиотеку для работы с Json в С++. Очень похоже на NIH-синдром и его последствия.

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

суббота, 17 августа 2019 г.

[comp.notebooks] Минутка дыбра: продолжение истории про выбор ноутбука

Развитие темы, начатой на прошлой неделе. Я прислушался к мнению уважаемых френдов, которые сказали, что FullHD разрешение -- это уже вчерашний день и нужно что-то принципиально получше. В итоге приобрел 15.6" ноутбук с UHD разрешением (3840x2160): Asus X570UD. Если кому-то интересно почитать о моих текущих впечатлениях, то милости прошу под кат.

пятница, 16 августа 2019 г.

[prog.flame] Ну не могу не утащить великолепную цитату в склерозник. Про RAII в виде создания процессов

Ну прекрасно же! Просто прекрасно. Ни добавить, ни убавить.

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

Взято отсюда. Это человек решил вступить в спор о том, чего не хватает в чистом С, в частности об отсутствии в C классов и RAII.

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

среда, 14 августа 2019 г.

[prog.c++] Быть или не быть tls_inspector-у в RESTinio? И если быть, то каким?

В комментариях к одной из статей про RESTinio на Хабре прозвучала идея сделать объект tls_inspector для проверки TLS-ных подключений. И не только проверки, но и просто извлечения из сертификата клиента различной полезной для сервера информации.

Дошли руки заняться этой темой. Но есть ощущение, что блин получился комом. Если кому-то интересно, то суть я попытался описать здесь: https://github.com/Stiffstream/restinio/issues/44
Там же можно высказать и свое "фи". Хотя его можно высказать и прямо здесь ;)

вторник, 6 августа 2019 г.

[comp.notebooks] Минутка дыбра: очередной приступ поиска нового ноутбука :)

Бывает у меня периодически такое специфическое состояние: я начинаю выбирать себе новый ноутбук. Иногда просто потому, что время идет, моей "основной" машинке, уже больше пяти лет. А "резервной" уже около семи. Иногда потому, что на обоих машинах время от времени что-то оказывает. Так, последний приступ выбора ноутбука был в районе Нового Года, когда на "основной" стала слишком часто проявляться его родовая травма в виде спонтанных самовыключений, а на "резервной" начала выходить из строя клавиатура и аккумулятор перестал держать заряд. Но тогда удалось обойтись без приобретения новой машины путем латания уже имеющихся. Однако, прошло какое-то время, латки поизносились и вновь стал мучать вопрос о приобретении нового ноута, который сможет поработать в режиме 12/7 следующие несколько лет.

Еще один фактор, толкающий на поиск нового ноута -- это то, что годы берут свое и зрение от этого лучше не становится. Экран в 13.3", особенно с FullHD разрешением -- это уже тяжеловато, при том, что пялится в экран приходится по многу часов в день. Разрешение 1399x768 на 13.3" намного более щадящее, но зато есть другая проблема: сложно ориентироваться на экране, когда там открыто несколько десятков окон. Покупка внешнего монитора не вариант, т.к. тогда теряеся мобильность, а это именно то, ради чего мне ноутбук и нужен.

Дополнительный забавный момент в том, что в последние месяца три "резервная" машинка, которая у меня под Linux-ом, стала для меня основной рабочей станцией. Т.к. практически все сейчас делается под Linux-ом. А в Windows я захожу лишь по необходимости: с документами в MS Office разобраться, провести проверки под Visual C++, поработать в Lightroom-е, если где-то что-то заснял. Так что сейчас я практически линуксоид ;)

Выбор оказывается весьма непростой.

Основные требования, которые должны быть удовлетворены в обязательном порядке -- это, минимум 8GiB RAM, 4-е ядра (причем нормального Core i5/7 или Ryzen, а не какого-нибудь маломощного мобильного Pentium-а с частотой 1.1GHz), SSD диск от 128Gb, матовый экран.

Еще один серьезный момент: производитель. Из того, что широко представлено у нас, я доверяю разве что HP и Lenovo, плюс, в несколько меньшей степени, Asus и Dell.

Пожалуй, главный сдерживающий фактор -- это размер и вес. 17" экран с FullHD разрешением, наверное, был бы для меня вполне подходящим выбором. Но, боюсь, в мой рюкзак он не влезет. Да и таскать с собой каждый день туда-сюда 3кг вместо 1.5кг как-то не воодушевляет. Я, конечно, товарищ немаленький и доходягой вроде не являюсь, но лишний груз взваливать на спину не хочется :)

И если с размером и весом проблемы были ожидаемы, то неожиданными оказались вот такие факторы:

  • неудобные клавиатуры. Отсутствие отдельной клавишы Ins -- это обычное дело. Так же, как и кнопок PgUp/PgDn и Home/End. Причем, если для 13.3" или даже 14" ноута это еще понять можно (хотя можно посмотреть на HP ProBook 440 G6, например, там с нужными кнопками все нормально), то вот для 15" или 17" ноутов, в которые умудряются впихивать еще и блок цифровых клавиш отсутствие отдельной Ins -- это что-то за гранью моего понимания;
  • наличие USB 2.0 разъемов на моделях от 2017, 2018 и даже 2019-го годов. Скажем, ноут от 2018-го у которого два USB 2.0 и всего один USB 3.0 -- это вообще что такое?

При этом всем я ориентируюсь на весьма бюджетный сегмент -- плюс минус 1K USD. Ибо мне нужен рабочий инструмент, который я буду гонять и в хвост, и в гриву, и который не должно быть жалко, если я где-то долбану его по дороге или уроню на него что-нибудь, или он тупо сдохнет под непосильной нагрузкой :) Типа премиуальный/имиджевый ноутбук у меня был, это совсем другая история.

Благо, рабочих лошадок стоимостью между $700 и $1000 с 4-х ядерными Core i5 8-го поколения, 8GiB RAM и SSD на 256GB не так уж и мало. Например, HP ProBook 440 G6 6BN87ES с параметрами: Intel Core i5 8265U, 8GiB RAM DDR4, SSD 256GiB, FullHD IPS-дисплей, металлический корпус и вес порядка 1.6кг. Стоит такая машинка на данный момент порядка $800. Жаль только, что 14" :(

Пока в short-list-е у меня две модели от Lenovo: ThinkPad e590 и IdeaPad S340-15IWL. В пользу ThinkPad говорит IPS-ная матрица, намного более удобная для меня клавиатура (защищенная от протечек при том). А в пользу IdeaPad немного меньший размер и заметно меньший вес.

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

В связи с этим хочу спросить у тех, кто работает с ноутами-пятнашками с FullHD разрешением: как вам? Нормально или размер пикселя все-таки хотелось бы побольше?

PS. Жаль, что я завязан на C++. Программировал бы на Go, мог бы обойтись чем-то вроде вот такого. С дополнительным SSD, естественно ;)

четверг, 1 августа 2019 г.

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

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

Та еще парочка (Long Shot, 2019). Смотрибельно. Примитивно, предсказуемо. Но местами смешно. Плюс присутствие красавицы Шарлиз Терон компенсирует какие-то мелкие недостатки. И не очень мелкие недостатки тоже ;)

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

Хладнокровный (Cold Blood Legacy, 2019). Халтура. Даже удивительно, как Жан Рено согласился на участие в таком.

Искусство обмана (Lying and Stealing, 2019). Н-у-у о-о-о-чень с-к-у-у-у-чный ф-и-и-и-льм. Вот буквально: смотришь, а на экране какая-то нудятина, которая все никак не закончится.

Клуб анонимных киллеров (Killers Anonymous, 2019). Откровенная дрянь. Главная загадка: что там делает Гари Олдман?

Годзилла 2: Король монстров (Godzilla: King of the Monsters, 2019). Редкий бред. Не смотреть ни в коем случае.

суббота, 27 июля 2019 г.

[work.thoughts] Мысля насчет расценок в зависимости от языка программирования

В последнее время, когда приходится писать код, делаю это либо на C++17, либо на C++14, либо на C++11. Либо, внезапно, на чистом C. C++98 уже давно не попадалось.

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

Но к чему я этим решил поделиться? А вот к чему.

Похоже, что нужно выстраивать ценник в зависимости от степени свежести стандарта языка программирования. Скажем, есть базовая цена для C++17 (для наших еб*ней с прицелом на заказчиков из РФ -- это где-то $25/hour для проекта от двух-трех месяцев длительностью без горящих сроков).

Тогда для C++14 будет базовая цена + 5%.

Для C++11: базовая цена + 25%. А если нужно жить с GCC ниже 4.8 или MSVS2013, то + 50%.

Для C++98: базовая цена * 2.

Для чистого C: базовая цена * 3.89. В случае, если заказчик согласен на частичный рефакторинг с постепенным затаскиванием C++ных частей в C-шную кодовую базу (или постепенный перевод с C на C++), то базовая цена * 2.17.

Ибо нех*й.

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

PS. Если кто-то остался один на один с древним C-шным или C++ным кодом, без которого вам не обойтись, но с которым вы не знаете, что делать, то вам сюда. И да, это реклама. Проплачена мной.

пятница, 26 июля 2019 г.

[prog.c++] rotor: библиотека, разработанная под влиянием SObjectizer-а

Полку акторных фреймворков для C++ прибыло!

Собственно, вот: rotor. Автор пробовал использовать SObjectizer, но у SObjectizer-а нет интеграции с wxWidgets, а интеграция с Asio находится под двойной лицензией. Поэтому автору показалось проще сделать свое решение. Более подробно о причинах можно прочитать здесь.

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

Ну а меня впечатляет другое: как-то незаметно для меня SObjectizer превратился в большой и сложный инструмент. Настолько, что кто-то уже хочет чего-то полегче. Ну это типа ты сделал текстовый процессор уровня Microsoft Word, а пользователи говорят, да не, нам бы чего-то не сложнее WordPad-а :)

суббота, 20 июля 2019 г.

[prog.c++] Идея развития темы, начатой в статье "A declarative data-processing pipeline on top of actors? Why not?"

Давеча опубликовал на Хабре большую статью на английском языке "A declarative data-processing pipeline on top of actors? Why not?", в которой описал старый, но доведенный "до ума" пример make_pipeline из состава SObjectizer-а. К самой статье Григорий Демченко задал интересные вопросы в комментарии. Плюс на Reddit-е подсунули ссылку на (как мне показалось) недоделанную и полузаброшенную библиотеку RaftLib.

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

По сути, тема создания пайплайнов (или графов в общем случае) обработки данных на C++ состоит из двух частей. Можно сказать, что есть верхняя и нижняя части проблемы.

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

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

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

среда, 17 июля 2019 г.

[prog.flame] Почему Rust может быть намного более пригоден для прикладного программирования, чем C++

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

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

Прежде чем пойти дальше отпрыгнем в сторону и попробуем хоть как-то определить само понятие "прикладного программирования". По большому счету к прикладному программированию можно отнести все, что не касается системного и низкоуровневого программирования. Т.е. если код не решает каких-то специфических задач, интересных только программистам (ядро ОС, компилятор, линкер, MQ-шный брокер, сервер БД, утилита типа grep и т.д.) или не управляет каким-то оборудованием (вроде бортового ПО автомобиля или самолета), то это прикладное ПО. К сожалению, в этом случае в "прикладное ПО" попадает слишком большой спектр софта: скажем, от Microsoft Word или Adobe Lightroom до склепанного на коленке в Wordpress сайта-визитки. Но есть подозрение, что если попытаться конкретизировать термин "прикладное ПО", то возникнет ощущение насильственной подгонки условий под нужный результат. Посему более жестких условий накладывать не будем.

Итак, есть тезис о том, что Rust отлично подойдет для прикладного программирования...

вторник, 16 июля 2019 г.

[prog.sadness] Похоже, разработчики D решили закопать свой язык еще глубже

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

На D.

А вот сегодня на HackerNews увидел ссылку на статью Вальтера Брайта (это автор D и его основной разработчик) про возможность добавления в D механизмов Ownership и Borrowing из Rust-а. Смысл статьи в том, что изначально Брайт думал, что borrow checker из Rust в D не запихнуть, но потом у него появились идеи, которые Брайту кажутся вполне себе реализуемыми. Поэтому Брайт начинает активно копать в этом направлении.

Ну что тут сказать. Один раз Брайт и Ко уже основательно поднасрали своему детищу. Это кода в 2008-го году, всего через полгода после официального релиза D 1.000 было заявлено, что начинаются работы над D2, который будет несовместим с D1. Сказано это было в тот момент, когда вокруг D не было никакой существенной экосистемы и количество нормальных библиотек для D измерялось, в лучшем случае, несколькими десятками.

Да, D2 получился гораздо более интересным и мощным языком, чем D1. Но лет через шесть после D 1.000. И, по факту, он появился уже тогда, когда окно возможностей для D захлопнулось благодаря C++11/14, Go, хайпу вокруг Rust-а. Так что D отличный язык для небольших проектов маленьких команд и энтузиастов. Но широкого применения ему, увы, уже не светит.

А тут в D хотят впихнуть еще одну мегафичу. И мне непонятно нахрена это нужно делать :(

Ну вот основная фишка в том, что это продвинутый язык с GC для нейтива. И как раз GC дает D те преимущества, о которых C++никам остается только мечтать, если на C++ пытаться разрабатывать что-то более-менее высокоуровневое.

Казалось бы: ну и развивайте D как язык с GC. У вас и в этой области работы будет выше крыши. Зачем вы еще куда-то лезете? Делаете GC отключаемым, придумываете какой-то betterC... Теперь вот еще и borrow checker в язык затаскиваете...

Ну вот явно "чувство меры" -- это не то, что свойственно разработчикам D.

Пичалька, что еще скажешь. Вот так и разрушаются мечты :(

пятница, 12 июля 2019 г.

[prog.flame] Пятничное дополнение ко вчерашнему посту. Снова про Rust

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

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

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

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

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

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

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

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

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

Имхо, вариант Haskell-я, когда посредственности в этот язык просто не идут, здесь не прокатит. Т.к. Haskell в силу разных причин никогда и не мог претендовать на широкое использование. В отличии от Rust-а.

Так что будет интересно посмотреть на то, что произойдет. Выпрямит ли Rust-овский компилятор растущие из жопы руки? Или этот самый компилятор наеб*т посредством расставления unsafe в коде, ибо дедлайны, нужно фичи в прод выкатывать, а не ублажать borrow checker.

четверг, 11 июля 2019 г.

[prog.flame] Предлагаю новый слоган для D: "Fast as C++, safe as Rust, easy as Java"

Намедни в LOR-овском срачике сформулировал свое впечатление от наблюдений за тем, кто, как и откуда переходит на Rust. На мой взгляд, в Rust идут люди, которые всю жизнь программировали на безопасных языках с виртуальной машиной. Ну там Java, Python, Ruby, JavaScript, Erlang, Clojure и т.д. А так же C++ники, которые толком C++ не освоили, а уж о том, что такое современный C++, вообще не имеют никакого понятия.

А потом довелось прочитать серию постов небезызвестного своими "плачами Ярославны" НикиТонского: "С высоты", "С высоты-2" и "С высоты-3". И еще более утвердился в том, что мои наблюдения более-менее коррелируют с действительностью.

вторник, 9 июля 2019 г.

[prog.c++] Что-то затупил с выписыванием условия для SFINAE

Стоило отвлечься на пару недель на написание документации и статей, как остаточные знания C++ улетучились из головы и случились жуткие тормоза при попытке написать условие для SFINAE :(

Нужно было вот что: в шаблонный фабричный метод передается ссылка на контейнер (или что-то, что притворяется контейнером, какой-нибудь range, к примеру). Нужно, чтобы этот шаблонный фабричный метод попадал в рассмотрение компилятора только если передали ссылку на контейнер/range. Для этого я решил написать проверку того, что у контейнера есть методы begin/end, и что при разыменовании итератора, возвращенного begin-ом, получается нужный мне тип.

Затык случился при попытке написать проверку на наличие begin/end. Вроде как в C++17 нет штатных средств проверить, что decltype(std::declval<const Another_Container &>().begin()) является валидным типом. Т.е. не нашел в type_traits чего-то вроде is_valid_v<constexpr-expr>. Пришлось извращаться вот таким образом:

templatetypename Another_Container >
static std::enable_if_t<
      !std::is_same_v< Container, Another_Container >
      && !std::is_same_v<
            decltype(std::declval<const Another_Container &>().begin()),
            void >
      && !std::is_same_v<
            decltype(std::declval<const Another_Container &>().end()),
            void >
      && std::is_same_v<
            std::decay_t<
                  decltype(*(std::declval<const Another_Container &>().begin())) >,
            mbox_t >,
      mbox_t >
make(
   environment_t & env,
   const Another_Container & destinations )
   {
      return make( env, destinations.begin(), destinations.end() );
   }

Т.е. сравнивать тип итератора, возвращаемого begin/end, с void. Ведь итератор, в принципе, не может иметь тип void. Поэтому если begin/end есть, то возвращать они должны не void.

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

Upd. Обновленный текущий вариант, полученный в результате обсуждения в FB, пока выглядит так:

templatetypename Another_Container >
static std::enable_if_t<
      !std::is_same_v< Container, Another_Container >
      && std::is_convertible_v<
            decltype(
               ++std::declval<
                  std::add_lvalue_reference_t<
                     decltype(std::begin(std::declval<const Another_Container &>()))>
                  >()
               == std::end(std::declval<const Another_Container &>()) ),
            bool>
      && std::is_same_v<
            std::decay_t<
                  decltype(*std::begin(std::declval<const Another_Container &>())) >,
            mbox_t >,
      mbox_t >
make(

Здесь сделано упрощение + поддержка C-шных массивов + несколько дополнительных проверок, которых не было ранее, а должны были бы быть. И, что самое интересное, это даже VC++ компилируется (как VS2019, так и VS2017).

Upd.2 У варианта с SFINAE обнаружилось два серьезных недостатка. Первый, который был виден изначально, это отсутствие поддержки ADL. Т.е. если Another_Container -- это какой-то пользовательский тип, для которого пользователем определены собственные begin/end функции, то SFINAE бы его забраковал. Поскольку внутри SFINAE используются std::begin/std::end. И как внутри условия SFINAE разбираться с ADL без создания каких-то дополнительных вспомогательных сущностей -- это отдельный квест.

Второй недостаток -- это неспособность Doxygen-а сгенерировать документацию для метода с навороченными условиями SFINAE. Показанный в первом апдейте вариант кода Doxygen не может переворить и просто не включает такой make в итоговую документацию :(

Посему в итоге отказался от SFINAE, а все проверки перенес внутрь метода в static_assert-ы. Получилось что-то вроде:

templatetypename Another_Container >
static mbox_t
make(
   environment_t & env,
   const Another_Container & destinations )
   {
      using std::begin;
      using std::end;

      // Ensure that destinations if a container or range-like object
      // with mbox_t inside.
      static_assert(
         std::is_convertible_v<
            decltype(
               ++std::declval<
                  std::add_lvalue_reference_t<
                     decltype(begin(std::declval<const Another_Container &>()))>
                  >()
               == end(std::declval<const Another_Container &>()) ),
            bool>,
         "destinations should be a container or range-like object" );

      static_assert(
         std::is_same_v<
            std::decay_t<
                  decltype(*begin(std::declval<const Another_Container &>())) >,
            mbox_t >,
         "mbox_t should be accessible via iterator for destinations container (or "
         "range-like object" );

      return make( env, begin(destinations), end(destinations) );
   }

PS. Ну и современный C++ в очередной раз оставил впечатление вроде "ну круто, чё, а нельзя ли все тоже самое, но раза в полтора-два попроще?". Так что ждем C++20 с концептами.

понедельник, 1 июля 2019 г.

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

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

Отель Мумбаи: Противостояние (Hotel Mumbai, 2018). Добротно снят. В принципе, понравился.

Однажды в Стокгольме (Stockholm, 2018). Любопытный фильм, стилизованный под эпоху 1970-х. Этим, наверное, и интересен в первую очередь. Как будто не от мира сего в хорошем смысле этого слова.

Битва за Землю (Captive State, 2019). Мне понравилось. Но фильм специфический. В нем создается своеобразная атмосфера, в которую хорошо вписываются главные герои фильма. Именно это мне в картине и понравилось. Однако, если вы ждете динамичного экшена, то фильм вас разочарует.

Загадочное убийство (Murder Mystery, 2019). Ну так себе средней руки фильмец. Местами смешно. На Дженнифер Энистон все еще приятно смотреть. Плюс Дэни Бун в придачу. Проходная комедия, но посмотреть можно.

Люди в черном 4 (Men in Black International, 2019). Полное разочарование. Весь фильм -- стандартные клише. Никакой интриги. Крис Хэмсворд играет полного дегенерата. Смешного мало. Спецэффекты так себе. В общем, понятно, что киностудия захотела перезапустить успешную в прошлом франшизу, но жидко обгадилась.

Шафт (Shaft, 2019). Скучно. Экшена мало. Тупизма много. Негров слишком много. Посмотреть можно разве что если больше нечего смотреть.

Домино (Domino, 2019). В страшном сне не могло привидится, что Брайн Де Пальма, автор "Лица со шрамом", "Путь Карлито" и "Миссия: невыполнима", опустится до такого шлака. А вот поди ж ты :(

План побега 3 (Escape Plan: The Extractors, 2019). Говнофильм. Но, в отличии от второй части, эту я хотя бы смог досмотреть. Ощущение, что снимался по следующему принципу: у нас есть вот столько-то героев, пусть эти будут хорошими, а вот эти -- плохими. Пусть вот этот будет выбивать зубы вот этому, а вот этот будет драться с вот этим. Ок, боевые сцены засняли, теперь заполним пространство между ними каким-то невероятным бредом.

вторник, 25 июня 2019 г.

[prog.c++] Кому-нибудь будет интересен еще один доклад про акторов и их применимость/реализуемость в C++?

Мне прислали приглашение подать доклад на конференцию C++ Russia 2019 Piter, которая пройдет в Питере 31-го октября и 1-го ноября. И я нахожусь в задумчивости по поводу темы доклада с которым можно было бы достойно выступить.

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

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

А так же добавить сюда информацию о том, как модель акторов может быть реализована в C++. Ну, например, как могут быть в принципе представлены акторы (нити, сопрограммы, объекты с коллбэками). Как может происходить извлечение и обработка сообщений (ручной вызов receive актором или автоматический вызов коллбэка). Как может происходить работа с сообщениями (аллокация в момент отсылки, преаллокация, аллокация с отложенной деаллокацией, простой FIFO порядок или selective-receive/stashing). Отказоустойчивость C++ приложений с акторами. Защита акторов от перегрузок. Распределенность для акторов (прозрачная или непрозрачная, из коробки или нет). Насколько черным должен быть тот ящик, который выступает в качестве акторного фреймворка (т.е. насколько просто в него заглянуть и понять, что происходит). Насколько просто тестировать акторов и кто/как может в этом помочь.

И, главное, чтобы этот рассказ не был привязан к какому-то одному конкретному инструменту. Ссылки на то, что есть в наличии в QP/C++, CAF, SObjectizer и т.п., возможны, но разве что как иллюстрации.

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

Часть этих вопросов уже рассматривалась, например, на Corehard Autumn 2017. Но там рассматривался, в основном, концептуальный аспект, без привязки к особенностям реализации. А когда мы говорим об акторах в C++, то без привязки к реализации не обойтись. Очень уж специфический язык C++ и очень уж сильно сегментировано его комьюнити (об этом речь шла на C++ Russia 2018, но там не освещался вопрос полезности/бесполезности акторов). Поэтому хочется выдать материал в максимально сжатом и концентрированном виде.

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

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

пятница, 21 июня 2019 г.

[prog.c++] В склерозник: список встраиваемых HTTP-серверов для C++

Время от времени приходится то там, то там рассказывать людям, что в мире C++ есть ряд готовых к использованию встраиваемых HTTP-серверов. И дабы этот список было проще искать, решил зафиксировать его в виде блог-поста. Итак, что есть:

  • RESTinio. Это наша разработка, в которую наша маленькая команда продолжает вкладывать силы и душу. Соответственно, номер один в списке претендентов. Если вам чего-то не хватает в RESTinio или что-то не нравится, то с нами всегда можно договориться ;)
  • Silicon Framework;
  • Pistache;
  • RestBed. Продвинутый. Но, насколько я помню, был одним из самых тормозных. Плюс он идет под двойной лицензией. Т.е. либо за деньги, либо GPL;
  • served;
  • C++REST SDK. Разработка от самого Microsoft-а. Не знаю, как сейчас, но раньше не отличалась хорошей производительностью под Linux-ами;
  • proxygen от Facebook-а. Традиционно ориентируется на мир Linux-ов, насколько юзабелен за его пределами (тем более под Windows) -- без понятия;
  • Simple-Web-Server (раньше жил на GitHub-е);
  • drogon;
  • CROW. Пожалуй один из самых распиаренных фреймворков такого рода для C++. Но который, вероятно, уже давно приказал долго жить и не развивается с декабря 2017-го.

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

четверг, 20 июня 2019 г.

[prog] Статья на Хабре не про акторы, но в которой можно увидеть хороший пример использования акторов

Вот эта статья от Яндекса на Хабре: "Архитектура сервиса распределённых очередей сообщений в Яндекс.Облаке". И картинка оттуда, демонстрирующая наличие акторов:

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

№1:

YMQ Actor system – акторная система. В ней одновременно запущены тысячи различных акторов, обменивающихся информацией. Акторная система каждого хоста — это часть кластера. Все акторы кластера живут и действуют как единое целое. Бизнес-логика YMQ реализована в различных акторах, осуществляющих запросы-транзакции к YDB.

№2:

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

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

И, как по мне, сама по себе задача разработки системы, вроде YMQ, является отличным примером ниши, для которой могут применяться инструменты вроде Akka, SObjectizer, CAF, Actix и пр. По крайней мере наверняка могу сказать, что заложенные в SObjectizer проектные решения (вроде использования динамической памяти и исключений) не будут стоп-фактором для использования SObjectizer-а в разработке подобного проекта. В отличии от проектов, связанных с настоящими системами жесткого реального времени.

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

Ну а почему бы и нет? Вообще, список подходящих кандидатов окажется небольшой: Java (или альтернативы для JVM, вроде Scala, Kotlin, Ceylon), C#, C++ и Rust. Можно, конечно, взять в рассмотрение еще и чистый C, а так же Go. Но, имхо, стартовать сейчас что-либо на чистом C за пределами системной Linux-овой хардкорщины -- это крайняя степень изощренного мазохизма. Тогда как Go, опять же имхо, не очень хорош для разработки больших и долгоживущих проектов (просто в силу убогости заложенных в этот язык выразительных возможностей).

Так что, по сути, имеем список из Java, C#, С++ и Rust. При этом и у C++, и у Rust-а есть то преимущество, что в погоне за максимальной производительностью можно без проблем опускаться на сколь угодно низкий уровень.

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

PS. Динамику, вроде Erlang-а, я не рассматривал. Ибо делать большие системы на динамике -- это другая крайняя степень мазохизма, имхо. Но, наверняка, Erlang или какой-нибудь Elixir можно будет использовать в разработке такого рода системы. Тут вопрос лишь в итоговой ее стоимости. Впрочем, как и в случае C++.

среда, 19 июня 2019 г.

[prog.c++] Послесловие к релизу RESTinio 0.5.1

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

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

Если же новые хотелки озвучиваться не будут, то RESTinio будет оставаться в своем текущем состоянии.

Я бы даже развил эту мысль. Текущие версии наших проектов, будь то RESTinio, SObjectizer/so5extra или json_dto, имеет смысл рассматривать как инструментарий в, скажем так, базовой комплектации. Не факт, что эта базовая комплектация хорошо подходит для ваших условий. И, если подходит не очень хорошо (либо вы думаете, что подходит не очень хорошо), то вы можете обсудить ситуацию с нами. Есть далеко не нулевая вероятность, что наши инструменты смогут быть доработаны так, чтобы удовлетворять вашим требованиям.

вторник, 18 июня 2019 г.

[life.music] Немного гитарной музыки с YouTube

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

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

А с недавних пор в меня стала заходить и акустическая гитара, в частности под соусом "фингерстайла". И, вместе с ней, испанская гитара. Классическая гитара (как и изрядная часть классической музыки) остается сильно в стороне и, практически, не трогает. Хотя современные и не очень вещи, переработанные под исполнение на классической гитаре, мне нравятся (для примера: "My Way" и, конечно же, "The Entertainer"). Но, наверное, это просто разновидность все того же "фингерстайла", только на классике, а не на акустике.

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

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

Попутно нашел еще вот какой канал на YouTube: Tunc Er. Там лежит несколько сборников испанской музыки. Ну т.е. фламенко и все такое. Как в виде чистой гитары, так и "с оркестром". Но, что мне особенно понравилось, практически без вокала. Поскольку зачастую фламенко с вокалом наводит меня на мысли вроде "почему никто не застрелит того кота, который так истошно вопит?" Сорри за неполиткорреткность, но говорю как есть ;)

PS. Маленькое наблюдение после прослушивания/просмотра полутора десятков подобных сборников на YouTube: если в описании к ролику нет списка композиций с таймингами, то сборник, скорее всего будет корявый. Вплоть до того, что одни и те же композиции там могут повторяться несколько раз.

четверг, 6 июня 2019 г.

[prog.thoughts] Немного рефлексии на тему применимости SObjectizer-а и возможных путей его эволюции

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

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

среда, 5 июня 2019 г.

[prog.work] Немного рефлексии на тему неспособности работать в больших компаниях

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

вторник, 4 июня 2019 г.

[prog.c++] RESTinio обновился до версии 0.5.0

Наш небольшой проект RESTinio продолжает развиваться. Сегодня была официально выпущена версия 0.5.0, в которой стало возможно использовать кастомные версии http-parser-а. Так что если кому-то нужно поддерживать нестандартные HTTP-методы во входящих запросах, то сейчас понятно, как это делать без вмешательство в потроха RESTinio.

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

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

суббота, 1 июня 2019 г.

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

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

Итак, что имеем:

Затерянные во льдах (Arctic, 2018). Неплохой фильм о выживании одинокого (почти) героя в Арктике. Но неспешный, это нужно иметь в виду перед просмотром.

Видок: Император Парижа (L'Empereur de Paris, 2018). Не шедевр, но мне было интересно. Добротно сделано и есть некоторое погружение в эпоху начала XIX века (но я не историк).

Отмщение (Avengement, 2019). На удивление крепкий и зрелищный мордобойный боевик в старом духе. Любителям жанра может зайти. Мне зашел. И Скотт Эдкинс чуть ли не драматическую игру продемонстрировал.

Мы всегда жили в замке (We Have Always Lived in the Castle, 2018). Ну очень своеобразный и манерный фильм. Аж до раздражения. Смотреть тяжело не смотря на то, что визуальный стиль выдержан просто на отлично. Плюс к тому, где-то к середине фильма стало понятно, что там к чему, поэтому никакой интриги в финале не случилось.

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

Джон Уик 3 (John Wick: Chapter 3 - Parabellum, 2019). Разочарование. Первый фильм зашел отлично: свежо, бодренько и интересно. Второй не подкачал: еще больше всего хорошего из первой части и все это в присутствии вменяемого сюжета. А вот третью снимали, такое ощущение, чтобы количество мордобоя и перестрелок превысило допустимую концентрацию. Явно переборщили и это все на фоне какого-то невнятного сюжета с непонятными поворотами и переобуванием в прыжке. Разочарован. Лучше было бы его вообще не видеть.

Мстители: Финал (Avengers: Endgame, 2019). Муть. Редкая. Затянутая. Скучная. Не зрелищная. Откровенно тупая. Три часа впустую потраченного времени.

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

[prog.flame] Профильные форумы скатываются в какое-то УГ

Так уж получилось, что с профильными программерскими форумами в качестве читателя/писателя я связан достаточно давно. Так, на RSDN-е начал участвовать в форумных баталиях в 2004-ом, на LOR-е года через три. А так как последние лет пять плотно занимаюсь инструментарием для разработчиков, то профильные форумы рассматривались в качестве одного из основных каналов для продвижения наших продуктов "в массы". И, как мне кажется, еще года три назад эти самые форумы такими каналами были.

Сейчас я стараюсь держаться от форумных битв в стороне. На RSDN-е, например, разве что даю комментарии по поводу SObjectizer/RESTinio. На LOR-е время от времени еще встреваю в споры вокруг С++ или Rust-а. Кстати говоря, наверное половина полезной информации о Rust-е была получена именно в срачах с плюсохейтерами.

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

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

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

Причем есть у меня сомнения в том, какая из этих функций первична.

Кстати говоря, есть впечатление, что и reddit/cpp идет в том же самом направлении. Как-то часто там в темах оказываются какие-то праздношатающиеся идиоты, единственной целью которых является донесение до окружающих своей ценнейшей точки зрения. Началось это года три назад, когда там стали разгораться rust-осрачи. Потом модераторы научились быстро rust-офилов оттуда выпроваживать, но тенденция приходить в темы с ХЗ-какими комментариями осталась.


Понятное дело, что я необъективен и, возможно, это уже старческое брюзжание. Не исключено, что RSDN в 2004-2007-х годах, пока там не начала бесчинствовать банда Nemerle-проповедников, был таким же, как и сейчас. Просто из-за своего активного RSDN-ерства в те годы я не мог посмотреть на это спокойно и со стороны. Но остаюсь при мнении, что в период между 2004-м и 2009-ом годами на RSDN-е предметных и конкретных дискуссий с примерами кода, с отсылками на литературу, статьи, исследования и т.д., было много.

"Кладезь знаний" -- это, наверное, слишком громко сказано, но источником интересного профильные форумы (RSDN, LOR, sources.ru, opennet.ru) все-таки были. В отличии от того, чем они являются сейчас.

PS. Побрюзжал. Полегчало.

пятница, 24 мая 2019 г.

[prog.work] Пару слов о релизе SObjectizer-5.6

На этой неделе состоялся релиз мажорной версии SObjectizer-5.6.0. Об этом я уже много где писал, в том числе и в статье на Хабре. Так что вновь проговаривать одно и то же не буду.

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

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

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

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

Пара слов о том, что можно ожидать от нас дальше.

Видимо, в разработке SObjectizer-а наступит небольшая пауза. Есть вещи, которые не успели войти в релиз 5.6.0 и мы к ним обязательно вернемся. Но сейчас наблюдается большая волна интереса к другой нашей разработке, RESTinio. И там образовалась некоторая нехватка рабочих рук. Так что на некоторое время мы сосредоточимся на RESTinio. А потом вернемся к SObjectizer-у.

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

Тем не менее, если у кого-то возникнут вопросы к SObjectizer-у или пожелания/предложения, то сразу же давайте нам знать. Исправлять проблемы постараемся максимально оперативно. Ко всем конструктивным идеям и предложениям обязательно прислушаемся.

Ну а в общем, что еще сказать? Что смогли, то сделали. SObjectizer-5.6.0 уже здесь. Пользуйтесь на здоровье!

суббота, 18 мая 2019 г.

[prog.c++] Еще один любопытный баг на стыке многопоточности и ООП

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

Итак, обнаружилось, что один из тестов время от времени падает с диагностикой "pure virtual method called". Разбирательство показало, что проблема проявляется в коде, который похож вот на этот (лишние детали убраны, дабы не можно было рассказывать только о сути проблемы):

class data_owner_t {
public:
   virtual void update() = 0;
   ...
};

class data_repository_t {
   std::mutex lock_;
   some_container_t<data_owner_t *> owners_;
   ...
public:
   void add(data_owner_t & owner) {
      std::lock_guard lock{lock_};
      owners_.insert(&owner);
   }

   void remove(data_owner_t & owner) {
      std::lock_guard lock{lock_};
      owners_.erase(&owner);
   }

   void update_all() {
      std::lock_guard lock{lock_};
      for(auto * p : owners_)
         p->update();
   }
   ...
};

Виртуальный метод здесь всего один -- это data_owner_t::update. Вызывается он только внутри data_repository_t::update_all, в цикле, перебирающем всех зарегистрированных owner-ов. Значит в какой-то момент времени внутри data_repository_t оказывается невалидный указатель на owner-а. Но как и почему?

среда, 15 мая 2019 г.

[work.thoughts] Теплое чувство внутри, большое видится на расстоянии и периодическое удивление...

...тому, что наши разработки кто-то берет и использует.

Работаю сейчас над сопроводительными материалами к очередному релизу SObjectizer-а. Для чего перечитываю статью Павла Вайнермана "Если проект «Театр», используй акторов…", в которой речь идет об опыте применения SObjectizer-а для управления сценическим оборудованием в театре. И вот на чтении вот этого фрагмента меня вдруг "пробивает":

Был разработан «проигрыватель сценариев» который создаёт группу специальных акторов и запускает их в работу. Мы разработали два вида акторов: акторы-исполнители, предназначенные для выполнения задания для конкретного штанкета и актор-координатор, который распределяет задания между исполнителями. Причём акторы-исполнители создаются по мере необходимости, если в момент очередной команды не находится свободного. За создание и поддержание пула акторов-исполнителей отвечает актор-координатор. В итоге управление выглядит примерно следующим образом:

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

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

Почему-то именно при перечитывании этого фрагмента до меня внезапно (с) дошло, что вообще-то говоря, выбор SObjectizer-а для реализации этого всего был вовсе не обязательным. И это мягко говоря.

В принципе мы, разработчики, с пиететом относимся к инструментам от больших компаний. И это нормально. Если небезосновательное мнение, что в больших софтверных компаниях, вроде Google, Facebook, Amazon, Microsoft, Яндекс, Лаборатория Касперского и т.д., оказываются очень квалифицированные разработчики. Которым, при этом, создают отличные условия для концентрации именно на разработке софта.

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

Поэтому нет ничего удивительного, когда разработчики берут proxygen от Facebook или Abseil от Google. Просто потому, что это инструменты от Facebook-а и Google. Само их применение в проектах компаний таких масштабов уже служит неким знаком качества.

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

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

При этом, хоть описанный в статье проект далек от сложности и критичности от, скажем, системы управления Boeing 737 Max, но это вовсе не "Hello, World". Мягко говоря. И не вебня уровня какого-нибудь Интернет-форума, в котором недоступность или ограниченная функциональность в течении десятков минут не страшна от слова совсем. Вполне себе реальное оборудование и стоимость отказа в неподходящий момент высокая. И разработчики сочли возможным использовать наш продукт, посчитав его достаточно качественным, зрелым и обеспеченным должной поддержкой.

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

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

PS. Кстати говоря, то факт, что и SObjectizer, и RESTinio справляются с возложенными на них задачами, меня лично вовсе не удивляет. Я не из тех персонажей из анекдота "Да вы успокойтесь, софт для этого самолета делала наша фирма, поэтому он даже не вырулит на взлетную полосу". Все-таки мы делаем то, что работает. А то, что не работает, стараемся оперативно допиливать напильником ;)

[prog.c++] Обновили RESTinio до версии 0.4.9

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

Пару слов о текущем статусе разработки RESTinio.

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

Поэтому если перед кем-то стоит выбор брать RESTinio в работу или не брать, то ответ, на наш взгляд, очевиден: конечно же брать. Без поддержки мы вас не оставим :)

Попутно просьба поделиться своими впечатлениям тех, кто смотрел на RESTinio и не выбрал его. Почему? Чего не хватило? Что отпугнуло?

Эта информация сильно поможет нам сделать RESTinio еще лучше и практичнее.

Так же не могу не дать ссылку на свежую статью на Хабре о том, как можно использовать архитектурные особенности RESTinio для длительной обработки запросов: "RESTinio — это асинхронный HTTP-сервер. Асинхронный".

суббота, 4 мая 2019 г.

[work.flame] Увидел прекрасный список требований к соискателям. Не могу не прокомментировать

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

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

1. Способность разбираться (вот надо проанализировать кучу логов - человек найдет чем, даже если этого никогда не делал, разучит grep или научится виртуозно владеть Notepad++)
2. Отсутствие "нас этому не учили" позиции. И умение учиться. В современном мире, особенно когда ты делаешь что-то новое, никого никогда ничему не учили. Надо самому быть готовым учиться. И это нормально, когда рекламщик для своей работы изучает pandas, а программист - UX построения отчетов.
3. Личный тайм-менеджмент. Умение управлять своим временем, ресурсами, результатами. Чтобы без этих "ой, я увлекся" или "ой, я неправильно расставил приоритеты".
4. Грамотная и структурированная письменная речь. Это прямо must, мы живем в мире текстовых коммуникаций. Неспособность внятно выражать свои мысли в письменной форме - бич современного общества.
5. Понимание слова "результат". Это когда вы не считаете результатом "я кодил" или "я делал" или "я занимался". Когда вы считаете своим результатом - конечный результат, а не "свою маленькую делянку".
6. Амбиции. Я не понимаю и не люблю людей, которым все равно, чем они занимаются, лишь бы платили. Имхо это какой-то начальный уровень развития. Не понимаю и не люблю людей, которых не интересуют достижения команды, в которой они работают. У нас ежемесячное подведение итогов по компании - самое популярное мероприятие у сотрудников.
7. Здравый смысл. Не знаю как измерять. Но это общее понимание того, нафига ты что-то делаешь. Это частота задавания себе вопросов "а зачем?", "а как добиться того же самого, но попроще". Это когда ты не оправдываешь идиотизм ситуации или баги тем, что "так исторически сложилось" или "так было написано в ТЗ".
8. Способность "отвечать за базар". Грубая фраза, но очень важная. Это когда ты можешь человеку доверять. Потому что если он сказал "я разберусь", то ты уверен, что он не забудет и либо разберется, либо придет и скажет "ну слушай, там вот такая история, нужна помощь". И если он сказал "будет к вечеру", то к вечеру у тебя либо будет результат, либо до вечера ты узнаешь, что его не будет. Но уж точно тебе не придется писать на следующий день "ну что там?".
UPD 9. Отсутствие стеснения задавать вопросы. Когда у человека чувство собственного достоинства связано с тем, как он выглядит в глазах других, а не с реальными результатами - они стесняются задавать вопросы.

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

Ну и еще не могу не удержаться и не упомянуть, что у автора этого списка предшествующая запись в FB имеет вот такое содержание:

ОЧЕНЬ ищем iOS разработчика и QA инженера. Прям измучились в поиске людей с инженерной жилкой.

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

среда, 1 мая 2019 г.

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

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

Разрушитель (Vargur, 2018). Тяжелый и натуралистичный европейский криминальный фильм. Можно посмотреть просто ради того, чтобы почувствовать глоток свежего воздуха на фоне голливудской продукции. Но фильм тяжелый и натуралистичный. Может быть нудноватый.

Хэллбой (Hellboy, 2019). Первые два фильма я смотрел давным-давно и уже даже толком не помню, что там было и какие впечатления на меня они произвели. Вроде бы для жанра гомикса неплохие были картины. Этот, вроде как, из той же серии: в смысле неожиданно неплохо, могло быть сильно хуже. Так что вполне можно посмотреть в порядке развлечения.

Звонок мертвецу (Abgeschnitten, 2018). Смешанные ощущения от просмотра: по ходу дела интересно и ждешь, что же будет дальше. А потом остаешься в недоумении -- что это вообще было? Так что даже не знаю, советовать ли такое к просмотру или нет.

Клаустрофобы (Escape Room, 2019). Фильм для поклонников кино вроде "Куб" или "Пила". Если такого рода фильмы нравятся, то можно и этот посмотреть. Если нет, то не стоит и начинать.

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

Crypto (2019). Глянуть можно, но оставляет ощущение халтурности. И, главное, не понятно, что там делает Курт Рассел.

Снегоуборщик (Cold Pursuit, 2019). Как мне показалось, чуть ли не 1-в-1 сделанный ремейк скандинавского "Дурацкое дело нехитрое" от 2014-го года. Как по мне, так если и смотреть, то фильм от 2014-го. Хотя оба фильма сильно на любителя, наверное.

Капитан Марвел (Captain Marvel, 2019). Посмотрел только для того, чтобы быть в курсе что за нового персонажа добавят в "Мстители: Финал". Гомикс как он есть. Если не фанат жанра, то лучше не тратить время.

Стекло (Glass, 2019). Редкой унылости говно.

понедельник, 29 апреля 2019 г.

[prog.c++.flame] Посмотрел тут свежий доклад Саттера про более дешевые исключения для C++

Вот этот доклад с ACCU 2019:

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

пятница, 26 апреля 2019 г.

[prog.thoughts] Проектирование -- это искусство возможного

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

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

Например, количеством информации, которой вы располагаете. Количеством и качеством формализированных и неформализированных требований. Их (не)противоречивостью. Способностью повлиять на требования. Или хотя бы выяснить их происхождение и степень "жесткости".

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

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

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

К чему я все это веду?

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

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

Так что, перефразируя Сальвадора Дали: к совершенству нужно стремиться, но достичь его не получится. И это нормально.

вторник, 23 апреля 2019 г.

[prog.c++] Продолжение истории про отсутствие в C++ полноценного static if-а

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

Вот эта статья на Хабре: "С сожалением об отсутствии в C++ полноценного static if или…" Желающие сказать своё "Фи" могут сделать это на Хабре или прямо здесь.

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

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

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

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

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

суббота, 20 апреля 2019 г.

[prog.c++] Тот случай, когда жалко, что C++ный if constexpr не дотягивает до D-шного static if :(

Хорошо, когда C++ со временем впитывает в себя хорошие штуки из других языков программирования. Вот тот же if constexpr из C++17 явно позаимствован из D. Жаль только, что static if в D может применяться в большем количестве контекстов, чем if constexpr в C++.

Был бы в C++17 if constexpr таким же мощным, как static if в D, я бы мог написать вот такой вот код сходу, не сильно задумываясь:

среда, 17 апреля 2019 г.

[prog.c++] Кому-нибудь будет интересна еще одна статья про C++ные навороты с шаблонами и наследованием?

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

Суть в том, что я сейчас закончил адаптацию базирующегося на Asio диспетчера для SO-5.6. И в этой реализации полно всяких C++ных штук. Тут есть и шаблоны, и CRTP, и наследование как от шаблонов, так и не от шаблонов, включая нелюбимое многими наследование реализации.

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

Собственно, каждый желающий может сам составить свое впечатление. Текущий вариант реализации зафиксирован здесь. Можно обратить внимание, например, на thread_local_ptr_holder_t (стр.423), на его наследника work_thread_t (стр.466) и на его наследников work_thread_without_activity_tracking_t (стр.575) и work_thread_with_activity_tracking_t (стр.677). Либо на basic_binder_impl_t (стр.716) и его наследников binder_template_t (стр.790), binder_with_external_strand_t (стр.831) и binder_with_own_strand_t (стр.863). Не говоря уже про basic_dispatcher_skeleton_t и то, что идет дальше :)

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

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

пятница, 12 апреля 2019 г.

[prog.c++] Шаблоны против копипасты 9: SFINAE и CRTP чтобы бить юзверя по рукам в компайл-тайм

Очередная серия про то, как C++ные шаблоны позволяют бороться с копипастой. Опять в виде статьи на Хабре: "Немного C++ной шаблонной магии и CRTP для контроля за корректностью действий программиста в компайл-тайм". На Хабре потому, что нужен PR. Какой-никакой, но PR. И нужен.

Сказать свое "Фи", "Не нужно", "За такое нужно руки отрывать" или "Когда я вижу такой код, то хочется обнять и плакать" можно как в комментариях на Хабре, так и здесь. Но меня вы все равно не переубедите :) Так что лучше, если вы где-нибудь сделаете репост ссылки на статью со своими уничижительными комментариями. Мол, вон как хардкорные C++ники упарываются, нидайбох дойти до жизни такой ;)

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

  • в basic_holder_t потребовалось два метода data (константный и неконстантный), причем оба эти метода сделаны публичными (чтобы не трахаться с friend-ами для шаблонов);
  • методы clone_if_necessary в примеси cloner_t оказались статическими.

Поиграться в on-line с продвинутой версией можно здесь.

PS. Предыдущая часть серии "Шаблоны против копипасты" здесь.

вторник, 2 апреля 2019 г.

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

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

Закатать в асфальт (Dragged Across Concrete, 2018). Пожалуй лучший криминальный фильм за последние годы. Может быть слишком длинный, но по ходу просмотра даже это не вызывает особых претензий.

Журнал 64 (Journal 64, 2018). Отличное продолжение серии фильмов про странного следователя и его коллег. Особенно ценно то, что это европейское кино, со своим стилем, не похожим на американский.

В погоне за Бонни и Клайдом (The Highwaymen, 2019). Хорошее кино с хорошими актерами. Мне было интересно. Но тех, кто ждет от фильма какого-то экшена, ждет разочарование: весь экшен был показан в трейлере.

Наркокурьер (The Mule, 2018). Не шедевр. Но вполне себе добротное кино. Которое впечатляет не само по себе, а то, что это умудряется выдавать в свои годы Клинт Иствуд. И как режиссер, и как актер.

Хоть раз в жизни (Begin again, 2013). Незамысловатое кино с простым и предсказуемым сюжетом. Но, такое ощущение, что сами актеры получали кайф от своей работы, поэтому получился приятный фильм со своим настроением.

Удивительный мир Марвена (Welcome to Marwen, 2018). Добротно сделанное кино, вполне в духе Роберта Земекиса. Но, видимо, я уже не в том возрасте, чтобы в меня такие мелодраматические картины заходили. И этот не зашел. Хотя снят добротно.

Ржавый ручей (Rust Creek, 2018). В общем-то не так уж и плохо. Но общее впечатление испортило несколько моментов, которые вызывали желание воскликнуть "не верю!", а также совершенно невнятный финал.

В поисках Стива Маккуина (Finding Steve McQueen, 2019). В принципе, история рассказана неплохая. Но вот манера рассказа и показа такова, что фильм наверняка зайдет не всем. Так что, если вас не накроет раздражение от стилистики изложения истории в первые 15 минут, то может быть досмотрите до конца с интересом.

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

Тройная граница (Triple Frontier, 2019). Трейлер обещал очень крутой боевик. На деле же оказалась унылая нудятина в которой главные герои, якобы будучи крутыми головорезами, ведут себя как рефлексирующие интеллигенты.

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

Счастливого нового дня смерти (Happy Death Day 2U). Если вам понравилась первая часть, то, чтобы не портить впечатление, не смотрите вторую.

понедельник, 1 апреля 2019 г.

[life.cinema] Неожиданное следствие "очередных кинообзоров"

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

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

У этой артели в последние годы есть серьезная проблема: утечка мозгов. Т.к. порядка 20% придуманных в Минске пилотов получают свое развитие в Москве, то зачастую вместе с рабочими материалами из Минска в Москву перебирается и кто-то из ключевых людей из команды, работавшей над пилотом. Кстати, говорят, что 20% -- это очень высокий процент, в аналогичных компаниях в России обычно едва достигается 10%.

А тут еще, как оказалось, одна крупная госкорпорация в РФ, связанная с телекомунникациями (название начинается на Рос-, а заканчивается на -телеком) уже довольно давно готовит запуск своей стримминговой платформы. Задумывалось как российский ответ Netflix-у. Но с анонсом из-за обычного разгильдяйства и присущей госкорпорациям бюрократии затянули, Apple о своем Apple TV+ объявила раньше. Так что руководителям соответствующего направления в этой госкорпорации "хвосты накрутили" и обещали влить дополнительных бюджетных средств для ускорения запуска свой собственной стримминговой платформы.

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

Короче говоря, в ближайшее время меня ждет резкая смена деятельности. Вместо разработки ПО займусь управлением небольшой творческой командой, которая будет заниматься созданием пилотов на тему "производственная драма".

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

Пока не понятно, как быть с завершением текущих работ по нашим OpenSource-проектам. Времени на "закрытие хвостов" совсем не много, не больше недели. Так что, наверное, на днях будет выпущена бета-версия SObjectizer-5.6. Не все удалось сделать, но, по крайней мере, код компилируется и 2/3 тестов стабильно отрабатывают. Жаль, что актуальной документации не будет. Но, с другой стороны, вполне себе обычная картинка для OpenSource. Месяца через два-три, после того, как втянусь в новую работу, должно появится немного свободного времени по выходным, чтобы заставить оставшуюся 1/3 тестов работать.

Ну вот как-то так. Много лет писал "меня фильм не торкнул" по отношению к чужим фильмам. А вскоре это же самое начнуть говорить и в мой...

четверг, 28 марта 2019 г.

[prog.c++] Как работать с STL-ными контейнерами без include-ов описаний этих контейнеров

Давеча мы обновили свою тоненькую обертку над RapidJSON. Очередным добавлением в json_dto стала поддержка STL-ных контейнеров (std::deque, std::list, std::forward_list, std::set, std::multiset, std::unordered_set, std::unordered_multiset, std::map, std::multimap, std::unordered_map, std::unordered_multimap). И добавляя эту поддержку нам нужно было решить, как это сделать с минимальными накладными расходами.

Идти по простому пути, т.е. делать в json_dto какой-нибудь #include <set>, а потом перегружать часть внутренних функций json_dto для std::set и std::multiset, очень не хотелось. Во-первых, это сильно увеличивает объем нашей собственной работы. Во-вторых, это увеличивает время компиляции проектов, в которых json_dto используется.

Поэтому мы пошли по пути современного C++: т.е. шаблонная магия и SFINAE во все поля :) Под катом несколько слов об этом для тех, кому тема современного C++ интересна.

четверг, 21 марта 2019 г.

[prog.bugs] Интересная ошибка, связанная с многопоточностью

В минувший вторник убил целый рабочий день на разбирательство с любопытным багом. В многопоточном коде, в котором пришлось иметь дело с голыми std::mutex-ами и std::thread. Кому интересно, милости прошу под кат. Ошибка, в общем-то, имеет C++ную специфику, но, полагаю, во что-то подобное можно втоптаться и в любом другом языке с ручным управлением ресурсами.

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

среда, 20 марта 2019 г.

[prog] Тестов много не бывает...

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

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

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

Ну и да, традиционное: если у вас есть возможность не писать многопоточный код, то не пишите. А если вам все-таки нужно оный написать, то не опускайтесь на уровень голой многопоточности. Используйте лучше высокоуровневый инструментарий. Ну там акторов, CSP, task-flow, data-flow, STM и пр. Багов вы и там насажаете в свой код, можете даже не сомневаться. Но до такого траха, как с голой многопоточностью доходить будете гораздо, гораздо реже.

вторник, 12 марта 2019 г.

[prog.c++] C++Modules: there is no place for simplicity and beauty in C++?

C++Modules has been accepted in C++20. Nobody has a real experience with those modules and only few understand what C++Modules are. I don't understand that too. Moreover I don't read accepted Modules proposal yet. But I read a wonderful post "Understanding C++ Modules: Part 1: Hello Modules, and Module Units" and want to share some impressions.

It seems that simplicity and understandability weren't friends of C++ anytime in the past. But C++Modules lifts this up on another level.

It obvious that work on C++ standards is performed by very smart people. But sometimes you have to be as smart as they if not smarter to understand some of the new C++ additions and to find some beauty in them. C++Modules is an example.

Unfortunately I'm not as smart to participate in the evolution of C++ language. I'm just a (very ordinary) user of C++ and use C++ as a tool for solving my and my client's problems. Because of that, I can understand that there were some reasons to accept C++Modules in that form. But it's very hard to find and understand those reasons.

I can't understand why there are different types of module units (module interface, module implementation, module interface partition, module implementation partition, primary module interface) and very strange looking sentences like "export import :something;". Why not just:

module greeting;

export {

   public import another_module; // Instead of export import another_module.

   ... // Some ordinary C++ code.

// interface.

implementation {

   ... // Some ordinary C++ code.

// implementation.

If we have to deal with very big amount of code for a module we can simply use old #include directive:

module greeting;

export {

   public import another_module; // Instead of export import another_module.

   #include "some_declarations.hpp"
   #include "some_more_declations.hpp"

// interface.

implementation {

   #include "some_implementations.cpp"
   #include "some_more_implementations.cpp"
   #include "yet_more_implementations.cpp"

// implementation.

It's also hard to understand why modules and namespaces are orthogonal. Namespaces played their role in the pre-Modules world where we had only headers files and namespaces were used for "modularization" of C++ code.

But it's hard to imagine why we can write something like that:

import hello;

int main() {
   bye::tell();
}

From experience with different languages I expect that "import hello" introduces stuff from "hello" namespace. But in C++ we can "import hello" but receive "bye" namespace. Maybe there is some logic, but it seems also that "least surprise principle" doesn't live here.

I can suppose that there are some very important reasons why C++Modules and C++ namespaces are different entities. And I want to read the justification for this decision because as for me modules should make namespaces obsolete. With modules, we can get namespaces and nested namespaces (top-level modules and submodules).

Namespaces in C++ are open. It had two benefits in the past:

1. The content of namespace could be stored in several headers and source files. We opened namespace in one header file then reopened it in another file and so on.

But this benefit doesn't have sense with modules. IMHO.

2. An user can add specialization for its own types into external namespace.

But we can keep this benefit with modules if we add something like module's specialization (based on example from our json_dto library):

module json_dto specialization;

export {

   import my_module;

   template<>
   read_json_value( my_module::some_type & v, const rapidjson::Value & object )
   {
      ... // Specific version for some_type from my_module.
   }
}

Instead of conclusion.

I don't want to say that C++Modules proposal is bad. But it seems that C++Modules look much more complex than many of us expected. It also seems that C++Modules are intended to solve different problems than many of us can suppose.

It would be great to have some explanation about what C++Modules actually are, which problems they address, why C++Modules do it that way.

Without such explanation C++Modules remind me things like "export template" and "throw specification" from C++98 and "concept maps" from C++0x. They looked good in theory, but were deprecated or/and eliminated later.