суббота, 28 ноября 2009 г.

[comp.prog.bugs] Серия заметок про отладку в блоге “Алёна С++”

В блоге “Алёна С++” началась публикация серии заметок про отладку, уже опубликованы первая (“Искусство отладки”) и вторая (“Искусство отладки: как предупредить появление багов”) части.

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

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

Впрочем, старым и матерым программистам так же может быть интересно. Я, например, с удивлением для себя обнаружил, что существует такой феномен, как “отладка – это не престижно”. Никогда с таким не сталкивался раньше. Встречал мнение, что программирование – это ерунда, а вот разработка архитектуры – это круто. А так же с мнением, что и разработка архитектуры это ерунда, а вот создание математических моделей… Теперь вот узнал про то, что для некоторых отладка – это не престижно. Век живи, век учись.

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

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

А средства поиска и устранения багов – это как оснащение такого корабля средствами спасения на случай, если он все-таки пошел ко дну.

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

пятница, 27 ноября 2009 г.

[comp.humour] Рождественский танец роботов от RoboBuilder

Нравятся мне танцующие роботы почему-то :) Вот еще один:

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

[life.wow] Байка про Виктора Гюго: cтрижка как мотиватор

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

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

Найдено в “Аргументах и Фактах”.

PS. Этот способ хорош только для тех специальностей, где не требуется очное общение с другими людьми. Вот у меня, например, производительность вне офиса выше, чем в офисе ;)

[comp.prog.boasting] Ход одного рефакторинга

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

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

|| Вариант первый: используется только HTTP-аутентификация.
{auth_params "http_basic"
  {user_name "name"}
  {user_password "password"}
}

|| Вариант второй: HTTP-аутентификация + SSL с проверкой сервера.
{auth_params "http_ssl_server"
  {user_name "name"}
  {user_password "password"}
  {ca_file "path/to/ca/file"}
}

|| Вариант третий: SSL с проверкой и клиента, и сервера.
{auth_params "ssl_client_server"
  {ca_file "path/to/ca/file"}
  {client_cert_and_key_file "path/to/pem/file"}
  {client_private_key_password "password"}
}

Нужно было написать функцию, которая после завершения парсинга тега {auth_params} проверяла бы корректность сочетания вложенных тегов.

Первый вариант получался вот таким:

/* Вариант I */
void
tag_auth_cfg_t::on_finish(
  const cls_3::parser_context_info_t & context )
  {
    base_type_t::on_finish( context );

    const std::string & auth_type_name = base_type_t::query_value();
    auth_cfg_t::auth_type_t auth_type = get_auth_type( auth_type_name );

    // В режимах http_basic и http_and_ssl_server имя пользователя
    // и пароль обязательно должны быть определены. А в режиме
    // ssl_client_server -- не должны.
    if( autg_cfg_t::auth_ssl_client_server_check != auth_type )
      {
        if( !m_user_name.is_defined() )
          throw cls_3::semantic_ex_t(
              "mandatory tag should be defined: " +
              m_user_name.query_name() );
        if( !m_user_password.is_defined() )
          throw cls_3::semantic_ex_t(
              "mandatory tag should be defined: " +
              m_user_password.query_name() );
      }
    else
      {
        if( m_user_name.is_defined() )
          throw cls_3::semantic_ex_t(
              "tag should not be used: " +
              m_user_name.query_name() );
        if( m_user_password.is_defined() )
          throw cls_3::semantic_ex_t(
              "tag should not be used: " +
              m_user_password.query_name() );
      }
    ... // Дальнейшие проверки.
  }

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

/* Вариант II */
void
mandatory_tag_not_defined(
  const ... & tag, const std::string & auth_mode_name )
  { ... /* Порождение исключения с нужным сообщением. */ }

void
disabled_tag_not_defined(
  const ... & tag, const std::string & auth_mode_name )
  { ... /* Порождение исключения с нужным сообщением. */ }

void
tag_auth_cfg_t::on_finish(
  const cls_3::parser_context_info_t & context )
  {
    ... /* Начало точно такое же. */
    if( autg_cfg_t::auth_ssl_client_server_check != auth_type )
      {
        if( !m_user_name.is_defined() )
          mandatory_tag_not_defined( m_user_name, auth_type_name );
        if( !m_user_password.is_defined() )
          mandatory_tag_not_defined( m_user_password, auth_type_name );
      }
    else
      {
        if( m_user_name.is_defined() )
          disabled_tag_defined( m_user_name, auth_type_name );
        if( m_user_password.is_defined() )
          disabled_tag_defined( m_user_password, auth_type_name );
      }
    ... // Дальнейшие проверки.
  }

