пятница, 27 сентября 2013 г.

[prog.flame] Про отчет "менеджера" об использовании Хаскеля

Ссылку на Хабровскую статью "Haskell в продакте: Отчёт менеджера проекта" нашел в ЖЖ ув.тов.grundik. В том же ЖЖ у меня состоялся очередной спор с тов.thesz. А уже в процессе спора оформились претензии к тексту Хабровской статьи, которые я решил оформить в виде отдельного поста.

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

Ну а теперь пойдем по-порядку.

Во-первых, в статье не указан объем и характер задачи, размер и состав проектной команды. Для чего применялся Хаскель? Для проекта, который в течении двух лет писала команда из 50 человек? Или для мелких утилит, которые три человека время от времени клепали по просьбе сисадминов? Какова важность этой разработки для компании? Насколько жесткие дедлайны для релизов? Каковы последствия от дефектов в ПО после его запуска в эксплуатацию?

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

Во-вторых, в статье не говорится о целях, которые ставились перед новой разработкой на Хаскеле. Т.е. из статьи следует, что какую-то из ранее написанных на Питоне систему переписали на Хаскеле. Но зачем, почему? Это не праздные вопросы для ПМа и руководства. Ведь в предыдущую версию было вложено время и деньги компании. Сейчас требуется повторное вложение денег. Чем оно обосновывается? Были ли какие-нибудь альтернативы? Делались ли какие-то прикидки по срокам/трудозатратам различных вариантов (сопровождение версии на Питоне против разработки новой версии на Хаскеле)? Если делались, то какие еще параметры рассматривались в сравнении? Учитывались ли какие-нибудь риски и если да, то какие?

Если здесь попробовать сложить озвученные выше "во-первых" и "во-вторых", то версию о том, что на Хаскеле стали писать что-то большое и важное, можно отбросить сразу. Поскольку я не могу себе представить, как разработку, в которую было вложено, скажем, 100 человеколет (т.к. 2 года работы команды из 50 человек) просто так взяли и стали переписывать на Хаскеле. При всем моем скептическом отношении к профессионализму российских ТОП-менеджеров, я слабо себе представляю, как кто-нибудь из ТОП-ов пошел бы на перечеркивание предыдущих затрат и новые инвестиции в разработку в таком же объеме.

Следовательно, речь идет о неких мелких приложениях/утилитах, и совсем небольшой проектной команде. Косвенно подтверждение этому можно найти в комментариях, где приведены сравнительные размеры реализаций одного из приложений на Хаскель и Питоне: 212 против 263 строк.

Эта информация очень важна для руководителей проектов и проектных команд. Т.к. она позволяет таким читателям спроецировать опыт автора статьи на свою ситуацию. И если мне, скажем, нужно управлять разработкой компонента в 300KLOC то выводы из статьи я сделаю несколько другие, чем если бы мне приходилось управлять разработкой нескольких утилит, по 5KLOC каждая.

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

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

Скорость исполнения. Блин, кто в здравом уме будет сравнивать скорость исполнения компилирующегося в нативный код Хаскеля с Питоном?!!! В ваших задачах нужна производительность? Так с какого хера там Питон (да еще без C/C++ных вставок для самых ресурсоемких операций)? А если скорость работы ваших Питоновых компонентов вас устраивает, то зачем тогда приводить сравнение производительности с Хаскелем?

Про указанные в статье проблемы с многопоточностью Питона и его GIL-ом ничего сказать не могу. Имхо, тот, кто на языках вроде Питон или Руби начитает серьезно использовать многопоточность для увеличения производительности (нет, серьезно, производительности на Питоне/Руби?!), тот сам себе...

Отдельно доставила часть фразы "Быстрее Erlang/Java (и других vm-based языков)". Уровнять Эрланг и Джаву по производительности, это сильно.

Использование памяти. Вообще смешно. В качестве примера приводится потребление памяти написанным на C демоном -- 0.15Mb. При этом их устраивает расход памяти Питоновских и Хаскелевских демонов -- от 9 до 20Mb. Ребята, да вам расход памяти вообще пох! Зачем же вы об этом пишете?

Настоящие исполняемые файлы. Во-первых, у автора статьи по этому поводу, похоже, какой-то пунктик. Во-вторых, если бы это действительно было важно, дальше C/C++ у них бы дело никогда и не пошло бы. А так у них, похоже, и Джава, и Эрланг, и Питон жили, живут и будут жить без проблем. Значит нифига этот параметр не важен, вычеркиваем ;)

