Category: наука

Category was added automatically. Read all entries about "наука".

ICFPC 2019

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

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

Очень любопытно посмотреть, чего ты стоишь. В голове-то ты мог много себе про себя нафантазировать, а тут вот объективная реальность, ладдер, и ты либо можешь компьютер заставить делать что ты хочешь, либо не можешь. Никаких «если бы», никаких «возможно, наверное, мне кажется». Мы довольно посредственно выступили (на момент закрытия 29 место из 142 участвовавших, в лучший свой момент были на пятом).

Исторический скриншот. Дальше мы сильно сдали
Исторический скриншот. Дальше мы сильно сдали

Участвовали втроем, я в первый раз. Как я понял, средний размер команды ~5 человек, не редкость и восемь встретить. Втроем у нас довольно хорошо делились области ответственности, было бы больше появился бы организационный оверхед (как мне кажется). Восемь человек я бы вообще офигел менеджить и вообще ничего бы не написал, наверное. С другой стороны, больше рук – можно попробовать больше подходов. Можно вложиться в инфрастуктуру. Наверное.

Задача достаточно нетривиальная, чтобы решить ее до конца было в принципе невозможно. Но и не супер-сложная, чтобы как-то ее решить можно было бы даже иногда и руками (ну, самые простые примеры). Как правило это значит перебор вариантов в каком-то NP-полном поле, соревнование эвристик.

Собери бонусы, закрась лабиринт
Собери бонусы, закрась лабиринт

Clojure, несмотря на все плюсы языка высокого уровня и быстрого iteration time, по ощущениям подошла довольно плохо. Потому что все упирается в перформанс. Можно сколько угодно рассуждать про «глобальные оптимизации против локальных», ненавидеть байтоебство, мыслить как стратег с высоты птичьего полета и гордиться тем, что не знаешь, как устроен компьютер, но это все и в императивных языках можно делать. Они же не отнимают способности мыслить и планировать. Да, механика записи мысли чуть более многословна, ну зато оно того стоит. Плюс за три дня вы разницы может и не заметите даже. А вот по перформансу заметите, еще как. Как ни крути, а команда, которая обсчитает за условное время X в два раза больше вариантов, чем ее конкурент, будет в топе выше. КАК НИ КРУТИ. Больше здесь строго лучше. Либо больше итераций, больше вариантов попробовать, либо решения будут более глубокими, а значит и очков принесут больше.

ICFPC это как раз такой случай, когда лучше чуть больше устать но получить программу которая будет нагружать процессор по делу, а не только мусор за юзером подбирать. К тому же, как ни странно, старые императивные языки может и не очень легко позволяют до энтерпрайзных масштабов раздувать программы, но что-что а бегать по массивам и мутировать структуры они похлеще функциональных могут. Ирония – соревнование приурочено к конференции по функциональному программированию, а побеждают в нем все стабильнее C++ и императивщина.

Выглядит красиво, жаль вся эта мощь обслуживает всякое говно вроде lazy sequences, primitive boxing, high-order functions вместо того, чтобы решать задачу
Выглядит красиво, жаль вся эта мощь обслуживает всякое говно вроде lazy sequences, primitive boxing, high-order functions вместо того, чтобы решать задачу

Сейчас я думаю, что даже если бы мы выбрали просто Java с unboxed примитивами и примитивными массивами, было бы качественно лучше. C++/OCaml/Rust может быть дали бы еще 1,5-2 раза прирост, но это уже не изменило бы ситуацию качественно. Но может и нет, цифры так, с потолка.

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

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

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

не с этого хакатона, но смысл такой же
не с этого хакатона, но смысл такой же

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

лабиринты, генерируемые нашим алгоритмом, имели хорошо узнаваемый вид
лабиринты, генерируемые нашим алгоритмом, имели хорошо узнаваемый вид

Очень важна базовая гигиена. Ну там код неиспользуемый удалять, переменные нормально называть, на функции разбивать нормально где нужно, не писать по два-три раза почти одно и то же, если уже написано. Казалось бы, тоже — хакатон, вы через три дня все это выкините, так ли это важно? Вот оказалось что да. Потому что там где в обычном проекте косяки может через полгода-год всплывут, здесь если ты что-то поленился, коллега уже через полчаса об это споткнется. Причем споткнется обязательно, потому что кода мало и все используют всё постоянно. Так что лучше пять минут потерять, но поправить самому, пока контекст у тебя в голове, чем заставить коллег тебя материть и тебя же дергать. Чисто по времени выгоднее. Несмотря на.