Уже лучше, но писать вызовы is_defined() и disabled_tag_defined() мне быстро надоело.  Во-первых, проверку наличия значения у тега можно переместить во вспомогательные функции. Во-вторых, зачем постоянно передавать имя режима аутентификации, если это можно сделать один раз? Стало получаться что-то вроде:

/* Вариант III */
class presence_checker_t
  {
  private :
    const std::string & m_auth_mode_name;
  public :
    presence_checker_t( const std::string & auth_mode_name )
      : m_auth_mode_name( auth_mode_name )
      {}
    void
    check_mandatory_tag( const ... & tag ) const
      { ... /* Проверка значения и порождение исключения. */ }
    void
    check_disabled_tag( const ... & tag ) const
      { ... /* Проверка значения и порождение исключения. */ }
  };

void
tag_auth_cfg_t::on_finish( const cls_3::parser_context_info_t & context )
  {
    base_type_t::on_finish( context );

    const std::string & auth_type_name = base_type_t::query_value();
    auth_cfg_t::auth_type_t auth_type = get_auth_type( auth_type_name );
    presence_checker_t checker( auth_type_name );

    // В режимах http_basic и http_and_ssl_server имя пользователя
    // и пароль обязательно должны быть определены. А в режиме
    // ssl_client_server -- не должны.
    if( autg_cfg_t::auth_ssl_client_server_check != auth_type )
      {
        checker.check_mandatory_tag( m_user_name );
        checker.check_mandatory_tag( m_user_password );
      }
    else
      {
        checker.check_disabled_tag( m_user_name );
        checker.check_disabled_tag( m_user_password );
      }

    // В режиме http_basic должны быть определены только два тега.
    if( auth_cfg_t::auth_http_only == auth_type )
      {
        checker.check_disabled_tag( m_ca_file );
        checker.check_disabled_tag( m_client_cert_and_key_file );
        checker.check_disabled_tag( m_client_private_key_password );
      }
    else
      {
        // В оставшихся режимах тег {ca_file} всегда должен быть определен.
        checker.check_mandatory_tag( m_ca_file );

        // Оставшиеся два тега должны быть определены только в
        // одном случае.
        if( auth_cfg_t::auth_ssl_client_server_check == auth_type )
          {
            checker.check_mandatory_tag( m_client_cert_and_key_file );
            checker.check_mandatory_tag( m_client_private_key_password );
          }
        else
          {
            checker.check_disabled_tag( m_client_cert_and_key_file );
            checker.check_disabled_tag( m_client_private_key_password );
          }
      }
  }

Этот вариант уже гораздо лучше. Хотя бы потому, что он позволяет обозреть весь метод on_finish – код понятен и легко проверяется.

Но все равно я вошел во вкус – мне казалось, что можно сделать еще короче:

/* Вариант IV */
class presence_checker_t
  {
  private :
    const std::string & m_auth_mode_name;
  public :
    presence_checker_t( const std::string & auth_mode_name )
      : m_auth_mode_name( auth_mode_name )
      {}
    void
    check( const ... & tag, bool is_mandatory )
      {
        // Если is_mandatory == true, то требует, чтобы тег
        // имел значение. Если is_mandatory == false, то тег
        // не должен иметь значения.
        ...
      }
  };

void
tag_auth_cfg_t::on_finish( const cls_3::parser_context_info_t & context )
  {
    base_type_t::on_finish( context );

    const std::string & auth_type_name = base_type_t::query_value();
    auth_cfg_t::auth_type_t auth_type = get_auth_type( auth_type_name );
    presence_checker_t checker( auth_type_name );

    // В режимах http_basic и http_and_ssl_server имя пользователя
    // и пароль обязательно должны быть определены. А в режиме
    // ssl_client_server -- не должны.
    const bool is_user_name_and_password_mandatory =
      (auth_cfg_t::auth_ssl_client_server_check != auth_type);
    checker.check( m_user_name, is_user_name_and_password_mandatory );
    checker.check( m_user_password, is_user_name_and_password_mandatory );

    // При работе по SSL тег {ca_file} обязательно должен быть задан.
    const bool is_ca_mandatory = (auth_cfg_t::auth_http_only != auth_type);
    // Параметры клиента должны быть определены только в режиме
    // ssl_client_server.
    const bool is_client_cert_mandatory =
      auth_cfg_t::auth_ssl_client_server_check == auth_type;

    checker.check( m_ca_file, is_ca_mandatory );
    checker.check( m_client_cert_and_key_file, is_client_cert_mandatory );
    checker.check( m_client_private_key_password, is_client_cert_mandatory );
  }