Качество кода. Тут какой-то детский сад. Сравнение динамической типизации со статической (да еще и очень строгой статической типизацией). Кто-то ожидал какого-то другого итога?

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

Не, тут меня занесло. Обычные ПМы, которые знакомы только с MS Project-ом и способны разве что сроки задач в диаграммах Ганта передвигать, а таковых в нерезиновой туева хуча, совершенно точно не будут знать об особенностях разработки на динамически типизированных языках программирования. Прошу прощения, мы тут в себя в провинции привыкли работать иначе, подотошнее, тащетельнее ;)

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

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

Сложность сопровождения. Выше я уже задавал риторический вопрос об оценке рисков. Вот это и есть воплощение одного из рисков. "Поиск программистов является проблемой, как бы апологеты Хаскеля и не говорили об обратном. Даже вариант «переучить» является проблемой, потому что под функциональное программирование, особенно с «комонадами» и template haskell, нужно сильно мозги повернуть." Это ПМу проекта стало очевидно только в процессе разработки проекта? А до старта проекта это как-то учитывалось? И, что более важно, как эту проблему собираются решать в будущем?

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


Если резюмировать, то у меня сложилось такое впечатление. Есть небольшая компания, в которой есть небольшая группа разработчиков, пишущих какие-то небольшие внутренние приблуды. Может групп разработчиков там больше, но конкретно та группа, которая занималась описанной в статье разработкой, маленькая, полагаю, 3-5 человек. Эта команда работает в довольно неформальной обстановке. У них прямое и неформализованное общение с бизнес-подразделениями, а так же с техническими службами/сисадминами. Задачи на разработку вряд ли формализуются в виде документов, заверяемых подписями представителей всех заинтересованных подразделений. Возможно, зачастую задачи спонтанно возникают в результате общения руководителя сисадминов с тим-лидом и кем-то из бизнеса. Какой-то более-менее "взрослый" процесс разработки проектов (со стадиями написания и согласования ТЗ, проектирования, реализации, документирования, тестирования, прохождения приемо-сдаточных испытаний) отсутствует как класс. Как отсутствует и использование соответствующего инструментария (Project, Bug-Tracking, Continous Integration, репозиторий документов). В принципе, для небольших сплоченных коллективов это нормально и естественно.

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

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

четверг, 26 сентября 2013 г.

[work] Небольшая заметка Ричарда Бренсона. How I Hire: Focus On Personality

Редкая хорошая ссылка на LinkenIn: заметка Ричарда Бренсона "How I Hire: Focus On Personality". После прочтения "Теряя невинность" Ричарда Бренсона, основателя группы компаний Virgin, я с большим интересом и вниманием отношусь к тому, что говорит Бренсон. И, я надеюсь, приведенные ниже цитаты из упомянутой мной заметки, подтвердят, что это не напрасно. Знающих же английский смело отправляю к первоисточнику, там совсем немного текста.

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

The first thing to look for when searching for a great employee is somebody with a personality that fits with your company culture. Most skills can be learned, but it is difficult to train people on their personality. If you can find people who are fun, friendly, caring and love helping others, you are on to a winner.

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

Don’t be afraid of hiring mavericks. Somebody who thinks a little differently can help to see problems as opportunities and inspire creative energy within a group. Some of the best people we’ve ever hired didn’t seem to fit in at first, but proved to be indispensable over time.

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

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

If you hire the wrong person at the top of a company, they can destroy it in no time at all. Promoting from within is generally a good idea as the employee who is promoted will be inspired by the new role, already know the business inside out, and have the trust and respect of their team.

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

Очевидные же вещи говорит Бренсон. До них несложно дойти просто исходя из здравого смысла.

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

среда, 25 сентября 2013 г.

[business] Еще про Элопа, Nokia, Microsoft и чужие деньги

Не могу не запостить у себя несколько цитат из Бывший глава Nokia получит бонус $25,5 млн «за то, что сравнял компанию с землей»

...Бывший президент и генеральный директор Nokia Стивен Элоп (Stephen Elop), который сложил свои полномочия после объявления о покупке смартфонного бизнеса Nokia корпорацией Microsoft, получит бонус за возвращение в софтверную корпорацию в размере 18,8 млн евро ($25,5 млн)...
...Размер бонуса будет более чем вдвое больше по сравнению с тем, сколько Элоп заработал в Nokia за 3 года руководства компанией. Кроме того, стоит отметить, что нанимая Элопа в 2010 г., компания Nokia выплатила ему премию в размере $6,2 млн, чтобы он у нее работал...
...Газета Financial Times подсчитала, что Элоп получил по 1 млн евро за каждые потерянные компанией Nokia 2,5 миллиарда рыночной капитализации.

