суббота, 24 сентября 2011 г.

[life.photo] Был в лесу, фотографировал костер

Люблю смотреть на огонь. В детстве мог часами наблюдать за пламенем свечи или за огнем в печке. Сейчас на это уже нет времени, но игра пламени все равно действует на меня завораживающе.

Сегодня семьей совершили вылазку в лес, на барбекю. Сделал несколько снимков костра. Под катом небольшое слайдшоу (а вот ссылка на альбом).

[life.rest.photo] Фотографии живности из отпуска

Под катом несколько фотографий разных зверюшек, которые попали мне в кадр.

пятница, 23 сентября 2011 г.

[prog.flame] Каким же образом знание разных языков делает программиста лучше?

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

Для того, чтобы продолжать дальше нужно определиться, кто такой “хороший программист” и что означает “быть лучше”. Имхо, начинать нужно с того, что бы определить понятие “хорошая программа”. Хорошая программа – это программа, которая:

  • делает то, что от нее требуется;
  • разработка которой укладывается в приемлемый бюджет;
  • содержит допустимое количество ошибок и недоделок;
  • ее сопровождение и развитие обходится не слишком дорого.

Соответственно, хороший программист – это такой, который умеет делать хорошие программы. А из чего это умение складывается?

Я бы поставил на первые места следующие составляющие:

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

2. Умением выбирать простые и удобные проектные решения.

3. Умение писать простой и понятный код.

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

4. Умение связно и понятно излагать собственные мысли. Как в устной речи, так и (особенно) в письменном виде. Просто удивительно иногда, насколько тяжело бывает понять написанное умным человеком – вроде бы и правильно все, но чтобы разобраться нужно поломать голову. Из-за банальной причины – пишущий не может поставить себя на место читателя.

5. Умение поддерживать нормальные человеческие отношения с коллегами. Неприятно об этом говорить, но заносчивость, зазнайство, поведение в стиле “я-то знаю, а вы сами должны до всего додуматься”, скрытность (“как я реализую этот модуль – это моя проблема, никого больше это не касается”), некоммуникабельность, обидчивость и пр. встречаются. К счастью, не часто.

Так вот, я не понимаю, каким образом знание нескольких десятков языков способны развить вышеуказанные умения. Хотя бы первые три.

По первому умению. Тут языки программирования вообще не причем. Здравый смысл + опыт. Еще лучше, когда у человека есть врожденная способность разбираться в предмете досконально. А так же умение “примерить чужую шкуру” – поставить себя на место заказчика чтобы уяснить, зачем нужна какая-то фича программы.

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

В данном случае я могу увидеть возможный способ влияния новых языков. Например, знакомство с функциональными языками вынуждает знакомиться с такими вещами, как иммутабельные структуры данных и ленивые вычисления. С которыми обычный программист может быть и не знаком. Если, конечно, ранее ему не приходилось заниматься задачами по параллельной обработке данных.

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

По третьему умению. Во-первых, простой и понятный код – это, во многом, следствие опыта, чувства стиля и вкуса. Во-вторых, это следствие хорошего знания языка и, что чрезвычайно важно, знание best и worst practicies для этого языка.

И вот здесь я склонен считать, что знание разных языков программирования вовсе не способствует упрощению кода. А может даже и наоборот. Поскольку на каждом языке нужно писать именно так, как принято писать на этом языке. Можно на Ruby писать как на Java. Но лучше все-таки использовать Ruby way. И в Java не стоит тащить привычки из C++. А чтобы этого не происходило, требуется a) хорошее знание языка (которое приобретается за счет длительного опыта, набивания шишек и их переосмысления) и b) отсутствие жгучего желания воплотить в X вот эту классную фишку из Y. И я, честно говоря, не понимаю, как знание многих языков программирования помогает пунктам a) и b).

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

PS. Кстати говоря, я придерживаюсь мнения, что здесь имеет место путаница. Не изучение языков делает программистов хорошими. Это хорошие программисты зачастую имею желание изучать разные языки. Так что здесь скорее причина и следствие перепутаны ;)

четверг, 22 сентября 2011 г.

[life.photo.wow] Это ж сколько времени у него погрузка заняла?

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