Вот этот вариант у меня и остался. Поскольку он намного компактнее всех предыдущих. Хотя и воспринимается чуть сложнее, чем предыдущий. Что не есть хорошо. Но дальше думать уже лень ;) Хотя я не сомневаюсь, что можно сделать еще проще.

PS. Кстати о количестве строк, производимых программистом. Вариант IV оказался самым компактным (всего на несколько строк короче варианта III и значительно короче варианта II). Вариант I я вообще не дописал, т.к. его размер превосходил все допустимые размеры. Однако, времени на написание окончательного варианта потребовалось раза в три больше, чем на работу над двумя первыми вариантами (грубо говоря: вариант II у меня получился через 20 минут после начала работы, а вариант IV – через час после начала). Что подтверждает мое старое наблюдение – чем спокойнее и неторопливее ход работы, тем меньше по объему получается код. Как следствие – чем спокойнее программист работает, тем меньше строк он пишет. Так что, смею предположить, у хороших программистов производительность в килостроках вообще никакая ;)

четверг, 26 ноября 2009 г.

[comp.prog.flame] Для меня XML, как для некоторых C++ ;)

Вдогонку к моему вчерашнему выплеску ненависти к XML.

Долго думал над комментарием ув.тов.Зверька. Пришел к выводу, что это у меня такое же субъективное неприятие XML, как у многих программистов неприятие C++ ;)

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

Правда же, все вышесказанное отлично подходит под C++? ;) Хотя я об XML. А мог бы и о Java ;)

PS. А все-таки мне бы для работы с XML данными в С++ хотелось бы иметь простой, легкий в освоении и бесплатный инструмент, который бы позволял писать как-то так:

/*
 * Разбор XML-сообщений вида:
 *
 * <message>
 *   <report>
 *     <status date="...">OK</status>
 *   </report>
 * </message>
 *
 * или
 *
 * <message>
 *   <report>
 *     <status errorCode="..." description="...">...</status>
 *   </report>
 * </message>
 */
AutoPtr< Document > doc = parse_document_from_stream( message_stream );
element_proxy_t status =
  root( *doc, EL_MESSAGE )
    .single_mandatory_element( EL_REPORT )
    .single_mandatory_element( EL_STATUS );
if( EL_STATUS_OK == status.text() )
  handle_success( status.mandatory_attribute( EL_ATTR_DATE ) );
else
  handle_failure(
    status.text(),
    status.mandatory_attribute< int >( EL_ATTR_ERROR_CODE ),
    status.mandatory_attribute( EL_ATTR_ERROR_DESCRIPTION ) );