Эффективный профессионал, что тут еще скажешь.

На ум почему-то приходят ассоциации с Геростратом и тридцатью серебренниками. Хотя все это just a business.

[prog.wow] Достойно отлития в бронзе :)

Обожаю запах напалма программерского флейма по утру:

I>Односвязный список это ни разу не экзотика, это основы структур данных. Не бывает человека, который хорошо понимает структуры данных и не знает что такое связный список.

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

вторник, 24 сентября 2013 г.

[prog.c++] Очередной подход к обеспечению null safety для сообщений в SObjectizer

Главным средством взаимодействия между агентами в SObjectizer являются сообщения. Но сами сообщения можно разделить на два фундаментальных подвида: собственно сообщения, которые переносят информацию, и сигналы, т.е. уведомления которые не несут больше никакой информации кроме самого факта своего существования. Например, пусть есть два агента, Master и Slave. Когда нужно что-то сделать, скажем, обработать порцию данных, Master отсылает Slave сообщение msg_process_data, в котором находятся подлежащие обработке данные. Когда работу нужно завершить, агент Master отсылает агенту Slave сигнал msg_shutdown. Этот сигнал никакой другой информации не переносит, важен сам факт возникновения этого сигнала.

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

void a_slave_t::evt_process_data( const msg_process_data * msg ) { ... }

void a_slave_t::evt_shutdown( const msg_shutdown * ) { ... }

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

// Отсылка сообщения.
msg_process_data * msg = new msg_process_data(...);
so_4::api::send_msg( "a_slave""msg_process_data", msg );

// Отсылка сигнала.
so_4::api::send_msg( "a_slave""msg_shutdown"0 );

Однако, уже в самом начале использования SO4 стало понятно, что для сообщений, которые обязаны переносить данные, нужно обеспечивать null safety, т.е. на уровне SObjectizer-а запрещать попытки передачи нулевых указателей в качестве экземпляра такого сообщения.

Здесь нужно сказать пару слов о том, почему null safety для сообщений важен. Думаю, многие C++ программисты сталкивались с ситуацией, когда по ошибке передавали nullptr в std::string(const char *). Хотя все знают, что делать этого не следует, класс basic_string не содержит обработки нулевого указателя в своем конструкторе, но тем не менее, время от времени такое происходит. Приложение валится от access violation и потом приходится искать в отладчике причины краха. Аналогичные вещи иногда случаются и с агентами в SObjectizer, особенно когда подготовка объекта-сообщения записывается не одной-двумя строчками кода. Если подготовка экземпляра сообщения нетривиальна и задействует сторонний API, то запросто можно получить нулевой указатель, даже не заметив этого. Мне самому приходилось наступать на эти грабли и доводилось видеть последствия у коллег. Так что null safety окупается.

Первоначально null safety обеспечивалась слишком уж в духе Plain C: для сообщения можно было назначить т.н. checker -- функцию, которая проверяет экземпляр сообщения и говорит, корректен ли он или нет. Поскольку в рассматриваемом здесь примере обработчик msg_process_data не должен получать нулевых указателей на экземпляр сообщения, сообщение msg_process_data должно было бы быть снабжено checker-ом хотя бы следующего вида:

bool msg_process_data_checker( const msg_process_data * msg )
{
   // Не должно быть нулевым.
   return 0 != msg;
}

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

Естественно, заставлять разработчика писать для одной проверки отдельную функцию-checker, а потом еще и регистрировать ее для типа сообщения, было не правильно. Поэтому в SO4 был добавлен еще один тип формата обработчика событий:

void a_slave_t::evt_process_data( const msg_process_data & msg ) { ... }

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

В SObjectizer-5 с сообщениями и обработчиками событий произошли серьезные изменения. Сообщения теперь должны быть наследниками специального базового типа so_5::rt::message_t, а обработчики событий получают не экземпляр сообщения непосредственно, а ссылку на специальный объект-обертку:

// Декларация сообщения.
struct msg_process_data : public so_5::rt::message_t
{ ... };

// Обработчик события.
void a_slave_t::evt_process_data(
   const so_5::rt::event_data_t< msg_process_data > & msg ) { ... }