Пилу нужно точить. Как бы ни казалось, что три дня уж без удобств можно прожить, удобства все-таки решают. Мы очень страдали от отсутствия визуализатора. Организаторы предлагали готовый, но в браузере (на ScalaJS кстати), и это не оч удобно было (для каждого запуска нужно было накликать мышкой и выбрать два раза через диалог выбора файла два файла).

Визуализатор организаторов
Визуализатор организаторов
ух как же меня бесило выбирать эти файлы каждый раз!
ух как же меня бесило выбирать эти файлы каждый раз!

Самое большое, чего там не хватало — пошагового реплея, перемотки назад и вперед, ну и доп информацию тоже иногда хочется какую-то вывести. Как разбился лабиринт, что думает бот, такое. Я написал в какой-то момент простой визуализатор через println и clear screen, он даже мультики показывал типа, но хотелось бы чего-то более удобного и универсального.

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

Приходить надо было подготовленным. У ребят, например, из контура, была инфраструктура заготовлена: сервера, гоняющие задачи, сбор ответов, дашборд, сравнение. Мы этого, конечно, не знали, у нас в лучшем случае запустил программу на ноуте — в терминал вывалился результат. Пик инфраструктуры.

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

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

Как правильно распределять силы я пока не понял. Я выложился по максимуму в первый день (до 6 утра, на следующий встал в 11) чтобы как можно больше впихнуть в Lightning Round (первые 24 часа). В результате весь второй день был как в тумане и работалось как на автопилоте. В третий зашли нормально, я переписал алгоритм даже, но тоже было очень тяжело. Возможно, здоровый сон каждый день (ну ок, кроме последнего) суммарно дал бы больше эффективности за три дня, чем такое.

Перерыв на обед
Перерыв на обед

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

усы2

Панель Шрёдингера

Классическое нытье: куча мобильных приложений и сайтов делает заголовки, которые прячутся по скроллу. Идея, как и все современные тренды, максимально дебильная: типа, пока скроллишь вниз, весь экран занят контентом: текстом там, картинками, не знаю. Но стоит руке дрогнуть и скрольнуть на один-единственный пиксель вверх, как тут же со всех сторон вылетают панели, кнопки, статусы и прибамбасы. Вот они вылезают, скажите мне, что бы что? Просто пораздражать своей анимацией? Или люди что, вверх не листают? Все с первого раза понимают? Штука еще и в том, что если (если!) эти гребаные панели действительно нужны и на них хочется посмотреть, ничто не подскажет, как их достать. Худший вариант интерфейса: вызывается случайно all the time, а когда нужно, то фиг поймешь как достать.

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

А как-же, как-же? Ведь мы хотим создать иллюзию легкого и воздушного интерфейса, в котором много места, в котором content first, зачем человеку пялиться на наши кнопки, пока он читает? Работает это так: мобильник — это уже маленькое окошко, вырезанное в нашей реальности. Ваш сайт/приложение — окошко, зона внутри мобильника. Контент — зона внутри сайта. И тем не менее человек может прекрасно сосредоточиться на любом куске реальности и смотреть только в него. Вокруг меня могут бегать кошки, я могу менять руку, которой держу телефон, и я всё равно буду видеть только то, на чем я сосредоточился: контент.

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

А как делать-то тогда?

Первое: не надо этих ваших анимаций. Хотите чё-то на экране показать — показывайте всегда, не надо случайно вызываемых жестов к нему приделывать. Чего нам точно всем не хватало [сарказм] — еще одного аспекта управления и так уже перегруженными многофасеточными контрольными центрами (мобильниками то есть). Если вы хотите чтобы гребаный хэдер с вашим гребаным лого мазолил мне глаза, ну будьте мужиками, примите решение, показывайте его всегда. Только не надо уменьшать его по скроллу, это их двух зол обе: вы и глаза мозолите, и анимациями заколебете.