PPS. У меня есть маленькая просьба. Я знаю, что мой блог читают и не C++ программисты. Обращаюсь к ним: поделитесь, плз, ссылочками на хорошие описания разных способов работы с XML в других статически-типизированных языках (C#, Java, OCaml или F#). Какие-нибудь статьи, чтобы прочитать и просто составить мнение о том, что в мире делается. Чтобы узнать, до чего, так сказать, передовая мысль дошла ;)

среда, 25 ноября 2009 г.

[comp.prog.3.1415…] Крик души: как же я ненавижу XML!!!

Это просто не передать словами… Когда приходится писать код вида:

std::string get_service_name( const Document & document )
  {
    AutoPtr< NodeList > services = document.getElementsByTagName( "service" );
    if( 1 != services->length() )
      throw ...;
    Node * first = services->item( 0 )->firstChild();
    if( !first )
      throw ...;
    if( Node::TEXT_NODE != first->nodeType() )
      throw ...;
    return first->nodeValue();
  }

я испытываю если не рвотные позывы, то что-то очень близкое к ним.

Хочется попробовать в деле что-то вроде Code Synthesis’s C++/Tree, да нет времени, трясти нужно. Если у кого-то есть опыт работы с данным продуктом, поделитесь, пожалуйста, впечатлениями – как оно? Еще интересно, сколько стоит коммерческая лицензия, а то они на сайте цену не указывают.

[life] Байка про неудавшуюся пересадку сердца, кому и сознание

Вчера по НТВ показали репортаж про бельгийца Рома Хубена, который провел 23 года парализованным, но в сознании. Тогда как врачи считали, что он в коме.

Вспомнилась байка, рассказанная Андреем Ломачинским в книге “Курьезы военной медицины и экспертизы” (глава “Донор сердца”):

   Генерал: «Да, именно преднамеренно убить, но не просто, а крайне изысканно – в лучших традициях центрально-американских индейцев, всяких там Майя или Ацтеков».
   Я думаю – дед гонит, хотя виду не показываю: «А-аа… А как это?».
   Генерал: «Да должен был я у него вырезать бьющееся сердце».
   Генерал поставил чайник и неспешно стал рассказывать:
   «Цветы эти для его второй мамки в честь его второго Дня Рождения. О чём речь сейчас поймешь.
   Было это по моим понятиям – недавно, по твоим – давно. И был шанс у Академии стать вторым местом в мире (а может и первым!), где была бы осуществлена трансплантация сердца. Это сейчас все привыкли смотреть на западные достижения, как на икону. Тогда же мы им дышали в затылок, и уж что-что, а Южная Африка для нас авторитетом не являлась. Главную роль играл не я, а академик Колесов с Госпитальной (*Прим. – фамилия может была Колесников, сейчас точно не помню). Они там к тому времени уже тонну свиных сердец пошинковали, да и на собаках кое-что отработанно было. Что думаешь, экстракорпоралка у нас слабая была? Что без забугорных оксигенаторов не прошло бы? Да мы тогда уже над пузырьковой оксигенацией смеялись, работали с «Медполимером», разработали хорошие насосы и мембраны– гемолиз во внешних контурах был весьма приемлимым. Да, была наша оксигенация в основном малопоточной – ну а делов то двадцать литров дополнительной крови в машину залить! Всё равно больше выбрасываем. А какие наработки по гистосовместимости! Да нам неофициально вся Ржевка помогала – я имею в виду Институт Экспериментальной Военной Медицины, они же там со своими «химерами» —ну облучённые с чужим костным мозгом все реакции отторжения нам смоделировали! А про оперативную технику я вообще молчу.
   Короче всё готово. Но, но очень большое «но» остаётся. Через Минздрав такое провести было невозможно, даже через их 4-е Главное Управление. И досада, кроме политической, вторая главная препона – юридическая. Ну вопрос, когда человека мёртвым считать. Сердце бьётся – значит жив, а когда сердце мертво – так на что нам такое сердце! Подбил Колесов меня с ним на денёк в Москву съездить, на приватный разговор к начмеду в Министерство Обороны. Пальма первенства уже утеряна – «супостаты» «мотор» пересадили. Речь идёт по сути о повторении достигнутого. А ведь в СССР как, раз не первый – значит и не надо. Что с Луной, что с сердцем. Ну в Управлении и резко рубить не охота, и напрасно рисковать не желают. Ситуация – ни да, ни нет. Хлопцы, разок попробуйте, но из тени не выходите, мы тут наверху за вас не отвечаем. Получится – к орденам и звёздам, нет – к неприятностям.
   Ну и придумали мы бюрократическую процедуру, которая помогала эти ловушки обойти. Несколько потенциальных реципиентов подобрала Госпиталка, всех протестировали. Дело ВПХ за малым – добыть донора. Мы даже придумали как нам через Боткинскую с ним «прыгать». Кому донорское сердце больше подойдёт – тому и пересадят. Так вот, был у нас документ с печатью ЦВМУ, Медуправления Министерства Обороны, за подписями Начмеда и Главного Хирурга. Было в том документе упомянуто 11 фамилий на 12 пунктов под подпись– десять военных, ну кто к «донорству» будет приговаривать, одна – пустой бланк (это на согласие от ближайшего родственника «покойника»), и последняя, самая малозначительная подпись вообще считай лаборанта – подтвердить оптимальную совместимость донор-реципиент при «переводе» в Госпиталку! Ну не совсем, конечно, лаборанта – я специально пробил должность в лаборатории клиники – ну там иммунология-биохмия; сразу взял туда молоденькую девочку сразу после университета. Нет хоть одной подписи – и «донор» автоматически остаётся в нашей реанимации до самого «перевода» в Патанатомию.
   По понятным причинам намерение держим в тайне и ждём «донора». Через пару недель происходит «подходящий» несчастный случай. Считай рядом с Академией, сразу за Финбаном, пацан 17 лет на мотоцикле влетает головой в трамвай – прямо в ту гулю, что для вагонной сцепки. Скорая под боком – пострадавший наш, профильный, доставлен в момент. Прав нет, но в кармане паспорт. Ну я как его увидел – категория уже даже не агонирующих, а отагонировавшихся. Травма несовместимая с жизнью. Но на ЭКГ все ещё работающее сердце! Голову кое-как сложили, с кровотечением справились и быстро на энцефалограмму. Там прямые линии – красота мёртвого мозга. Говорю сотрудникам – боремся с возможной инфекцией – в башке то точно некрозы пойдут! Ну нельзя же сделать хирургическую обработку травмы мозга в виде ампутации полушарий под ствол – а там всё побито! Ну и конечно реанимационное сопровождение и интенсивная терапия по максимуму – тело сохранять живым любой ценой, пока мы наш «адский документ» не подпишем.
   Первым делом согласие родственников – без него всё дальнейшее бессмысленно. Одеваюсь в форму, беру для контраста с собой молодого офицера и пожилую женщину – что бы легче было уболтать любого, кто окажется этим ближним родственником. Мчимся по адресу в паспорте куда-то на Лиговку. Заходим. Комната в коммуналке – на полу грязь страшная, на стенах засохшая рвота, вонь вызывает головокружение, из мебели практически ничего, похоже живут там на ящиках. Оказывается, что существует только один ближайший, он же и единственный родственник – его мать. Человеком её уже было назвать сложно – полностью спившееся, морально деградировавшее существо. Такого я ещё не видел – её главный вопрос был, а можно ли НЕ забирать тело, чтоб не возиться с похоронами. К сыну похоже она вообще не испытывала никаких положительных эмоций, а истерика и вопли моментально сменились откровенными намёками, что по этому поводу надо срочно выпить. Я послал офицера купить ей три бутылки водки. Документ она подписала сразу, как услышала слово водка! Получив подпись мы пулей вылетели из той клоаки с брезгливым осадком.
   Но ещё более интересную новость я узнал чуть позже, когда в клинику прибыл тот офицер, что был послан за спиртным для «ближайшего родственника». Он столкнулся с другими обитателями той коммуналки и узнал некоторые подробности о самом «доноре» – крайне асоциальный тип, хулиган, исключался за неуспеваемость из школы и ПТУ, хоть и молод – сильно пьет, страшно избивает свою мать! Короче, что называется – яблоко от яблони… А ещё через десять минут, как по звонку Свыше, в клинику пришёл следователь и принёс ещё более увлекательную информацию – мотоцикл «донора» краденный, точнее отобранный в результате хулиганского нападения, а сам «донор» и без этого уже под следствием не то за хулиганство, толи за ограбление. Похоже единственное хорошее дело «донору» за всю его жизнь ещё только предстоит – и это отдать своё сердце другому.
   Быстро все обзваниваются – собираем «заключительный» консилиум – бумаги под «приговор» подписывать. Все ставят подписи – сомнений ни у кого нет. Только одну подпись не можем пока поставить – анализы не готовы, времени не достаточно их завершить. В Госпитальной Хирургии идёт подготовка, ответственой за лабораторию велено сидеть на работе, пока результатов не будет. Ну вот наконец и это готово – иди, ставь свою последнюю подпись! Ну а тётка и говорит, мол по документу на момент подписания я обязана совершить осмотр! Тю, ты ж дура, думаю. А десяток академиков-профессоров, совершивших осмотр и разбор полдня назад, тебе не авторитет!? Ну вслух ничего такого не говорю, пожалуйста, идите. Смотрите себе тело под аппаратом, только не долго.
   Она и вправду недолго. Пошла, взяла ЭЭГ, а мы ему энцефалограммы чуть ли не непрерывно гнали – ну как не было, так и нет там ничего. Мозг – аут! Стетоскоп достала – вот умора, да её в клинике вообще со стетоскопом не видели. На что он ей вообще? И что она там выслушивать будет – «утопил» ли дежурный реаниматолог его или пока нет. Да мне уже всё равно – счёт пожалуй на часы идёт. Что-то она там потрогала, что-то послушала, толком ничего не исследовала – курсант после Санитарной Практики лучше справится. А потом поворачивается ко мне и так это тихо-тихо, но абсолютно уверенно говорит:
   – Он живой. Не подпишу я…
   Девочка, ты деточка!!! Да ты хоть представляешь какие силы уже задействованы? Отдаёшь ли ты себе отчёт, что ты тут человек случайный – почти посторонний? А понимаешь ли ты, что городишь ты нам полную чушь – кровь в пластиковом контейнере тоже живая, а вот человек – мёртвый. Тело есть, а человека в нём нету! Короче ругали мы её, просили, убеждали, угрожали увольнением. Нет, и всё. И ведь сама по себе не упрямая, а тут ни за что не соглашается. Мол если я ноль – то и делайте без моей подписи. Сделали бы, да не можем мы без твоей подписи.
   На утро собрались все главные действующие лица. «Донор» терпит? Да пока терпит – ни отёка легких, ни инфекции, кое-какая моча выделяется. Стараемся, ведём этот «спинно-мозговой препарат» как можем. А может потерпеть, если Колесов в Москву слетает и переутвердит новый документ? Не знаю, надежды мало. Короче день мы решали лететь или не лететь. Потом полетели. Что-то сразу не заладилось. А там выходные. Восемь дней волокита заняла. А «донор» терпит! Горжусь – во мужики у меня в клинике – мертвеца столько ведут.
   Наконец назначен новый консилиум с «вердиктом». Только не состоялся он – ночью на ЭЭГ кое-какие признаки глубокого ритма появились. Всё – дальше по любому не мертвец, а человек. Зови спецов с Нейрохирургии – пусть погадают. Много они не нагадали – ведите как сможете, прогноз неблагоприятный. О том, что это был кандидат в доноры сердца – табу даже думать. Обеспечиваем секретность, как можем.
 
   Долго он был в нашей реанимации. Сознания нет (а я тогда был уверен, что и не будет), но мозг ритмы восстанавливает. Попробовали отключить ИВЛ. Дышать пытается! Дальше – больше. Перевели в Нейрохирургию. Там ему много чего сделали, но ничего радикального – всё как у нас, что природа сделает, то и прогресс. Говорить пытается, шевелится. Уже порядком восстановившись из Нейрохирургии он попал в Психиатрию. Наверное для учебного процесса психо-органический синдром демонстрировать. А там вроде вот что было – перечитал все книжки, и всем надоел. Ну кто-то и подшутил – сунул ему вузовский учебник по высшей математике. А ещё через полгода комиссия и первая (!) группа инвалидности. А ещё через полгода ещё комиссия – пацана в ВУЗ не берут! Молит-просит – дайте вторую. Что он закончил, я не точно не знаю, по слухам Московский Физтех. Пять лет за два года. Если это не легенда – то на экзамены ходил так – один экзамен в день. Сегодня сдаю ну там математику за первый семестр, завтра сопромат за пятый, послезавтра ещё что-то за девятый. Заходил на любой экзамен вне зависимости от курса. А к концу второго года что-то такое придумал – короче моментально целевое распределение в какой-то сверхсекретный «почтовый ящик». Ну а финал ты сам сегодня видел.
   Колесов год ходил грознее тучи – полностью подробностей не знаю, но похоже кое-что просочилось на самый верх в ЦВМУ и выше в МО. Вроде сам Гречко об этом знал – может как байку в бане кто ему рассказал, а может в сводке прошло, типа вон в ВМА пытались сердце пересадить, да ничего не вышло. Видимо посчитали там наш подход к решению проблемы авантюрным, направление быстренько прикрыли.
   Особисты и люди из ГлавПура нас самого начала предупреждали – какая-либо информация только в случае полного успеха. Боялись видно, что вражьи голоса злорадно запоют – в Советском Союзе провалилась попытка пересадки сердца, а вот у нас в Мире Капитала с пересадками всё ОКэй, как зуб вырвать. Нам последствий никаких – пострадавших то в этой истории нет, да и вообще полная картина известна единицам и с каждым годом этих «единиц» меньше и меньше становится… Люди подписавшие этот конфузный документ молчат, а сам документ мы уничтожили – всё равно он силы без той подписи не имел, что макулатурой архивы забивать? Всё вроде тихо-спокойно… Забывается потихоньку. Но одна тайна всё же мне покоя не даёт. Невозможно это, ну абсолютно исключено и совершенно не научно. Но факт.
   Знаешь, никто ему не мог сказать, что он «донором» был. Мы с Колесовым все варианты перебрали. Некому было рассказать. А он знает! Притом знает всё с самого начала. Даже как под ИВЛ трупом лежал.»
   Я: «Ну вы же сами говорили – учёный не простой, ну там КГБ вокруг всякое. Ну они же ему и сказали…»
   Генерал: «Глупости! Не получается так.»
   Я: «Ну а тётка эта?»
   Генерал: «Нет, нет и нет! Парадокс, что он её вообще знает. А ещё больший парадокс, что всю дальнейшую историю после того дня она знает только со слов самого «донора»! Я от неё избавился сразу после отказа подписаться. Два года спустя разыскал её – меня сильно совесть мучила. Предложил вернуться в Клинику, посоветовал хорошую тему для диссертации. Она никогда не интересовалась судьбой «донора» – история в её изложении была очень простой – «донор» умер, тему закрыли, генералов надо слушаться. Так она и считала, пока «донор» уже в теперешнем виде не явился к ней ровно в тот же день, как она сказала, что он живой. И знает «донор» только то, о чём говорилось в его палате. А значить это может только одно. Когда у него на энцефалограмме прямые линии ползли – ОН ВСЁ СЛЫШАЛ! Слышал и помнил…»

PS. Данный пост можно считать неприкрытой рекламой книг Андрея Ломачинского. Как по мне, так его “Криминальные аборты” нужно заставлять штудировать всех достигающих половой зрелости подростков. Чтобы жили.

вторник, 24 ноября 2009 г.

[comp.prog.c++] Вышла новая версия POCO – 1.3.6

Через полгода после версии 1.3.5 появилась следующая версия POCO – 1.3.6. В основном, это bug-fix релиз, с некоторыми дополнениями и улучшениями. Подробный список изменений можно посмотреть в CHANGELOG-е.

Отсюда можно скачать новую версию: http://pocoproject.org/download/ (tar.bz2 полной версии занимает всего 2.3Mb).

PS. Потихоньку используем у себя POCO 1.3.4 и 1.3.5. Впечатление такое, что если нужно что-то сделать по быстрому и непритязательно, то POCO как раз самое оно. Но если захочется большего контроля за происходящим, тогда… Ну и плюс, как недавно выяснилось, класс SharedPtr у них своеобразно спроектирован :(

[comp.prog.wow] 1K строк на C в день?!!!

Случайно найдено здесь:

lionet: Более того, на C у меня в опен сорсе больше программ (ipcad, asn1c), чем на FP. И писал я на нём десятки и сотни тысяч строк в год. Этот опыт не отменяет того, что на FP, в случае, когда я его выбираю, я более продуктивен.

ormuz: 1000 строк в день, каждый рабочий день, в течении года? Это ж два ~ апача (на глаз) в год написать можно.

lionet: Да, так то и был типа такой апач. Продали за 188 миллионов долларов фирме Akamai. И не 1000 строк в день, а 1500-2000, раз в два дня.

lionet – это Лев Валкин, разработчик asn1c и ipcad (подробнее о его проектах можно прочитать на его странице). Собственно, человек, который много сделал и в этом можно легко убедиться.

Но вот производительность в 1K C-шных строк в день – это для меня что-то запредельное. Не могу я себе представить, как можно на постоянной основе раз в два дня выдавать на гора по 1500-2000 строк отлаженного, задокументированного кода. Пусть и C-шного.

Кто-нибудь сталкивался в реальной жизни с такой производительностью? Или, если кто-нибудь располагает подробностями того проекта – было бы интересно почитать (хотя бы о том, что именно Akamai купила – софт или программно-аппаратный комплекс).

[comp.prog.flame] Chromium OS и чистА функциональные языки

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

А тут Google продвигает платформу, которая выведет Web-программирование на совершенно другой уровень. Где главную роль, по крайней мере на первом этапе, будет играть JavaScript. Динамически язык с прототипами вместо классов и интерфейсов, хотя и с функциями в качестве первоклассных сущностей и замыканиями.

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

В общем, победа функционального программирования становится все более очевидной и безоговорочной ;)

PS. Данный текст можно воспринимать как шутку, в которой есть только доля шутки ;)

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