Снимок найден в очередном выпуске WSJ’s Photos of the Day.

среда, 21 сентября 2011 г.

[prog] Презентация Мартина Одерски State of Scala с конференции Scala Days 2011

PDF-ка на 42 страницы. (Ссылка найдена здесь, но там висит предупреждение, что в будущем URL может измениться. Пока же там можно найти ссылки на статьи, слайды и видео других докладов).

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

После просмотра презентации осталось несколько впечатлений.

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

def encode(number: String): Set[List[String]] =
  if (number.isEmpty)
    Set(List())
  else {
    for {
      splitPoint <- 1 to number.length
      word <- wordsForNum(number take splitPoint)
      rest <- encode(number drop splitPoint)
    } yield word :: rest
  }.toSet

Чем хороши языки вроде C++, Java, C#, Eiffel, D – почти не имея опыта работы с языком все-таки можно прочти сразу понять, что вызывается и с какими параметрами. А вот в функциональщине, если с ней плотно не работать каждый день – фигушки :( Ближе нужно быть к народу, господа ученые :)

Во-вторых, есть у меня сомнения в том, что такие штуки, как параллельные и персистентные коллекциидолжны быть введены раз и навсегда в языке (хотя я не уверен, что Одерски под персистентными имел в виду именно хранящиеся во внешней памяти). Имхо, такие вещи должны быть на уровне библиотек – попроще и посложнее, с ориентацией на различные задачи, с разным уровнем адаптации под нужды разработчиков. Хотя, если цель завлечь в параллельное программирование бесплатной первой дозой – тогда становится понятно. Мол, просто берешь стандартный SortedSet, потом просто вызываешь par и ты уже в Хопре! А что там – под кaпотом – разве кого-то сейчас это интересует, по большому-то счету? ;)

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

Думаю, что такое мелкое DSL-естроение не есть хорошо, поскольку ведет к усложнению процесса сопровождения программы разными людьми, у каждого из которых есть собственное чувство прекрасного (подробнее см.Social Problems Of Lisp).

Но, полагаю, Одерски говорит о “большом DSL-естроении”, когда DSL-и разрабатываются не под конкретные мелкие сиюминутные нужды отдельных разработчиков. А как основа для больших проектов. Например, какая-то лаборатория нуждается в серии вычислительных экспериментов по определению надежности ленточных фундаментов. Экспериментов будет много, каждый довольно дорогой, поэтому от вычислительных программ требуется максимум эффективности. В сочетании с достаточной гибкостью изменения параметров и методов расчетов. Для чего лаборатория разрабатывает или заказывает у кого-нибудь DSL под свою задачу. Чтобы параметры экспериментов описывались на DSL-е, а описания затем транслировались в эффективный код, использующий различные технологии вроде MPI.

В такой интерпретации я ничего не имею против DSL-естроения. Хотя и не очень понимаю, чем здесь internal DSL лучше external DSL. Но это уже другой вопрос.

вторник, 20 сентября 2011 г.

[life.rest.humour] Вспомнились забавные фразочки из отпуска

Во время отдыха в Турции было несколько забавных момента, два из которых буквально врезались в память.

Первый произошел в автобусе, который развозил только что прибывших отдыхающих по отелям. Сопровождала нас русскоговорящая девушка, которая обожала употреблять уменьшительно-ласкательную форму: путевочки, страховочки, карточки, часики, напиточки, прогулочки и пр. Апогеем этого стал рассказ об экскурсии куда-то в горы к целебному источнику: “…А водичка в этом источнике содержит более 30 полезных элементов таблички Менделеева…”

После “таблички Менделеева” я минут десять приходил в себя. Хотя, подозреваю, что из всего автобуса я один обратил на это внимание.

Второй случай был на местном рыночке неподалеку от нашего отельчика :) Видимо, в этом месте отдыхает много русских туристов, поскольку практически в каждом магазинчике (не говоря уже о претендующих на звание “бутика”) были продавцы, очень чисто говорящие на русском. Почти все они – выходцы с Кавказа. Из Грузии или Азербайджана. Приставучие, понятное дело :) А некоторые, похоже, еще и по жизни любители потрепаться.

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