И тут мы подходим ко второму решению, совсем старперскому радикальному: показывать хэдер один раз вверху страницы. Никуда его не скроллить и не прибивать гвоздями. Поскроллил вниз — хэдер остался наверху. Нужен хэдер — промотал в начало. Радикально? Может, по сегодняшним меркам и да. Но знаете, что я вам скажу? Ни один человек еще не умер от того, что не смог в середине чтения статьи очень быстро и без потери скролла вспомнить, какой же это сайт он сейчас читает. Ну нет такой задачи у людей. У брендов, может, есть. Всем остальным на меню вашего сайта, «доступное в любой момент» — глубоко и совершенно искренне пофиг.

усы2

Десктопные UI

Очевидно, самый правильный способ делать десктопный UI — индивидуально под каждую платформу. Мечта о том, что мы выделим «компоненты», из которых соберем экран, а потом «заскиним» их под каждую платформу, — абсолютно оторвана от реальности. Слишком много нюансов (размеры, отступы, порядок и расположение элементов, уникальные для платформ идиомы) чтобы обойтись просто скином и при этом притворяться нативом.

Кажется, что идея провальна с самого начала. Но в мире есть успешный пример кросс-платформенных UI которые прилично выглядят на любой платформе. Это веб. Да, веб-сайты не собраны из системных компонентов, каждый вебмастер рисует свои кнопки и панели с нуля. Но все привыкли и не возражают. Браузер аккуратно доделывает системно-специфичные детали: нативный скролл (с инерцией или без), рендеринг и выделение текста, системные контекстные меню, системное поведение внутри даже полностью перерисованных инпутов. Системные нюансы, даже в комбинации с полностью уникальным скином и лайаутом, создают вполне приятный пользовательский опыт. Решение оказалось в том, чтобы не притворяться нативным системным приложением, иначе попадешь в uncanny valley, область фальшивых елочных игрушек.


на фото: Transmission Remote GUI (Free Pascal) притворяется нативчиком

На основе браузера сделали Электрон — бандл из хрома, node.js и ваших html/css/js, упакованных в обертку как-бы-приложения. С точки зрения пользователя — всё классно. VS Code, Atom, LightTable, Figma, Zeplin, Slack, VK Messenger, Rocket.Chat, Github Desktop, GitKraken, Basecamp, Ghost, Brave browser, Hyper, SimpleNote — прекрасные, вылизанные приложения, очевидно, что как платформа Электрон уже состоялся.


на фото: системное контекстное меню в Visual Studio Code (Electron)

И это одно из ключевых преимуществ Электрона — возможность напрячься и сделать действительно качественно, круто. Не в том, что можно быстро накидать, а в том, что можно довести до конца. Этого нет, например, у JavaFX/Swing — накидать быстро-то можно, но довести до состояния, когда приложение хочется облизать, —  нет, как ни старайся. Оно так и останется фальшивым на базовом уровне.

Претензия к Электрону, собственно, одна — это такой Докер для десктопа. То есть он пакует огромную тучу всякой фигни ради несоизмеримо маленького функционала. То, что нужно Хрому для веба, например совместимость с IE 5.5, всякие quirks mode, не знаю, видеокодеки, non-strict JS, устаревшие CSS свойства и режимы и совместимость их с новым и современным — это раз в 100 больше того, что вы когда-либо сможете и захотите использовать. И это никак не отковыряешь. Меня даже не размер бандла беспокоит, а то что весь этот легаси серьезно мешает приложению достичь своего потенциала скорости, простоты, надежности. Тот же JS — явно не лучший язык, с кучей совершенно левых/произвольных проблем-ограничений, медленный просто потому, что он настолько плох что уже не ускоряется, явно не готовый к тому, что под ним будет файловая система, что бывают потоки — да, мы не можем выкинуть его в вебе — но на десктопе-то ради чего страдать?

К сожалению, с браузером только всё-или-ничего. Как и докер, это явно неверный вектор развития — бандлить кучу говна просто потому, что так получилось и проще. И все равно web это лучшая на сегодня UI платформа, с лучшим integrated developer experience.

Вопрос, собственно, про альтернативы. На случай, если я проглядел что-то.

На QT бывают хорошие, красивые приложения. QT бывает кросс-платформенный, но это C++. Он, конечно, обходит JS по категории sanity, потому что он не сильно умный и в любой ситуации ты просто делаешь то что тебе нужно, а не пытаешься бороться с тормозами вмененного тебе динамизма. Figma, например, компиляют C++ в JS, чтобы работать в вебе, но лишь бы не писать на JS. Но все равно C++ ужасный язык, низкоуровневый, долгая компиляция, без REPL-а — а UI работу я себе не представляю без REPL-а.