[comp.prog.thoughts] Нетбуки под Chromium OS точно не вернут старые добрые времена

Прочитал новость про открытие исходников Chromium OS. Последовательность старта в виде “прошивка –> ядро ОС –> Web-браузер”, что называется, внушаить. Получается, что под Chromium OS будет работать только нативный Web-браузер. Все остальное (почта, игры, мультимедиа и пр.) – все это будут Web-приложения, которые способны работать в офлайне. Обещается, что работать Web-приложения будут шустрее, чем в обычных “универсальных” браузерах, за счет тесной интеграции Web-браузера из Chromium OS с ядром.

Похоже, мы наблюдаем ускорение развития нишевости в области персональных компьютеров. Времена, когда одна и та же машина могла использоваться для разработки ПО, работы в MS Office, запуска “малолитражных” САПР, разнообразных компьютерных игр, хождения по Интернету и т.д., уходят в прошлое. Игровые компьютеры, сервера, рабочие станции, офисные компьютеры – таковым было деление еще недавно. Потом появились игровые приставки. Теперь вот нетбуки могут трансформироваться в этакие “приставки для Web-а”.

Наверное, это правильно. Большое количество современных пользователей нуждается всего лишь в простом и дешевом инструменте для чтения новостей, пребывания в социальных сетях, обмена фотографиями “Вот я, а вот моя собака”, общения через Skype. Все это можно делать и с помощью “зашитого в BIOS” браузера в купе с набором написанных на JavaScript Web-приложений…

