Никита Прокопов (tonsky) wrote,
Никита Прокопов
tonsky

Categories:

Хипстеризация

Путешествие по миру Clojure библиотек проходит не так гладко, как планировалось. Отцы-основатели подали хороший пример в clojure.core и сlojure.contrib (ныне org.clojure/*), но соответствовать не у всех получается.

Сначала Storm (который Twitter Storm) опечалил своим ООП-подходом, когда вместо отдельно данных и функций всё сваливается в кучу. Это, кажется, идет от его Java-корней, Clojure там приделали позже. Держаться можно, если спускаться в Storm только в самый последний момент.

Вторым моим неудачным опытом стал Midje, который рекламирует себя так:

Midje is a test framework for Clojure. I created it to support top-down as well as bottom-up testing, to encourage readable tests, to provide a smooth migration path from clojure.test, to support a balance between abstraction and concreteness, and to be gracious in its treatment of you, my valued guest.

На словах у них все действительно прикольно; лезешь в дебри, и вроде бы тоже круто — куча всякого мяса на все случаи жизни, и такой ассершн, и сякой, и пятый, и десятый; кажется, что больше ничего никогда не понадобится (в отличие от clojure.test, в котором есть только is и are и больше ничего и вообще непонятно, как же им тогда пользоваться). На радостях я начал его тянуть к себе и сразу понадобилось. Тут стало понятно, что Midje на самом деле весь про красивую запись, чтобы писать не

  (is (= (f x) 2))

а

  (fact (f x) => 2)

или, допустим, не

  (are [k v] (= (m k) v)
    :a 1
    :b 2)

а

  (fact m => (contains {:a 1 :b 2})

И хотя философия Clojure не запрещает красоты и удобства (зачем иначе макросы?), помимо них во главу угла ставятся также простота как отсутствие составных частей и стыкуемость абстракций. Midje же, если к нему присмотреться, родился из желания автора писать поменьше символов. Заявленное, конечно, работает, но эта стрелочка и разные удобные штуки правой части выражения — это очень страшное макропрограммирование, которое делает кучу сложных предположений об устройстве тестовых форм.

Получилась вещь в себе — если постараться, можно написать свою contains-in функцию с кучей особенностей для Midje и она будет работать в правой части (хотя добиться, чтобы она печатала что нужно в случае ошибки мне не удалось), а можно взять просто функцию get-in и дубовый clojure.test и написать (is (= (get-in ...))) и будет логично, удобно и просто. Если проверок несколько, это заворачивается в прекрасный (и гениально универсальный) макрос are и это единый способ на все случаи жизни. Оказывается, все что нужно у нас давно уже есть и его можно и нужно использовать в тестах. Воистину, лучше научить человека ловить рыбу... Или, скажем, надо поменять формат output — в сlojure.test сразу понятно как это сделать, а в Midje даже авторы затрудняются — потому что он внутри правда очень сложный. Зато, типа, символов мало писать.

Или посмотрел я вчера на что у нас есть для Redis. Гуглится такое:

  • A high-performance, all-Clojure client.
  • Modern targets: Redis 2.0+ (with full 2.6 support), Clojure 1.3+, Leiningen 2 support (not mandatory).
  • Industrial strength connection pooling.
  • Complete and accurate command definitions with full documentation.
  • Composable, first-class command functions.
  • Flexible, high-performance binary-safe serialization.
  • Full support for Lua scripting, Pub/Sub, etc.
  • Full support for custom reply parsing.
  • Command helpers (atomically, lua-script, sort*, etc.).
  • Ring session-store.
  • Simple, high-performance message queue (Redis 2.6+).

По первом прочтении я чуть от радости не запрыгал — надо же, какие классные ребята, как правильно пишут! Потом замечаешь эпитеты в каждом предложении, как будто дезодорантом пытаются спрятать что-то не слишком приятное само по себе (я уверен, что это маркетинг Эппл диктует моду — на сайте любого мак-приложения будет написано «The simplest way to ...», а написать вместо этого по делу яиц не хватает). Потом, конечно, читаешь, что «Simple, high-performance message queue (Redis 2.6+)» у них означает «Currently ALPHA QUALITY». Потом глаз цепляется за Leiningen 2 (зачем redis-библиотеке интеграция с системой сборки?), а потом видишь, что они еще и логгер свой туда притащили (зачем redis-библиотеке логгер? Я не знаю. Самописный, с самобытным конфигом — как его в приложение-то интегрировать?). Сериализация тоже самописная, по умолчанию она все объекты, даже примитивы, заворачивает так, что Redis нихрена не понимает, что у него там хранится (зато, типа, для разработчика «This scheme is consistent, unambiguous, and simple»).

Такой вот хипстерский лагерь — и вера в то, что на одном вкусе можно выехать, и что вкус в программировании (и простота тоже) — это написать поменьше символов, и поливание абстрактными, ничего не значащими комплиментами самого себя. Рич как-то призывал общественность расфокусироваться с удобства программиста и сфокусироваться на реальных, измеримых качествах получаемого продукта. Я ему верю, потому что каким-то образом все, к чему притрагивались ребята из clojure.core — оно работает, оно работает просто, оно меняется, расширяется, соединяется и переиспользуется в нужных местах. Так вот, кто-то его слушал, а кто-то в этот момент хвастался во дворе перед друзьями новой красивой, но бессмысленной вещью. Но красивой. В общем, как бы ни хотелось, мне с этими ребятами, кажется, не по пути. Лично я это самолюбование и взаимное обмазывание хипстерскими ценностями не смогу сколь-нибудь долго читать, для душевного спокойствия гораздо лучше что-то такое.

Кстати, пока писал, подоспела статья на ту же тему: clojurefun.wordpress.com/2012/08/17/composition-over-convention. Всем чмоки. Бороду уже начал растить (или бороды тоже хипстеры заняли?).

Tags: clojure, fp, девелопмент, культура, формула успеха, ходил в народ
Subscribe
  • Post a new comment

    Error

    default userpic
    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 56 comments