вторник, 1 января 2030 г.

О блоге

Более двадцати лет я занимался разработкой ПО, в основном как программист и тим-лид, а в 2012-2014гг как руководитель департамента разработки и внедрения ПО в компании Интервэйл (подробнее на LinkedIn). В настоящее время занимаюсь развитием компании по разработке ПО stiffstream, в которой являюсь одним из соучредителей. Поэтому в моем блоге много заметок о работе, в частности о программировании и компьютерах, а так же об управлении.

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

понедельник, 31 декабря 2029 г.

[life.photo] Характерный портрет: вы и ваш мир моими глазами. Безвозмездно :)

Вы художник? Бармен или музыкант? Или, может быть, коллекционер? Плотник или столяр? Кузнец или слесарь? Владеете маленьким магазинчиком или управляете большим производством? Реставрируете старинные часы или просто починяете примус? Всю жизнь занимаетесь своим любимым делом и хотели бы иметь фото на память?

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

среда, 21 февраля 2018 г.

[prog.thoughts] Запись "_ = some()" в С++ -- это извращение или нет?

В связи с тем, что в C++ завезли атрибут [[nodiscard]], да и в чистом C благодаря расширениям компиляторов ряд функций помечается соответствующим образом, становится актуальным явное обозначение в коде тех мест, где возвращаемое значение функции намеренно игнорируется.

Только вот использовать для этого запись вида:

(void)::pipe(pipefd_);

(void)::fcntl(write_pipefd(), F_SETFL, O_DIRECT | O_NONBLOCK);
(void)::fcntl(read_pipefd(), F_SETFL, O_DIRECT | O_NONBLOCK);

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

_ = ::pipe(pipefd_);

_ = ::fcntl(write_pipefd(), F_SETFL, O_DIRECT | O_NONBLOCK);
_ = ::fcntl(read_pipefd(), F_SETFL, O_DIRECT | O_NONBLOCK);

Что достигается очень простой вспомогательной конструкцией:

// Вспомогательная штука, чтобы подавить предупреждения об игнорировании
// возвращаемого значения.
namespace {
   struct just_ignore_t {
      template<typename T> void operator=(T) {}
   } _;
}

Правда, боюсь, если это и найдет свое применение в C++, то очень ограниченное. Но смотрится прикольно :)

[prog.plain.old.c] Сижу тут, интегрирую C++ный RESTinio и С-шный libcurl...

Работаю над примерами интеграции RESTinio и libcurl. Чтобы показать, как можно объединять асинхронную обработку входящих HTTP-запросов с асинхронной же обработкой исходящих HTTP-запросов. Используется чистый libcurl без каких-либо C++ных обвязок.

Что же хочется сказать по ходу колупания с чисто C-шным кодом?

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

В общем, это какой-то звиздец, дорогие товарищи.

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

Возможно, у любителей C отношение к жизни какое-то специфическое. Ну, типа, "кто понял жизнь, тот не спешит".

пятница, 16 февраля 2018 г.

[prog.thoughts] Куда катится этот мир?

Вчера не удержался, сделал небольшой пост в G+. Получил там комментарий от ув.тов.Dev Lila. Начал отвечать и понял, что ответ выходит слишком длинным и лучше бы его преобразовать в блог-пост. Что, в общем-то, и делаю.

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

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

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

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

Такое ощущение, что современный C++ начинает восприниматься как Haskell лет 10-15 назад. Эдакий илитарный (от илитка) и оторванный от жизни и реальных задач язык для ботанов, которым хватило терпения зазубрить стандарт.

Так вот хотелось бы заострить внимание на двух вещах.

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

Можно, конечно, делать поправку на то, что это Хабр такой. Но Хабр является всего лишь отражением программерского сообщество. Или какой-то части (существенной, думаю) этого самого программерского сообщества. Что не внушает оптимизма по поводу будущего.

Второе. Мне непонятны жалобы на то, что чем дальше, тем меньше современный C++ похож на старый-добрый, теплый и ламповый "С с классами", к которому все так привыкли и который такой удобный и няшный (на самом деле нет). Это как если бы студенты математических факультетов начали бы жаловаться на то, что матанализ, блин, какой-то слишком сложный, чем основы высшей математики и анализа из старших классов школы. Есть вещи, которые в принципе сложные. Для борьбы с ними и создаются сложные инструменты. И не важно, будет ли это математический аппарат из матанализа или же variadic templates и ADL из C++. Если вам так повезло, что вы можете обходится более простыми инструментами, то это не означает, что сложные инструменты не нужны.