Неприятный осадок от этой новости у меня остается по двум причинам.

Во-первых, как-то грустно осознавать, что специализация программистов все более и более усиливается. Все-таки, когда во время учебы перед глазами были примеры программистов-универсалов, которые и драйвера для real-time OS делали, и бухгалтерский софт писали, и ГИС-системы разрабатывали, было впечатление, что и ты так сможешь. Сейчас понимаешь, что вряд ли. В силу слишком большого порога вхождения в новую прикладную область.

Во-вторых, не покидает меня ощущение легкого маразма. Развитие событий похоже на то, что было при развитии Web-программирования. Ну не был предназначен HTTP+HTML для динамических страничек. Однако, нужно было. Поэтому вместо разработки альтернативы HTTP+HTML пошли на внедрение в него JavaScript (VBScript, ActionScript и пр.) Сейчас нужно создать минималистичное и безопасное окружение для нетбуков. Вместо создания (адаптации) специализированного безопасного языка и API (вроде экспериментов типа Singularity OS) идут по запихиванию в новую нишу уже имеющихся и, на мой взгляд, не предназначенных для этого технологий. Все-таки написанный на JavaScript файловый менеджер, работающий внутри Web-браузера – это как попытка отослать почту из Москвы в Санкт-Петербург через Камчатку.