// Отсылка сообщения.
std::unique_ptr< msg_process_data > msg( new msg_process_data(...) );
slave_mbox->deliver_message( std::move(msg) );

Обеспечению null safety для сообщений в SO5 так же было уделено внимание. Для этих целей предназначалась обертка not_null_event_data_t, которую нужно было указывать в качестве параметра обработчика события вместо event_data_t. Т.е. приведенный выше обработчик evt_process_data должен был бы быть описан так:

// Обработчик события.
void a_slave_t::evt_process_data(
   const so_5::rt::not_null_event_data_t< msg_process_data > & msg ) { ... }

Но тут я допустил два серьезных промаха. Во-первых, передача сообщений в SO-проектах происходит гораздо чаще, чем передача сигналов. Поэтому для описания обработчиков сообщений нужно было выбрать более удобное имя, а не not_null_event_data_t. Например, нужно было бы выбрать имена event_data_t и signal_data_t. Или же event_data_t и nullable_event_data_t. Мы же остановились на not_null_event_data_t и event_data_t, а я не заметил вовремя, к чему это приведет.

Во-вторых, на ранних стадиях использования SO5 я не проконтролировал корректное использование not_null_event_data_t и event_data_t в прикладом коде. Т.е. не навязал разработчикам дисциплины правильного выбора между not_null_event_data_t и event_data_t. Что привело к закономерному результату: event_data_t используется повсеместно, тогда как not_null_event_data_t можно было найти только в нескольких тестах и примерах самого SO5 (да и то в очень малых количествах).

В общем, когда дошли руки навести порядок с null safety для сообщений выяснилось, что уже есть большое количество кода с event_data_t, который просто так на not_null_event_data_t не перепишешь. Нужно было придумывать что-то другое. И вот что было сделано в разрабатываемой сейчас версии 5.2.

Во-первых, был выделен специальный класс so_5::rt::signal_t, наследник message_t. Этот класс должен стать базой для всех сигналов. Тогда как для сообщений продолжит использоваться message_t. Конструктор so_5::rt::signal_t сделал приватным, т.ч. наследника от signal_t объявить можно, а вот создать его экземпляр не получится. Так задумано специально, поскольку сигнал -- это уведомление без данных, какой-то объект создавать для него не нужно в принципе.

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

В-третьих, в публичный API SO5 было добавлены специальные compile- и run-time проверки. Целью которых является: a) не дать возможности использования сигналов в качестве сообщений и b) не дать возможности отослать nullptr в качестве экземпляра сообщения. Например, посредством простой функции ensure_not_signal, использующей возможности C++11, класс event_data_t модифицирован так, что в compile-time пресекаются попытки получить доступ к внутренностям сигнала. Немного технических детали для иллюстрации:

templateclass MSG >
void
ensure_not_signal()
{
   static_assert( !std::is_base_of< signal_t, MSG >::value,
         "instance of signal_t cannot be used in place of instance of "
         "message_t" );
   static_assert( std::is_base_of< message_t, MSG >::value,
         "message class should be derived from message_t" );
}
templateclass MSG >
class event_data_t
{
   public:
      //! Constructor.
      event_data_t( const MSG * message_instance )
         :  m_message_instance( message_instance )
      {}

      //! Access to message.
      const MSG&
      operator * () const
      {
         ensure_not_signal< MSG >();

         return *m_message_instance;
      }

      //! Access to raw message pointer.
      const MSG *
      get() const
      {
         ensure_not_signal< MSG >();

         return m_message_instance;
      }

      //! Access to message via pointer.
      const MSG *
      operator -> () const
      {
         ensure_not_signal< MSG >();

         return get();
      }

   private:
      //! Message.
      const MSG * const m_message_instance;
};

Т.е. если агент Slave в обработчике сигнала msg_shutdown попробует обратиться к event_data_t<msg_shutdown>::get() или event_data_t<msg_shutdown>::operator*(), то возникнет ошибка компиляции (если, конечно, разработчик не забудет унаследовать msg_shutdown от so_5::rt::signal_t).

Методы deliver_message так же получили дополнительные compile- и run-time проверки. Теперь они выглядят так:

