воскресенье, 16 октября 2016 г.

[prog.memories] Любопытное из воспоминаний Джо Армстронга про историю Erlang

Увидел в статье "A History of Erlang" от 2007-го (бесплатная PDF-ка легко гуглится):

But the Smalltalk was very slow -- so slow that I used to take a coffee break while it was garbage collecting.

Т.е. Smalltalk был настолько тормознутым, что приходилось отвлекаться на чашечку кофе, пока Smalltalk занимался сборкой мусора. Как я понимаю, речь шла о Smalltalk для BSD Unix на Vax 11/750. В 1985-86 годах.

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

четверг, 13 октября 2016 г.

[prog.wow] Новость про новый язык P от Microsoft

Собственно, вот сама новость: Microsoft Open-Sources P Language for Safe Async Event-Driven Programming. Небольшая цитата оттуда:

Microsoft describes P as a domain-specific language to model communication between components of an asynchronous system, such as an embedded, networked, or distributed system. A P program is defined in terms of finite state machines than run concurrently. Each of them has an input queue, states, transitions, a machine-local store, and can send asynchronous messages to the others.

Или, в моем корявеньком переводе на русский язык:

Microsoft описывает P как язык, заточенный под моделирование взаимодействия между компонентами в асинхронной системе, вроде встраиваемой, сетевой и распределенной системы. Программа в P определяется в терминах конечных автоматов, которые работают параллельно. Каждый из них имеет входящую очередь, состояния, переходы, локальное хранилище и может отсылать асинхронные сообщения другим [участникам].

Звучит как-то до боли знакомо...

Ба! Да мы же сделали это в SObjectizer-е фиг знает когда и уже много лет пользуемся полученными плюшками ;)

Правда, в P обещают верификацию. Вот чего у нас нет, того нет...

понедельник, 10 октября 2016 г.

[prog.c++] Статистика по использованию try-catch в исходниках SO-5.5.18

На волне темы про использование исключений подсчитал, как часто в исходниках последней стабильной версии SO-5.5.18 встречаются блоки try-catch. Общий объем ядра SO-5 порядка 25KLOC (не считая пустых строк и комментариев). Всего насчитал 25 блоков try (в двух-трех блоках по 2 секции catch). Из общего числа catch-ей:

  • в 10 случаях catch используется для преобразования одного типа исключения в другое. В нескольких из этих случаев перед пробросом нового исключения выполняются действия по очистке/откату операций;
  • в 7 случаях в catch-е иницируется вызов std::abort() (перед этом зачастую идет логирование проблемы);
  • в 4-х случаях исключение "проглатывается". В двух из них предварительно логируется;
  • в 3-х случаях ловятся исключения, выпущенные из обработчиков событий агентов. В этих catch-ах происходит то, что описывалось в свежей статье на Хабре;
  • в одном случае ловится исключение, выпущенное из обработчика события агента, для фиксации этого исключения в std::promise. Этот сценарий используется для синхронного взаимодействия агентов;
  • в одном случае используется логика на исключениях: с помощью исключения разрывается цикл выборки событий из очереди одного из диспетчеров. Оказалось, что такая реализация цикла самая простая;
  • и в одном случае catch используется для эмуляции noexcept для старых VC++ компиляторов.

В общем, получается где-то по одному try-catch на тысячу строк кода.

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

А вот два других случая с игнорированием исключений интереснее. Один из них такой (сорри за качество английского):

   //! Switching storage from map to vector.
   void
   switch_storage_to_vector()
      {
         // All exceptions will be ignored.
         // It is because an exception can be thrown on staged 1-2-3,
         // but not on stage 4.
         try
            {
               // Stage 1. New containers to swap values with old containers.
               // An exception could be thrown in the constructors.
               map_type empty_map;
               vector_type new_storage;

               // Stage 2. Preallocate necessary space in the new vector.
               // An exception can be thrown here.
               new_storage.reserve( m_map.size() );

               // Stage 3. Copy items from old map to the new vector.
               // We do not expect exceptions here at v.5.5.12, but
               // the situation can change in the future versions.

               // Use the fact that items in map is already ordered.
               std::for_each( m_map.begin(), m_map.end(),
                  [&new_storage]( const map_type::value_type & info ) {
                     new_storage.push_back( info.second );
                  } );

               // Stage 4. Swapping.
               // No exceptions expected here.
               m_vector.swap( new_storage );
               m_map.swap( empty_map );
               m_storage = storage_type::vector;
            }
         catch(...)
            {}
      }

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

Какова мораль? Да нет никакой морали. Просто любопытно стало. Думаю, что для библиотек небольшое количество try-catch -- это нормально. В прикладном кода плотность испрользования try-catch наверняка выше.

пятница, 7 октября 2016 г.

[prog.flame] Длина строки кода таки важная штука

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

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

Еще раз убедился в том, что ограничение на 78-80 символов для длины строки кода -- это вполне разумно.

PS. Длинная строка -- это когда 100+ символов.

вторник, 4 октября 2016 г.

[prog.c++] Официальный анонс конференции Corehard C++ Autumn 2016 в Минске

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