Так что возвращения к старым добрым временам пока не предвидится. Зато происходящее мне напоминает чудный афоризм про устранение любой проблемы дизайна путем добавления еще одного слоя абстракции. Chromium OS этот слой добавляет. Что будет дальше?

PS. Еще ссылка по теме: Скриншоты Google Chrome OS на RusDoc.ru.

[life] Две суровые фразы Стива Джобса

Позволю себе выдернуть их из подборки в блоге Qoshni:

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

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

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

воскресенье, 22 ноября 2009 г.

[comp.prog.d] Слайды презентации Metaprogramming in D: Real world examples

В ноябре на очередном заседании NorthWest C++ User Group Билл Бакстер сделал одноименный доклад. Доступный слайды этого доклада в формате PowerPoint.

Посмотреть интересно. Не то, чтобы мне нравился подход языка D, но сейчас он точно мощнее C++ного.

Так же в презентации упоминается демонстрационный проект ctrace – рейтрейсер на языке D, который работает в compile-time. Не понятно зачем эта штука нужна, но прикольно :)

PS. Для ветеранов RSDN-овский войн “Nemerle круче всех” будет забавно увидеть в презентации пару сравнений D и Nemerle :)

[comp.prog] Из gems.rubyforge.org в gemcutter.org

Получил сегодня письмо от RubyForge. В нем говорится, что теперь gems.rubyforge.org (раньше это был каталог доступных RubyGem-ов) указывает на gemcutter.org. И что теперь ведется только один индекс Gem-ов – на gemcutter.org. Поэтому, для публикации своего Gem-а сейчас нужно не только сделать релиз Gem-а на RubyForge, но и выполнить команду gem push для того, чтобы внести свой Gem в индекс gemcutter-а.

Имхо, это пример того, что новое не есть лучшее. Раньше было достаточно только сделать релиз своего нового Gem-а на RubyForge, и он автоматически добавлялся в каталог. Да еще сейчас gemcutter.org показывает статистику загрузки только с июля 2009. Зато делает это гламурненько так :)

[life.photo] Гламур и трущобы

Рекламный бигбоард в Лиме, Перу.

Сюрреалистично. Тем не менее, имеет место быть :)

Найдено в очередном выпуске WSJ’s Picture of the Week.