вторник, 19 января 2010 г.

[comp.prog.flame] Упрощения в презентациях – повторение пути шаттла Коламбия?

После катастрофы шаттла Коламбия в 2003-м мне попалась на глаза статейка, в которой одной из причин называлось широкое использование Microsoft PowerPoint в NASA. Т.е. виноват, конечно, не сам PowerPoint, а использование презентаций в качестве основной формы докладов подразделений и руководству NASA. Презентации, якобы, не позволяли углубляться в детали, а дают только поверхностную картинку. Т.е. подчиненные подсовывали своему начальству красочные презентации, которые начальство хотело видеть. Что и привело с системным проблемам в обеспечении безопасности полетов шаттлов.

Версия, конечно, бредовая. Но негативная роль презентаций, показывающих только “светлую” сторону, определенно есть. Взять, например, презентацию Дона Сайма “Why is Microsoft investing in Functional Programming?”, а в ней картинку на странице 38:

Действительно ли показанный желтым фрагмент на F# является эквивалентом трех страниц на C#?

Как по мне – так нет. Они не эквиваленты ни по выполняемым операциям, ни по объему комментариев в коде, ни по подробности обработки ошибок.

Зато как убедительно преимущество F# выглядит в презентации! ;)

Еще один пример, на этот раз из обсуждавшейся уже здесь статьи “Элементы функциональных языков”. Фрагмент кода из раздела “10. Сопоставление с образцом”, демонстрирующий работу с POP3 сервером:

sendCommand (POP3C conn _) (RETR msg) =
     bsPutCrLf conn (BS.pack ("RETR " ++ show msg))
        >> responseML conn
   sendCommand (POP3C conn _) (TOP msg n) =
     bsPutCrLf conn (BS.pack ("TOP " ++ show msg
                              ++ " " ++ show n))
        >> responseML conn
   sendCommand (POP3C conn _) (AUTH LOGIN user pass) =
     do bsPutCrLf conn (BS.pack "AUTH LOGIN")
        bsGetLine conn
        bsPutCrLf conn (BS.pack userB64)
        bsGetLine conn
        bsPutCrLf conn (BS.pack passB64)
        response conn
     where (userB64, passB64) = A.login user pass

Красиво? А вот пример работы с POP3 сервером из библиотеки POCO:

void POP3ClientSession::login(const std::string& username, const std::string& password)
{
   std::string response;
   _socket.receiveMessage(response);
   if (!isPositive(response)) throw SMTPException("The POP3 service is unavailable", response);
   sendCommand("USER", username, response);
   if (!isPositive(response)) throw POP3Exception("Login rejected for user", response);
   sendCommand("PASS", password, response);
   if (!isPositive(response)) throw POP3Exception("Password rejected for user", response);
}

Ведь тоже красиво, не так ли? Просто, лаконично, функционально. Лепота.

Одна проблема с кодом в POCO – нихрена тайм-ауты он не считает. Поэтому, если по какой-то причине соединение с POP3 сервером “залипнет” (т.е. из него ничего не будет читаться, но и сигнала о потере не будет), то приложение на вызове POP3ClientSession::login() уснет навсегда.

А если добавить в приведенные выше фрагменты более суровую (т.е. требующуюся на практике) обработку ошибок и тайм-аутов, куда исчезнет эта красота?

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

7 комментариев:

Skynin комментирует...

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

А когда пишешь на ФЯ - такого не бывает. Это у нас, императивщиков то с таймаутами что-то не так, то сокет "залипftn" аки USRobotics.

На ФЯ - все чистенько, все работает...

eao197 комментирует...

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

Rustam комментирует...

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

eao197 комментирует...

>в целом код на функциональщине получается и короче и выразительней.

Ну, zip-ованный текст в 3-4 раза компактнее обычного, только вот без специальных инструментов не читается :)

В существующей функциональщине степень краткости, имхо, перешла грань разумного. Синтаксис OCaml-а и Haskell-я для большинства нынешних мейнстримщиков хуже китайских иероглифов. Идеи ФП (лямбды, иммутабельность и паттерн-матчинг в первую очередь) проникают и продолжат проникать в мейнстрим (через Java, C#, C++, в меньшей степени через Scala и F#). Что хорошо.

Но хардкорный ФП вроде:

f a b C d E = n d \x :- d :/ g k ^ m >>=%^% W

лучше держать от обычных людей подальше :)

Rustam комментирует...

zip-ованный текст длиннее чем программа на J или K :)
Так что если гнаться только за краткостью это не к ФП - а к APL based. И до грани разумного тем же OCaml и хаскелю очень далеко :)

Ну и хардкорный C++ по закорючкам и криптостойкости может и фору дать ФП :)

eao197 комментирует...

>И до грани разумного тем же OCaml и хаскелю очень далеко :)

Как в анекдоте -- "да-а-а, Тал-л-л-ин теперь уже дал-л-лек-о-о" :)

>Ну и хардкорный C++ по закорючкам и криптостойкости может и фору дать ФП :)

Это точно. Была бы ему адекватная замена... А то сейчас D, мне кажется, по количеству закорючек C++ превзойдет. Что там в последних релизах добавилось? auto и auto ref-функции, вроде бы :) Столько всего уже нужно в D знать, OCaml по сравнению с ним выглядит каким-то оборванцем :)

Rustam комментирует...

Да D все матереет и матереет, похоже скоро (не пройдет и пяти лет) хаскель и окамл будут его подмножествами :)