Моя первая работа

Месяц назад я поддался пагубному воздействию чрезвычайно мощного вау-импульса — на целых три недели он выбил из меня все дерьмо и я забыл о чем я хотел писать в блог и что вообще планировал делать.

Сегодня я впервые получил деньги за написанную мной программу. 10к.

Это мало, но последний раз ради этой суммы мне пришлось целый месяц караулить тридцать самоходных пушек в диких уголках Уссурийска — тех местах, над которыми не властно время; там до сих пор явственно ощущается присутствие живого и здравствующего Советского Союза. За двадцать лет там ничего не изменилось… только обветшало и покрылось пылью.

После того как я написал этот огромный пост про маленькую программу-качалку на лиспе, меня неведомым образом нашел некто @pavelegorkin — яблочник-игродел из местной Приморской Kama Games и предложил податься в Apple-аналитики — написать небольшую программку для слежения за позициями приложений в чартах iTunes Store. Позже оказалось, что там же работал давний мой теперь уже твиттер-не-взаимофолловер @sirjartur; во-истину, мир мал. Учесть, что мой опыт в написании реальных приложений был чуть более чем никакой — я делать нечего, согласился; надо же когда-то начинать? Это ознаменовало начало моего фрилансерско- нищебродского пути.

Решили, что писать буду на Clojure (повезло с первой работой, да и XXI-ый век на дворе, не так ли?). Но первые несколько дней, пока осваивал библиотеки для работы с базами данных и RSS-фидами пришлось написать маленький прототип на питоне.

Через три недели я выдал результат — крохотное веб-приложеньице на 700 строк лиспокода. Заказчик разместил программу в облаке Amazon EC2 — для пущей релаябельности и аваилабельности :) К тому же ежедневно программа жрет довольно много трафика. Сама по себе она проста и обычна: параллельно запускается веб-сервер и c десяток-другой чтецов, которые читают RSS-фиды о позициях приложений в чартах Top Free Apps и Top Paid Apps яблочного магазина iTunes Store. Пользователь, зайдя на сайт может ввести имя программы для iPhone или iPad (с умным поиском через iTunes API!) и посмотреть на сколько позиций изменился рейтинг программы за неделю/месяц в каждой из стран для каждого из жанров программы.

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

Для испытания программы сегодняшний день подходит как нельзя кстати. Вчера студия Артемия Лебедева выпустила приложение Ozon.ru и вот что сегодня мне выдала моя программа:

Вот выдача для очень популярного приложения:

Сейчас я точно могу сказать чем отличаются реальные программы от халоворлдов: реальные программы — это комья грязи; липкая гадость которая склеивает энное количество технологий, семантик и языков:

NoSQL
До этого я к базам данных вообще не прикасался и не сказать что я их любил, скорее — опасался. Но жизнь заставила и пришлось в экстренном порядке браться за литературу. К SQLообразным базам у меня до сих пор недоверие, но к тому времени я уже был наслышан о всевозможных NoSQL-базах. Три дня осваивал CouchDB, но её возможности оказались для меня избыточными, к тому же её авторы явно перемудрили с MapReduce, так что я остановился на варианте по-проще: MongoDB. Для этого я использовал библиотеку congomongo, простую, удобную и в духе Clojure.
JavaScript
Для Clojure сейчас нет иного способа для выполнения MapReduce-запросов к MongoDB, кроме как отправки куска JavaScript-кода. Я попробовал библиотеку Scriptjure для генерации джаваскрипта из S-выражений, но она меня жутко разочаровала отсутствием формы for, без которой вся эта затея просто бессмысленна.
JSON
Тут у Clojure все просто замечательно: clj-json справляется с задачей перегона структур данных из/в JSON на отлично.
XML и HTML
Java-мир несколько разочаровал меня отсутствием вменяемого и надежного RSS-парсера на манер питоновского Feedparser. С другой стороны я терпеть не могу HTML-шаблоны. Для работы с XML-разметкой отныне я использую просто охуенную парочку из братьев-близнецов: tagsoup и hiccup.

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

Время
java.util.Date не так хороша как хотелось бы. clj-time для временных дел куда удобнее.
HTTP
Все HTTP-клиенты для Clojure сосут. clj-http сосет меньше.
Циклы
В здравом уме и твердой памяти у меня не поднимется рука писать маломальски незатейливые циклы имеющимися в Clojure loop'ом, doseq, for и недо-рекурсией. Я использовал небольшой DSL для итераций clj-iter. Это меньшáя сестрица библиотеки iterate из Common Lisp.
Многопоточность
Как ни странно, но многопоточные фичи, как-то — 60 параллельно работающих RSS-чтецов — это реально самая простая часть программы. Спасибо, Рич Хики.

Что я из этого вынес? Лисп вообще и Clojure в частности сейчас — лучшее средство для интеграции всего и вся. У меня получались функции в которых пересекались сразу три-четыре семантики и языка — HTML, Циклы и JavaScript — и все они были S-выражениями, все они были лиспом. И это было хорошо, потому что мне не приходилось учить вторые языки, например, язык HTML-шаблонов.

По этому поводу Joel Moses сказал:

APL как красивый бриллиант — безупречный, симметричный. Но вы ничего не можете к нему добавить. Если вы попытаетесь приклеить к нему другой алмаз — вы не получите бóльший алмаз. Лисп же — это ком грязи. Добавь еще и он останется комом грязи — он все еще будет выглядеть как Лисп.

(Джоэль отрицает что сказал подобное, он говорит, что сравнил Лисп с мешком фасоли, потому что он всегда возвращается к своей исходной форме)