на фото: Telegram Desktop (QT5) с кастомным контекстным меню. Не видно, но скролл тоже фальшивит

Java-решения (Swing/JavaFX) страшны как черт. Я тут скачал демку JavaFX, которая прям с дистрибутивом идет, так у них даже ховер на кнопках тормозит. Плюс естественно всё не нативное — ни скролл, ни выделения, ни контекстные меню, а нарисованное как будто программистами. Окей чтобы накидать что-то по-быстрому для нетребовательной аудитории клерков, но вылизать, кажется, невозможно.


на фото: Modena demo app (JavaFX). Пойдет, но тормозит и всё ненастоящее

Я не уверен, насколько хорош в этом плане SWT — смогу ли я выкинуть весь look-and-feel и нарисовать что-то стильно-современно-плоское, например? Не хотелось бы, чтобы получилось что-то уродливое вроде Eclipse. Он вообще живой еще?


на фото: страница проекта SWT

Что еще бывает? Или выхода нет?

Напомню, что мне важно не «быстро накидать из готовых компонентов», а «сделать и вылизать», причем без привлечения сверхусилий, одному (ха-ха), в разумное время, для всех платформ. Мобилки — что, наверное, сегодня удивительно, но — не интересуют.

усы2

ФП в Киеве есть

Был две недели назад в Киеве, прочитал на митапе в Grammarly доклад, продолжение «ФП в браузере». Доклад про то, как сделать векторный редактор на React.js и Immutable.js.

Коротко:

На JS жить можно, с правильной архитектурой писать вполне терпимо. Я ожидал больше страданий. Запилил мультиметоды и атомы, впрочем.

Immutable.js нормальная штука, не хватает только сериализации/десериализации структур в строку, очень странно что они это упустили. Пришлось писать самому.

Еще смешно: Immutable.js портировали реализацию персистентных структур из ClojureScript, при этом писали на чистом JS и умудрились сделать ее в 2-3 раза медленнее, чем на ClojureScript. Вот вам и про преимущества ручного кода перед компилируемым.

Код: https://github.com/tonsky/vec (650 loc)

Живая версия:



Видеозапись:
http://www.youtube.com/watch?v=lDkrXTDwbJQ (разбор кода)
http://www.youtube.com/watch?v=tUtLe1VlkYc (ответы на вопросы)

В Киеве классно:

усы2

Будьте здоровы!

Согласно вот этой статье из википедии, примерно 18–35% людей чихают при взгляде на солнце. Безусловный рефлекс, генетическая черта.

Я провел опрос в твиттере, действительно, многие признались, что феномен имеет место быть (~25 человек!)

Самые интересные ответы это: «я думал у всех так» (еще один: был уверен, что у всех так) и «постоянно советуют -- не получается чихнуть, посмотри на слонце. Постоянно смотрю как дурак и не чихаю»

С одной стороны, меня заворожил такой вот малоизвестный, но широко распространенный факт. С другой — забавно, как люди делают выводы об механизме устройства остального мира на основании того, как работает их собственное тело («всю жизнь считал...»). Понятно, что это экстраполяция, нехватка данных, малообсуждаемый феномен и т.п. — но пример показательный. Другой похожий пример — прошумевшее на днях #TheDress, которое вскрыло, что вообще говоря у людей сильно по-разному корректор на фоновое освещение работает. Т.е. даже самый близкий вам человек — довольно сильно отличающееся от вас существо (причем если отличается даже самый стандартный базовый «хардвер», то представьте, какие различия на уровне мыслительных процессов!), и что-то априори ему приписывать бывает чревато.
усы2

Научный метод

Когда рассказывают про новосибирский Академгородок (научный район Новосибирска, где изначально находилась куча институтов, НГУ, физматшкола, а теперь еще и Технопарк, все айтишники и офис компании Эхо), всегда вспоминают байку (или не байку) про тропинки:

Когда академик М.А. Лаврентьев в 57-м году приехал в Сибирь, он решил не прокладывать тропинки в лесу, а подождать, пока люди протопчут их сами. Каждая тропинка функциональна: это кратчайший путь к какому-либо месту. За последние 40 лет расположение тропинок не изменилось. От одного института до другого по тропинке можно дойти за 10 минут, а в обход – за 30.