-- Вы же русские, да?
-- Ну, не совсем. Мы из Белоруссии…
-- Из Белоруссии?… Но ведь все равно же русские, да?
-- Ну да, почти русские. Я так вообще русский, жена белоруска.
-- Так может вы мне объясните, почему немцы обижаются, когда я им говорю “Хайль Гитлер!”?

Давно я не впадал в такой ступор как после этого вопроса. Стою, потерявши дар речи, а он рядом и с надеждой смотрит на меня, неподдельный интерес виден в его глазах – мол, может хоть сейчас узнаю в чем дело. Я же понимаю, что что-то ответить нужно, а в голове ни одной мысли… Удалось выдавить из себя что-то вроде: “Так это… это еще с войны наследие осталось…”

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

День Победы, как он был от нас далёк,
Как в костре потухшем таял уголёк.
Были вёрсты, обгорелые, в пыли…

На этом я перестал вообще что-нибудь соображать – абсолютный cюрреализм. Спасло то, что жена, давясь от проглатываемого смеха за локоть утащила меня в другой магазин. А в след доносилось: “Этот день мы приближали как могли”.

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

[prog] Презентация о фреймворке Akka: Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM

Презентация не новая, но попалась мне на глаза только сегодня. Любопытно.

Вообще, смотреть такие презентации без изрядной доли иронии и сарказма я лично не могу. Далеко не новые идеи преподносятся как что-то из области cutting edge :) И это даже если не брать в расчет Erlang, где почти все показанное в презентации эксплуатирует с конца 80-х (правда, широко известен он стал намного позже). Мы в КБСП подобный подход переоткрыли и начали применять в середине 90-х. Что воплотилось затем уже в Интервэйле в наш внутренний инструмент SObjectizer-4, который не много, ни мало, а уже девять лет используется нами для разработки С++ных приложений.

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

По поводу показанных в презентации примеров есть у меня несколько сомнений в правильности выбранных авторами Akka подходов.

Во-первых, для сложных актеров метод onReceive с последующим ручным определением типа сообщения посредством множества обращений к instanceof, на мой взгляд, не есть хорошо. Это черевато некрасивым кодом, провоцирующим ошибки и сложным в сопровождении. Имхо, задача фреймворка определить тип сообщения и вызвать подходящий для сообщения метод. Это как раз то, за счет чего фреймворки вроде MFC упростили программирование под Windows, когда большая WndProc с одним switch-ем внутри была разбита на простые методы, каждый из которых обрабатывает всего одно Windows-сообщение.

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

В-третьих, я не понял, зачем в агентный фреймворк засовывать еще и STM. Шоб было усё и зразу? ;)

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

воскресенье, 18 сентября 2011 г.

[life.sport.darts] Впечатления от использования crowns для фиксации перышек на хвостиках

Существует несколько способов фиксации перышек в хвостиках дротиков. Очень подробно, с иллюстрациями, я писал об этих способах раньше. С тех пор прошло некоторое время, в течении которого опробовал еще один способ – с помощью коронок (crowns).

Коронка (crown) – это специальной формы алюминиевая пластина, свернутая в полуцилиндр, напоминающий корону. Одевается на конец хвостика перед перышком. А затем в усики хвостика обычным образом вставляется перышко:

Получается очень удобно. Перо держится крепко, вылетает редко. При этом, в отличии от колечек (clips), края коронки не режут края перышка.

Тем не менее, после нескольких месяцев использования коронок, я от них отказался. Основных причин две:

1. Коронки, не смотря на свой совсем незначительный вес, все-таки тяжелее колечек (clips) и пружинок (springs). При работе с дротиками больших весов (26g, например) это практически не сказывается. А вот при попытке использования коронок с легкими (22g) дротиками становится заметно, что в полете хвост дротика тянется вниз. Сейчас я вернулся на 24g дротики и на них этот эффект временами заметен :(

2. Если случается робингудовское попадание и игла летящего дротика попадает в зубец коронки, то коронка опускается по хвостики вниз. Если это medium хвостик, то почти до середины. Если это tweenie или short хвостик, то не так далеко:

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

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

В остальных же случаях нужно сильно подумать, стоит ли применять коронки.