Другое дело, что я сам, бывает, не в восторге от того, какую сложность доводится встречать в том или ином коде. Иногда эта сложность является следствием неумения программировать или же отсутствием опыта или даже элементарного вкуса. Как говорится "Программу на Фортране" можно написать на любом языке программирования. Точно так же и со сложностью: чрезмерную сложность, при отсутствии мозгов и здравого смысла можно организовать буквально на ровном месте.

Тоже самое касается и попыток выжать из возможностей текущей версии языка то, на что он не способен. Например, как Boost.Lambda в свое время или же попытки эмулировать variadic templates на перегрузках функций с разным количеством аргументов. Тут нужно вносить изменения в язык, а не извращаться с библиотеками. Хотя с тогдашними темпами развития языка у многих выбора просто не оставалось. Тем не менее, я сам не был в восторге, когда видел такое в коде. Ну и старался держаться подальше от такого кода.

Но ведь сейчас же как раз все происходит по уму: то, что должно быть именно в язык (вроде лямбд, variadic templates и rvalue references) оказывается именно в языке. Нужны тебе продвинутые возможности -- используешь их. Причем используешь их в нормальном, штатном режиме, а не балансируешь на пределе возможностей компиляторов. Не нужны продвинутые фичи -- не используешь. Но осуждать их наличие в языке-то зачем?

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

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

вторник, 13 февраля 2018 г.

[prog.thoughts] Начинаю вспоминать, почему в свое время параллельные состояния не попали в SObjectizer :)

Параллельные состояния -- это одна из фишек иерархических конечных автоматов. Параллельность означает, что КА находится сразу в нескольких состояниях. Допустим, у КА есть ортогональные состояния A и B, а в состоянии B есть два параллельных состояния C и D. Получается, что КА может быть либо в состоянии A, либо же сразу в двух состояниях B.C и B.D.

Но самая жесть начинается когда параллельные состояния начинают вкладываться друг в друга. Простенький пример:

+==========================+
| A                        |
|   +===================+  |
|   | B                 |  |
|   |   +===========+   |  |
|   |   | C         |   |  |
|   |   +===========+   |  |
|   |                   |  |
|   |- - - - - - - - - -|  |
|   |   +===========+   |  |
|   |   | D         |   |  |
|   |   |  +=====+  |   |  |
|   |   |  | E   |  |   |  |
|   |   |  +=====+  |   |  |
|   |   |- - - - - -|   |  |
|   |   |  +=====+  |   |  |
|   |   |  | F   |  |   |  |
|   |   |  +=====+  |   |  |
|   |   |           |   |  |
|   |   +===========+   |  |
|   |                   |  |
|   +===================+  |
|                          |
|   +===================+  |
|   | G                 |  |
|   +===================+  |
|                          |
+==========================+

Есть состояние A, в нем есть два ортогональных подсостояния B и G. Внутри B есть два параллельных состояния C и D. Внутри D еще два параллельных подсостояния E и F.

Как вы думаете, в каких состояниях может находится КА?

Он может находиться либо в состоянии A.G, либо... Тра-та-та-там! A.B.C + A.B.D.E + A.B.D.F.

И ведь это еще не самый сложный случай :) Гораздо круче было бы, если бы в A.B.C были еще и свои параллельные состояния.

Приходится возвращаться к теме параллельных состояний поскольку ради этого и затевается работа над SObjectizer-5.5.22. Но вот задумываясь как же искать обработчик для сообщения, когда агент одновременно находится в состояниях A.B.C, A.B.D.E и A.B.D.F вызывает непроизвольный ужас.

Отдельный ужас возникает от мысли о том, как потом объяснять пользователю как этот поиск происходит. И почему у него вызывается обработчик из A.B.C, когда он думал, что агент находится в A.B.D.F...

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

понедельник, 12 февраля 2018 г.

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

Очередная части сериала "Шаблоны против копипасты". Но на этот раз не в блоге, а в виде статьи на Хабре: Задействовать для простых тестов наследование, полиморфизм и шаблоны? Почему бы и нет….

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

Предыдущая часть серии -- здесь.