Отличный способ, и сегодня я наконец понял, как применить его в дизайне UI. Пока не до конца ясно, как перенести это на экранные интерфейсы, но на физических это выглядит вот так:



Обратите внимание, насколько понятнее и ближе человеку стал интерфейс с таким нехитрым исправлением. Короче, чтобы понять, как улучшить продукт, достаточно посмотреть, как люди с ним выкручиваются.

Еще пример:

Итак, что же я думаю по поводу Clojure?

Расширяемый чат-бот [1] оказался куда более толковым для освоения языка материалом, чем Проект Эйлер. Я потрогал практически всё, что было в Кложе, и почти не повторялся.

Страх перед скобочками сильно преувеличен. Их перестаешь замечать в первый день, куча гораздо более важного происходит внутри них. Пишешь себе код как везде, выравниваешь, копи-пастишь, читаешь, никаких проблем. Ставить их вокруг функции намного логичнее, чем часть выражения оставлять снаружи, часть внутри, и не дай бог можно опускать. Мне когда-то это казалось отличной идеей, а-ля ML, Coffee Script, Perl — мусора меньше, но потом я как-то увидел чужой исходник на Ocaml-е — пространство, равномерно заполненное двух- и трех-буквенными аббревиатурами, и понял, что скобки, они к лучшему, не мешают, а помогают читать.

Синтаксис в Кложе самый крутой, конструкции навернуты невероятные [2], но если поначалу тупишь [2], то потом все отлично, привыкаешь. Причем чтобы с этим всем разобраться, надо ковырять стандартную библиотеку, а не книгу по языку, что тоже довольно скоро начинает казаться естественным и логичным. И даже, разделение элементов списка пробелами, без запятых — как-то вдруг свежо, стройно и красиво решает проблему их назойливого болтания в начале и конце.

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

Динамичность тоже отличная штука. Пишу я своего бота, он у меня в фоновом потоке законнекчен, и не разрывая никаких соединений я его спокойно обновляю и тестирую. Говорят, если соединить repl с Емаксом, будет еще круче и код вообще из редактора будет обновляться, но я его пока боюсь, хотя надо уже браться. Главное, всё это построено на тех же самых примитивах, что доступны пользователю языка, то есть можно писать скрипты, работающие с неймспейсами, грузить туда-сюда, сканировать, менять, всё что угодно. Всё, чего вдруг не окажется, собери себе сам, как и в случае с синтаксисом.

Про собственно код. Намерения маппятся на текст программы точнее и плотнее, чем, опять же, везде, где я видел. На глазок получается, что одна функция на Кложе ≈ один файл на Джаве (при компиляции примерно то же соотношение).

Если об ощущениях, то это выглядит так: сидишь, думаешь, здесь так должно работать, а в этих случаях так, и если это, то то, и еще в этом случае надо вот это учесть, потом думаешь: ну всё, надо уже писать. Пишешь, пишешь. Проверяешь, пробегаешься по всем случаям, что продумал. Да, вроде всё учтено. Оглядываешься — написал четыре строчки.

Если еще об ощущениях, то чем больше я погружаюсь, тем больше паззл сходится. Последний раз такое было с Эрленгом, в котором все части очень грамотно и красиво дополняли друг друга, но там это укладывалось в одну нетолстую книжку. Здесь все началось с Рича Хики, который сначала рекомендовал всем не быть хипстерами, а выявлять настоящие проблемы и решать их [3]; продолжилось им же в толке про деконструкцию устоявшихся программистских конструкций на элементарные ортогональные части [4], и блестящим воплощением этих идей по всей Кложе.

Ну и в конце концов, из Кложи, возможно ввиду ее молодости, еще не высосали весь фан. Я, например, оторвался с антропоморфными названиями частей чатбота и лог-функциями типа (omg! …). Если попытаться представить что-то подобное в другом языке, вдруг понимаешь, что в Джаве запрещены имена классов из менее чем трех слов, в Скале названия берут из математических теорем, на Хаскелле пришлось бы называть их по-гречески (что круто, но крутизну оценили бы те восемь человек, которые его используют)1. На Питоне пришлось бы соревноваться в остроумии с Гвидо, чтобы писать на С, нужна борода, а на Ноде-ЖС, если давать осмысленные имена, велик риск обнаружить, что задница управляет мозгом через коллбеки. Получается, что единственное место, где можно ловить кайф по части названий — это Кложа.