Добрый день, друзья!
22 октября сообщество CoreHard.by проведет очередную большую конференцию выходного дня, посвященную языку С++ и сопутствующим «хардкорным» технологиям. Спикеры из ведущих IT-компаний Беларуси, России и не только соберутся вместе, чтобы рассказать о своем опыте в разработке и тестировании. Мы собрали лучшие доклады на самые различные темы: модели акторов и бинарная совместимость, эффективная работа с JSON в С++, рефлексия для С++ и GMock framework, рассказы непосредственных участников о разработке Bing и PVS-Studio для Linux и многое-многое другое.
Приглашенные спикеры:
  • Антон Полухин (Яндекс, Москва) – активный разработчик C++ библиотек Boost, автор книги “Boost C++ Application Development Cookbook” и представитель в международном комитете по стандартизации С++ от России. Антон расскажет о том, как организовать рефлексию в C++14 на этапе компиляции без макросов и вспомогательной разметки.
  • Егор Кишилов (Microsoft, Редмонд, США) более 8 лет работает в Microsoft, все это время занимаясь разработкой поисковой системы Bing. Егор расскажет о том, как построена разработка в Microsoft и что из себя представляет поисковая система Bing.
  • Святослав Размыслов (PVS-Studio, Тула, Россия) руководит отделом, занимающимся разработкой ядра анализатора PVS-Studio для анализа C и C++ кода. Святослав расскажет о том, как создавалась версия PVS-Studio под Linux.
  • Евгений Охотников – независимый разработчик с более чем 20-летним стажем, занимается OpenSource-инструментарием для упрощения разработки многопоточных приложений на языке C++. Евгений расскажет о моделях акторов для С++.
Полную сетку докладов ищите на нашем официальном сайте.
Конференция состоится в субботу, 22 октября и будет проходить в два потока.
Совместно с компанией JetBrains мы проведем розыгрыш лицензий на продукты ReSharper C++, CLion, AppCode среди участников.
Друзья, регистрация обязательна, спешите зарегистрироваться наофициальном сайте конференции.
Приходите, будет интересно!
С уважением,
Команда CoreHard.by

понедельник, 3 октября 2016 г.

[prog.c++] Вопрос за двоичную сериализацию в С++

Внезапно возник вот такой вопрос к читателям и просто интересующимся: а как часто вам доводилось сталкиваться с сериализацией сложных структур данных в С++ программе? Под сложными понимаются структуры, в которых активно используются разнообразные типы контейнеров (например, вектора, деки, списки, множества и мультимножества, словари и т.д.) и используются ссылки(указатели) на полиморфные объекты (в том числе и циклические ссылки).

Что вы использовали в этих случаях?

Какой-то готовый инструмент, вроде asn1-компилятора, protobuf, thrift, cap'n'proto, cereal, boost::serialization или что-то другое? Писали все сами?

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


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

Буду признателен как за ответы на эти вопросы, так и на распространение ссылок на этот пост.

пятница, 30 сентября 2016 г.

[prog.flame] portfile.cmake из Vcpkg супротив рецепта для MxxRu::externals

Попробовал представить, как сделать адаптацию SO-5 под новую волшебную пилюлю от Microsoft под названием Vcpkg. Проблевался. Какую только херню, пардон май френч, народ готов жрать только потому, что эта херня от MS или от Google. Поразительно.

Суть Vcpkg в том, что под каждый проект, который хочется затянуть в этот самый Vcpkg, нужно создать файлик portfile.cmake, в котором будут находится инструкции по доставанию исходников этого проекта и по его сборке (если проект нуждается в сборке). Для примера покажу, как выглядит portfile.cmake для библиотеки Range-V3. И как это же самое выглядит в виде рецепта для MxxRu::externals.

Итак, portfile.cmake для Vcpkg:

include(vcpkg_common_functions)
set(SOURCE_PATH ${CURRENT_BUILDTREES_DIR}/src/Range-V3-VS2015-ede9ad367fd5ec764fecb039c874614bd908e6b6)
vcpkg_download_distfile(ARCHIVE
    URLS "https://github.com/Microsoft/Range-V3-VS2015/archive/ede9ad367fd5ec764fecb039c874614bd908e6b6.zip"
    FILENAME "range-v3-ede9ad367fd5ec764fecb039c874614bd908e6b6.zip"
    SHA512 e978c7694471d8616c248647b77689f377b3e2517347abde8629b140e5994de8bf686565a24cdd7dd222f325d43b775f5e478c91220dce75313985499b134637
)
vcpkg_extract_source_archive(${ARCHIVE})

file(COPY ${SOURCE_PATH}/LICENSE.txt DESTINATION ${CURRENT_PACKAGES_DIR}/share/range-v3)
file(RENAME ${CURRENT_PACKAGES_DIR}/share/range-v3/LICENSE.txt ${CURRENT_PACKAGES_DIR}/share/range-v3/copyright)
file(INSTALL ${SOURCE_PATH}/include DESTINATION ${CURRENT_PACKAGES_DIR} FILES_MATCHING PATTERN "*.hpp")
vcpkg_copy_pdbs()

Тоже самое для MxxRu::externals:

MxxRu::arch_externals :range_v3_vs2015 do |e|
  e.url 'https://github.com/Microsoft/Range-V3-VS2015/archive/ede9ad367fd5ec764fecb039c874614bd908e6b6.zip'
  e.sha512 'e978c7694471d8616c248647b77689f377b3e2517347abde8629b140e5994de8bf686565a24cdd7dd222f325d43b775f5e478c91220dce75313985499b134637'

  e.map_dir 'include/*' => 'dev/range-v3'
  e.map_file 'LICENSE.txt' => 'dev/range-v3/*'
end

Резюмируя. Если кому-то действительно нужно, чтобы SO-5 был доступен из портов Vcpkg, то дайте знать. Мы сделаем. Но только если это кому-то действительно нужно. Ибо Vcpkg выглядит как говно и пахнет как говно. А посему вмазываться в говно и сопровождать потом это говно просто так не хочется, только если на то будут причины.