templateclass MSG >
void
ensure_message_with_actual_data( const MSG * m )
{
   ensure_not_signal< MSG >();

   if( !m )
      throw so_5::exception_t(
            "an attempt to send message via nullptr",
            so_5::rc_null_message_data );
}
templateclass MESSAGE >
void
mbox_t::deliver_message(
   std::unique_ptr< MESSAGE > && msg_unique_ptr )
{
   ensure_message_with_actual_data( msg_unique_ptr.get() );

   deliver_message(
      type_wrapper_t( typeid( MESSAGE ) ),
      message_ref_t( msg_unique_ptr.release() ) );
}

Т.е. теперь deliver_message во время компиляции проверяет, что пытаются оправить именно экземпляр message_t (т.ч. сейчас signal_t в deliver_message не засунешь). А в run-time проверяется, чтобы указатель на message_t был отличен от nullptr.

Для отсылки же сигнала в SObjectizer-5.2 один из вариантов deliver_message был переименован в deliver_signal, который в compile-time проверяет, чтобы в качестве сигнала не попробовали отослать message_t.

Вот как-то так получилось. Вроде бы выглядит логичнее и удобнее, чем в SObjectizer-5.1. Но как это пойдет на практике, нужно будет еще посмотреть. В любом случае, новые возможности C++11, в частности, type_traits, оказались очень к месту.

понедельник, 23 сентября 2013 г.

[life.humour] Журналистика такая журналистика...

Новость раз: "Учительница из Жлобина выиграла в украинском телешоу «Рассмеши комика»", цитата:

Учитель истории Беларуси из Жлобина Марина Барискова приняла участие в пятом сезоне популярного украинского телевизионного конкурса «Рассмеши комика» и выиграла крупную сумму денег.

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

...Так я ж учитель только по диплому. Ни дня в школе не работала. Только на практике...
... Все-таки основная и любимая работа — в Центре [eao197: Центре творчества детей и молодежи «Эврика»]. Здесь я руководитель команды КВН школьников и учащейся молодежи ВТСО, что означает «Водичка. Трубочки. Семечки. Орешки».

Но заголовки броские, да. Перестать, что ли, читать советские газеты перед сном? ;)

[life.photo] ЖЖ фотографа Ильи Рашапа подтолкнул к нижеследующему тексту

С подачи ув.тов.Alexander Gonchar открыл для себя ЖЖ российского фотографа Ильи Рашапа (его персональный сайт). До сих пор читаю все дальше и дальше в глубь журнала, не могу остановиться. Зато прекрасно понял, что цифровой фотографии я даже еще и не начинал учиться.

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

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

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

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

Но это мое отношение к фотографии. И я прекрасно понимаю, что во многих областях современного применения фото, это совершенно неправильное отношение. То, чем занимается Илья Рашап, очевидно, как раз из такой области.

А еще одна причина безразличного отношения к работам Ильи Рашапа стала мне понятна после просмотра нескольких роликов на YouTube. Первый -- это интервью Сергея Максимишина. В котором Сергей приводит слова американского редактора фотоиздания: "В работах русских фотографов слишком ощущается пот фотографа". Пока запомним это высказывание.

Два других ролика -- это небольшие рекламные зарисовки Phase One об одном дне работы фотографа David Thompson с камерой Phase One и софтом Capture One: часть первая и часть вторая. Если сравнить это с короткими фильмами о фотосессиях Ильи Рашарпа для какого-то корпоративного календаря (1, 2, 3, 4 и 5), то я не вижу принципиальных различий в работе Томпсона и Рашарпа, а так же того, чтобы модель английского фотографа отличалась по поведению, раскрепощенности, естественности или как-то еще от русских моделей. Но вот у Томпсона получается фото, на котором видно, что фотограф успел запечатлеть какой-то неуловимый момент, какую-то легкость и сиюминутность. Тогда как у Рашапа при всей художественной выразительности в фотографии намного сильнее ощущается вложенный фотографом в снимок тяжелый труд. Вот почему так? ХЗ. Может особенность нашего менталитета.

А может мне это просто так кажется. И это весьма вероятно. На почве зависти к чужим успехам :)))

PS. Если не жалко 20-25 минут своего времени, рекомендую посмотреть ролики работы Дэвида Томсона (еще раз ссылки: часть первая и часть вторая). Там даже не нужно английский знать. Достаточно просто понаблюдать за работой настоящего профессионала: он не занимается обустройством студии, не делает сам постобработку, он даже при первичной обработке в Capture One сам не передвигает ползунки яркости и контрастности! Но он самый главный, без него ничего бы не получилось :) Сразу вспоминается анекдот про "10 рублей за удар, 500 за то, что знаю куда ударить" :))