Когда я узнал, что они всю эту красоту еще и в браузер перенесли (в очередной раз сделав это очень умно и по делу — [5]), стало понятно, что деваться некуда, скоро все будут писать на Кложе, поэтому надо работать на опережение. Я, в общем-то, даже с JVM уже примирился, хотя нечаянно закрыть repl пока ощутимо больно. Oracle, давайте уже допиливайте свою модульность и быстрый старт, будет с вас хоть шерсти клок.

Резюме: всем брать пример с Рича Хики. Кложа опционально, но горячо рекомендую.

Ссылки:
  1. Разбор кода чат-бота, in english.
  2. Пример одной из сложнейших конструкций condp.
  3. Мини-конспект первой презентации Рича Хики про решение проблем.
  4. Конспект второй презентации Рича Хики про элементарные ортогональные части.
  5. Introduction Стюарта Сиерры и видео Рича Хики про ClojureScript, in english.


1 На самом деле, если мне когда-либо доведется что-либо писать на Хаскелле, абсолютно точно первый свой тип я назову Пиписька. Просто чтобы сбить пафос.

Простота против универсальности

Почтовые папки — это понятный интерфейсный объект, да еще и подкрепленный физической метафорой. Как люди используют папки? Наверное, они заводят папку под какое-то условие — адресат, ключевое слово в теме письма и т.д. Пользователь видит папки каждый день при работе с почтой, заходит в них, ищет в них. (В тексте под папками понимаются как ярлыки гмейла, так и классические imap folders, изложенные мысли верны для обоих.)

А что такое, скажите, фильтр? Фильтр, он же правило обработки почты — это маленькая программа, которая раскладывает письма по папкам. Фильтр эфемерен, у него нет метафоры, пользователь не видит его каждый день, не работает с ним, фильтр — это чистая абстракция.

Вот, например, настройка фильтров ГМейла:





А так выглядят правила Яндекс-Почты:




По сути примерно одно и то же. У Яндекса можно одновременно указать От кого ИЛИ Кому, но почему-то можно выполнить только одно действие.

Самая человечная, наверное, Зимбра:



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

Понятно, почему так получилось: программистам не привыкать работать с абстрактными сущностями, и им же не привыкать к действию-объекту (rm file вместо file rm). Эта гипотеза объясняет возникновение фильтров. (А по интерфейсу гмейла видно, что фильтров с первой технодемонстрационной реализации до сих пор не коснулась рука не то что проектировщика, но даже дизайнера).

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

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

P.S. Кстати, если посмотреть внимательно, один фильтр может складывать письма только в одну папку. То есть даже сейчас перевернуть отношение фильтр-папка ничто не мешает.

UPD: В Опере сделано страшненько, но правильно (спасибо legolegs за подсказку):

(no subject)

Что-то как-то не верю я больше в иконки как графическое средство. Как элемент интерфейса они нужны, но как оформительский прием бессмысленны и вредны. Да и изображения многие тоже — те, которые не являются непосредственным содержанием сайта, а «привлекают внимание посетителя», не нужны. Если их убирать, только лучше становится. А все почему? Потому что во всем должен быть смысл.



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

о гибкости сознания

Все протоны во вселенной между собой абсолютно одинаковы. Можете это представить? И электроны, и нейтроны тоже. То есть нас всегда учили, что двух одинаковых предметов не бывает, что они могут быть максимум что очень похожи, а когда спускаешься на фундаментальный уровень -- оба на! Возможности различить нет. Просто нет никакого способа. В принципе. Абсолютная идентичность. Так устроен мир.

А еще, свободный нейтрон распадается в протон плюс электрон и антинейтрино, и в то же время тот же протон (в ядре) распадается обратно в нейтрон плюс позитрон и нейтрино!

Я уж не говорю про способ просветления оптики: на стекло клеится пленка толщиной 1/4 длины световой волны, отраженная от нижней стороны пленки волна накладывается на отраженную от поверхности в противофазе и УНИЧТОЖАЕТ СЕБЯ! А поскольку энергии деваться некуда, увеличивается количество света, проникающего внутрь.

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