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

О блоге

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

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

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

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

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

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

четверг, 7 сентября 2017 г.

[prog.actors] Хотите решить задачу с помощью акторов? Спросите меня как! :)

После того, как мне довелось разным людям в разных местах рассказывать про Модель Акторов вообще и про SObjectizer в частности, сложилось впечатление, что продвижению Модели Акторов в массы препятствует две вещи:

  1. Отсутствие понимания того, что такое Модель Акторов вообще. Это, на самом-то деле, совсем не проблема. Очевидно, что всего на свете знать нельзя, а объяснить основные принципы работы Модели Акторов можно буквально на пальцах (что, кстати говоря, подтверждается практикой).
  2. Отсутствие понимания того, как эту самую Модель Акторов, принципы которой можно объяснить на пальцах, применить для решения практических задач.

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

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

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

Зачем это нужно мне? Очевидно, что мои цели исключительно корыстные ;) Прежде всего мне нужен материал, на основе которого можно было бы убедительно рассказывать людям о том, где применение Модели Акторов уместно, а где нет. Кстати говоря, неуместность применения Модели Акторов -- это актуальный вопрос. Бывает, что люди слушая про Модель Акторов теряют представление о том, что данная модель применима далеко не всегда. И хорошо бы уметь вовремя различать, где имеет смысл брать акторов, а где этого делать не нужно. Так же мне полезно прикидывать, насколько наш SObjectizer пригоден для решения тех или иных задач. Опыт показывает, что это сильно идет на пользу SObjectizer-у. А т.к. сам SObjectizer распространяется под BSD-лицензией (бездвоздме т.е. даром), то это пойдет на пользу и всем, кто воспользуется SObjectizer-ом.

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

В общем, если есть задачка и желание ее обсудить, то милости прошу. Описывайте свои задачки в комментариях к этой заметке (можно в G+), либо по почте eao197 на gmail тчк com, либо со мной можно связаться через FB, LinkedIn или Habrhabr.

PS. Запись специально повисит вверху до сентября. Но, если дело пойдет, можно будет заказать продление ;)

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

[prog.flame] Rust-оманы зря пытаются продавать Rust С++никам, им бы поменять целевую аудиторию :)

Данный пост возник под впечатлением от двух недавних больших срачей на reddit-е на тему о том, почему Rust лучше C++: Have you used Rust? Do you prefer it over Modern C++? и Things I love about Rust while being a C++ programmer. А так же интересным ссылкам, которые проскочили в этих обсуждениях, например: вот (про некоторые проблемы Rust) или вот (специально для тех, кто верит, что безопасность Rust-а не имеет платы в run-time). Кроме шуток, срачи интересные, помимо обычного булшита (например, в очередной раз всплыл аргумент о том, как классно иметь возможность во время компиляции подключиться к СУБД, выкачать оттуда описание схемы данных и сгенерировать ORM) встречаются и прикольные примеры C++ граблей на ровном месте. Вот, скажем:

четверг, 23 марта 2017 г.

[prog] А кому нужны типизированные агенты?

В комментариях ко вчерашней статье на Habr-е очень активно обсуждается тема типизированных акторов. Мол, проблема акторов в том, что они "нетипизированны", ты отсылаешь актору сообщение A, но не знаешь, может ли этот актор обрабатывать сообщения типа A или же он ждет сообщения типа B. А вот если бы акторы были типизированными, то мы бы имели не просто actor_reference, а actor_reference<B> и во время компиляции бы получили по рукам за попытку отослать актору сообщение типа A.

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

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

Посему вопрос: а кому хотелось бы иметь акторов с типизированными интерфейсами в фреймворках вроде Akka, CAF, SObjectizer, QP/C++ и пр.?

Под катом маленький пример того, как это может выглядеть в SObjectizer...

среда, 22 марта 2017 г.

[prog.c++.fantasy] Дополнительные атрибуты implies и expects в дополнение к noexcept

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

Итак, сперва поговорим о том, почему мне хочется иметь что-то в дополнение к noexcept.

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

[prog.thoughts] Не хватает мне в C++ noexcept-блоков с compile-time проверками

Написал давеча вот такой простой код на C++, с прицелом на обеспечение сильной гарантии exception safety:

void
stats_controller_t::turn_on()
   {
      std::lock_guard< std::mutex > lock{ m_lock };

      if( status_t::off == m_status )
         {
            const auto run_id = m_run_id + 1;

            send_next_message( very_small_timeout(), run_id );

// (1)
            m_status = status_t::on;
            m_run_id = run_id;
         }
   }

Тут в действиях до точки (1) может возникнуть исключение. Но это не страшно, т.к. никаких изменений в объект stats_controller_t внесено не было. А если мы нормально дошли до точки (1), то новое состояние объекта нужно зафиксировать. Что и происходит посредством двух простых операций присваивания.

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

void
stats_controller_t::turn_on()
   {
      std::lock_guard< std::mutex > lock{ m_lock };

      if( status_t::off == m_status )
         {
            const auto run_id = m_run_id + 1;

            send_next_message( very_small_timeout(), run_id );
// (1)
            noexcept
               {
                  m_status = status_t::on;
                  m_run_id = run_id;
               }
         }
   }

И чтобы компилятор дал бы мне по рукам, если бы в noexcept-блоке я бы написал какую-нибудь операцию, которая не помечена как noexcept. Зачем мне это нужно?

Затем, что код развивается и со временем, внося правки в какой-то кусок кода, разработчик может тупо не знать, под какие именно условия этот кусок кода затачивается. Например, спустя какое-то время какой-то новый разработчик добавит в noexcept-блок еще одно действие:

noexcept
   {
      m_status = status_t::on;
      store_status_change_timepoint();
      m_run_id = run_id;
   }

А это новое действие ба-бах! и начнет выбрасывать исключения. Тем самым послав изначальную сильную гарантию в /dev/null.

Но еще хуже то, что типы объектов могут меняться со временем. Так, сейчас у меня, допустим, m_run_id имеет тип int. А со временем он может быть заменен на какой-то "тяжелый" тип с бросающим исключения конструктором копирования. Т.е. внешне код в stats_controller_t::turn_on() остается таким же самым, но на практике сильная гарантия опять же отправится в /dev/null.

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


Интересно: только я задумывался на тему таких noexcept-блоков в C++? Или же это еще кому-нибудь интересно? Спрашиваю потому, что есть C++ RG21 и, в принципе, данную идею можно запулить туда. Если она хоть кому-нибудь представляется стоящей.

PS. Старый блог-пост на связанную тему. Тогда я еще не имел представления о том, что именно будет означать noexcept в С++.