|, me, hikki, ok

Хайлайт

Тхис жж ис врыттен ин тхе хопе тхат ит вилл бе усефул,
бут ВИТХОУТ АНЫ ВАРРАНТЫ; витхоут евен тхе имплиед варранты оф
МЕРЧАНТАБИЛИТЫ ор ФИТНЕСС ФОР А ПАРТИЦУЛАР ПУРПОСЕ.
РЫД АТ ЁОУР ОВН РЫСК!
Я предупредил.

Все упоминаемые в данном жж действующие лица вымышленны и не имеют связи с реальными людьми или событиями.

Все мои тексты и рисунки в этом жж, если в самом посте явно не оговорено иное, распространяются по лицензии Creative Commons License
Однако, рисунки из постов с тегом idraw, если в самом посте явно не оговорено иное, распространяются по лицензии Creative Commons License.

Содержательная часть этого жж примерно на три четверти состоит из моих явных и неявных излияний на тему «X — это говно», где X — это почти всё, что угодно, начиная от зубной щётки и POSIX-совместимых API, и заканчивая современной системой высшего образования и интерпретацией археологами архитектуры какой-нибудь древней пирамиды.
Ещё иногда вдруг начинаю писать про [конструктивную] математику (про Haskell там, зависимые типы и всё такое), но в результате всегда получаются серии постов об ужасах жизни, пьяницах-наркоманах-гопниках и войнах с бюрократией.
В объедках иногда встречаются излияния на тему японского визуального искусства, заметки об использовании UNIX-подобных операционных систем и всякий случайный мусор, приходящий мне в голову.

Пишу редко, но если пишу — то много. О уровне моего Чувства Собственного Достоинства можно не сообщать, я прекрасно осведомлён.

Ещё немного бесполезного текста есть в био.

А вообще это — пост для связи, где комменты скринятся.
|, me, hikki, ok

О не той оптимизации и голосовании не по любви, а по расчёту

Извините, наболело. Немного арифметики на пальцах и политики.

Предположим, имеются три группы лиц: A, B, C.

Цели группы A в равной степени: обманывать, воровать.
Цели группы B в равной степени (хорошо если бы): воровать, якобы что-то менять.
Цели группы C: якобы что-то менять.

В данный момент правит A, влияние их целей следующее:
обманывать = 50%,
воровать = 50%.

Предположим, вам не нравится, когда кто-то обманывает и ворует. И тут у вас вдруг появляется шанс подействовать на плотность обмана и воровства. Вы не голосуете за A, потому что она, очевидно, вам не нравится. Но вы не голосуете и за C, потому что вашего голоса всё равно не будет достаточно, чтобы она начала оказывать влияние, но вы не хотите, чтобы влияние получила A, потому вы голосуете за B. Логично, правда?

В результате влияние получается следующим:
обманывать = 50% * (1 - b) = 50% * a,
воровать = 50%,
якобы что-то менять = 50% * b,
где a — влиятельность A, b — влиятельность B, c — влиятельность C, c = 0, a + b = 100%.

Если бы вы проголосовали за C, и C не прошла:
(a + k * a * c) + (b + k * b * c) = 100%, k = 1 / a + b, после раскрытия скобок и подстановки получается a + b + c = 100%, но считаем, что проценты c распределены между a и b:
обманывать = 50% * a * (1 + c / (a + b)),
воровать = 50%,
якобы что-то менять = 50% * b * (1 + c / (a + b)),
где всё аналогично.

Если бы вы проголосовали за C, и C прошла:
обманывать = 50% * (1 - b - c),
воровать = 50% * (1 - c),
якобы что-то менять = 50% * (b + c),
где всё аналогично, a + b + c = 100%.

Итого, голосование за C в плохом варианте (C не проходит) увеличивает количество обмана на 50% * a * c / (a + b), где, замечу, c маленькое (иначе бы C прошла), а в хорошем варианте количество обмана и количество воровства уменьшается на 50% * c.

Значит:
плохой вариант: ухудшение на 50% * c * a * / (a + b)
хороший вариант: улучшение на 50% * c * 2,
не трудно заметить, что a / (a + b) <= 1.

Матожидание (плохой вариант с минусом, хороший с плюсом): 50% * c * (2 * p - (1 - p) * a / (a + b)).
Считаю в ghci:
let f = \ a b c p -> 100 * 0.5 * c * (2 * p - (1 - p) * a / (a + b))

(100 для того, чтобы в процентах)

Говорят у нас сейчас семипроцентный барьер. Число 0.55 взято из телевизора, я им не верю, но пускай будет официальное.

f 0.55 0.38 0.07 0.01 ~= -2.0
f 0.55 0.38 0.07 0.10 ~= -1.16
f 0.55 0.38 0.07 0.20 ~= -0.2
f 0.55 0.38 0.07 0.23 ~= -0.01
f 0.55 0.38 0.07 0.24 ~= 0.1
f 0.55 0.38 0.07 0.30 ~= 0.65
f 0.55 0.38 0.07 0.40 ~= 1.55
f 0.55 0.38 0.07 0.50 ~= 2.46
f 0.55 0.38 0.07 0.80 ~= 5.18
f 0.55 0.38 0.07 1    ~= 7

Итого, если существует хотя бы 24%-ная вероятность того, что C наберёт хотя бы 7% надо идти голосовать за C. В самом худшем случае матожидание хорошести жизни станет хуже на ~2 процента, зато уже с 50%ой вероятности оно становится лучше на ~2.5%. (Кстати, смотрите как быстро к c растёт функция при увеличении вероятности.)

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

Рассмотрим следующее рассуждение. За несколько итераций голосования по этой логике: A уменьшается во влиянии, B увеличивается, а C остаётся на нуле. Вероятно, что во время этого процесса B будет постепенно превращаться в аналог A (ибо нет конкурентов).
Но, предположим, что этого не происходит. Количество обмана постепенно уменьшается, количество воровства остаётся на прежнем уровне. Пусть в результате A выбывает из игры, на её место приходит D с любыми другими хорошими целями. Наступает очередное голосование, вы голосуете за D или C (они обе хорошие). В лучшем случае вы потратите ещё столько же времени, чтобы избавиться от воровства (в худшем случае ещё больше, поскольку в начале шансы пройти и у C, и у D низки). Вы уверены, что вам на это хватит жизни?

Замечу, что рассуждения и расчёты остаются аналогичными для любого количества групп/партий.

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

UPD: меня поправили на опечатке в формуле. заодно в f заменил k на p, чтобы не путалось.
|, me, hikki, ok

Европа почти как военные сборы

В прошлом году в конце лета были военные сборы, в этом году мне вдруг впёрло прокатить по, по возможности, всей интересующей меня Европе. Трудно сказать, что из нижеследующего было основной целью, но:
* хотелось хоть на какое-то время вырвать себя из среды, где в бытовой речи используются славянские языки;
* хотелось попробовать пожить в режиме постоянных переездов.
Получилось физически куда тяжелее и занимательнее военных соборов. Я отважный капитан, я в одиночку объехал много стран (перечисляю те, где останавливался больше, чем на 12часов): Литва, Польша, Австрия, Германия, Франция, Голландия, Дания. В сумме провёл там почти месяц, потратил чуть больше 800 евро (без учёта снаряжения). Без Франции, Дании (по большей части) и немного более аккуратном планировании (сэкономил бы ещё ~30 евро) было бы в полтора раза дешевле.

TL;DR: Если имеются способности к тому, чтобы не жрать двое суток подряд, знание английского, терпение, умение жестикулировать (пригодится во Франции, где по английски как-то не очень), смартфон с выходом в интернет по WiFi и GPS, то в западную Европу можно спокойно на месяц-два ехать одному. Если ещё и имеется умение вычислять гопников на расстоянии и знание Польского, то можно и в Польшу почти спокойно ехать (см. ниже).
Collapse )
|, me, hikki, ok

Нашёл в спаме и обрадовался

Dear Friend,
good day,my name is Pavel Khodorkovsky,son of Mikhail Khodorkovsky the former head of the Yukos oil company.Yukos oil company was once
Russia's largest oil producer.Please I want you to carefully read my letter as it means a lot to not only me but my entire family.I dont
want to waste your precious time neighter mine,but if you feel bad about this you may ignor it.My letter is born out of an emmergency
within my family.My Dad was convicted for Money laundering and tax evasion charges,the trial on money laundering and embezzlement charges
which began in March 2009,then later accused for sponsoring opponent presidential candidate and theft of billion Dollars with his PA Mr.
Platon Lebedev,from the subsidiaries oil Yukos company from 1998 to 2003.Since the begining of this trial my Dad's known wealth has been
taken away and most of his local and international bank accounts confiscated.I am now writing to you about this after my search for a kind
reliable and trusted person to handle this for me,since I cannot do this my self directly.I am contacting you for the unknown cash money
deposited by my father,in dollars some years back with a finance institute (bank)in Italy which no one else but my step mother and I are
aware of,my father revealed this to his wife on her last visit to him in prison as it was deposited in her daughters name for reasons of
security and human factors. The figure in Italy is worth precisely 15.7 Million Euro today.I want to let you know that if this is successfully
done,which I am very positive it will be sucsessful,I will give you more confidential information about some other deposit in switzerland and
the united state,where I am curently living in,on self exile.Please I seek someone who is honestly transparent to help received this money
before the government and persecutors gets to find out.All process will be handled by a legal Attorney so as not to breach laws,acknowledging
the circumstance at hand,I require someone who is proactive and willingness to contact the bank in italy and be in possesion of this said money
in no time soon.I also want to plead with your gods not to reply this letter if you will not be reliable.We want to transfer this whole money
for safe keeping for the use of my immediate family to my account here in the united state of america.
Contact me via my private email:-*censored*, so that we can discuss the other necessary important matters and I will pass all other
informations to you in respect of this deposit in rome.One last and most important thing I will want to make you understand is that my family
needs this money for the our future upkeep and only a reliable and trustworthy individual or organizaton is what we require for this transaction,
close relatives have in the nearest past done away with some of our money of this nature for reasons best know to them,as a result I do not want
such to repeat itself.I will be most delighted to receive your reply to my letter for futher correspondence.I shall give you my personal contact
details for transparency sake as we move forward.
Thank you,Pavel Khodorkovsky.
|, me, hikki, ok

Почти три месяца event_mask is 110111, not able to describe 4th event

Откровенно говоря, в половине случаев, когда я хотел о чём-то написать в жж, меня больше сдерживал сам жж своей свинской реабилити, нежели остальные обстоятельства. Три месяца — это много.

Из того, что произошло за это время ярко выделяются:
* защита магистерской диссертации,
* поступление в аспирантуру,
* написание отчёта по государственному контракту в TeXе,
* катание по Европе поездами и последствия,
* любовь к NixOS;
* начало ведения другого блога.

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

Про магистерскую я надеюсь когда-нибудь рассказать в другом блоге. Вкратце, я научился кодировать в разрешимом подмножестве зависимой системы (брр, я столько раз писал это словосочетание, что муражки по коже пробежали) типов (Agda) некоторые любопытные утверждения о некотором ограниченном классе программ (подмножество систем управления чем-нибудь достаточно дискретным). Я всё мечтаю допилить это до состояния, когда этим можно будет хотя бы нормально поиграть, но в Агде очень не хватает deriving Eq для эквивалентности по Мартину-Лёфу, я экономил всё, где мог, а потому там пока всё не очень красиво и малоюзабельно (зато научно, ага).

Собственно другой блог это там. Оно в весьма зачаточном состоянии и на английском. В очередной раз хочу выразить благодарность yuno и передать привет всем, с кем после поступления в аспирантуру у меня почти исчезло время поболтать.

Написание отчёта по госконтракту в TeXе это прямо веха в моей жизни, я считаю. Я так смачно натрахался с LaTeX2e, что словами не описать. По дороге возненавидел всё внутренности TeXа всей душой, но выпилил подобие ГОСТовских шаблонов для вёрстки документов и biblatex. Результатами я когда-нибудь тоже поделюсь (я хотел в сентябре, но, как обычно, времени допилить всё до приличного состояния нет, а в неприличном состоянии выкладывать стыдно). Нетипизированные языки программирования надо жечь.

Кстати, любопытно, в сентябре пришлось писать генерировалку doc'овских шаблонов для другого госконтракта. Из любопытства, возьмите достаточно большой вордовский документ, сохраните его в html. Загрузите обратно. За исключением изменения цвета текста (это баг ворда, да) вся разметка сохраняется. Даже ссылки на переменные и вычисляемые выражения в документе. Если почитать сгенерированный html и поэксперементировать с его минимизацией, то можно научиться генерировать красивые htmlные документы, в которых даже нумерация списков, оглавления и ссылки правильно генерируются самим вордом после их открытия им (правда в браузере их бесполезно открывать, вся разметка плывёт в жопу).

Я так нареверсинженерился того, что он там генерирует, что чувствую в себе силы написать компилятор из подмножества LaTeX в этот doc-html. Штука в том, что на этот раз я знаю как LaTeX устроен внутри и, извините, но компиляция документов сделанных при помощи стандартных пакетов и макросов LaTeX2e — занятие не для слабонервных. Если бы между texовским файлом пользователя и LaTeX2e был бы ещё какой-то вменяемый уровень абстракции, то ещё куда ни шло, но там сразу всё макроподставляется в грязнющий Plain TeX, полный всяких хаков, а это нереально декомпилировать обратно в адекватное описание того, что мы хотим получить. Судя по результатам реверсинженеринга, Word, в обмен на флексибилити, пытается держать внутри близкое к адекватному AST документа с которым хоть работать можно.

Короче, надо писать свой компилятор для TeXа.

Дальше. Я вроде писал, что у меня есть свой собственный дистрибутив. Так вот, был. Идея была хороша, из общего описания всех машин кластера генерируются squashfs-образы их систем, при пуске поверх squashfs при помощи aufs2 монтируется rwшный tmpfs. Чтобы закоммитить изменения нужно было запустить скрипт, который смонтировал бы ещё один tmpfs поверх, а предыдущий tmpfs зажал бы squasfsом, положил в специально отведённое место в /boot и добавил в смонтированные слои.
На практике, как оказалось, это работает не очень:
* локальные изменения перетирают изменения в настройках кластера и за конфликтами тяжело уследить (это можно было правильно победить, но лень);
* частые локальные изменения генерируют много слоёв в aufs, засирают неймспейс файловых систем в ядре;
* целиком пересобирать образы каждый раз очень бесит.
Я было стал переписывать систему, чтобы победить все эти недостатки сразу. Думал, думал, писал, писал, писал. И понял, что я пишу то, о чём уже слышал. Есть такой пакетный менеджер с очень неудачным трудно гуглибельным названием и операционная система, которая его использует. Мне лень тут пересказывать куски из его документации, читайте сами. Но эта штука решает почти все традиционные проблемы, связанные со сборками пакетов и деплоем.

По сути, Nix — это такой ленивый функциональный язык программирования, в котором есть специальный строгий тип derivation (по сути «пакет»). Эти деривейшоны (пакеты) генерируются из других деривейшонов (пакетов) функциями, принимающими зависимости (естественно, деривейшоны) пакета в качестве аргументов. Форс деривейшона — сборка пакета. Сборка происходит в изолированном окружении, где доступны только содержимые других явно указанных деривейшонов (аргументы функции). Никаких /usr и /usr/local в NixOS нет.
В итоге, забыть указать какую-то зависимость просто невозможно, пакет просто не скомпилируется. Идентефикатором деривейшона является хеш описания дерева зависимостей, начинающихся с него самого. Изменился исходник, способ сборки или зависимость — изменился идентефикатор.

Энвайромент юзера и системы явно составляются Nixом из списка нужных деривейшонов. Юзеры обычно делают это ручками (типа, мне нужен wget, я прошу Nix добавить мне его в энвайромент, если оно уже скомпилировано, то он просто его добавит, если нет, то скомпилирует и добавит, после этого, если другой юзер попросит добавить ему такой же wget (а не с другими зависимостями, например), то это произойдёт моментально), NixOS позволяет делать описание для всей системы, а nixos/modules по абстрактному описанию системы сгенерируют ещё и все конфиги в /etc и initrd (в том числе и конфиг для самого Nix, где рассказывают сколько ресурсов можно жрать во время сборки, например), например.

Можно откатываться на предыдущую версию пакета/всей системы, если что-то пошло не так (более того, версии системы добавляются в меню в GRUB и всегда можно загрузиться в предыдущую, если эту сломал), можно собрать две версии одного пакета, одну версию с разными зависимостями, установить пакет только для одно юзера (без прав rootа, кстати) и прочие плюшки, которые тут все просто не перечислить. Короче, Nix — это пакетный менеджер вашей мечты, просто вы этого пока ещё не знаете, прочтите их мануалы. Я в начале немного сомневался в удачности дизайна их системы, но, прочитав всю доступную документацию, понял, что там просто вещи не очень удачно названы (тот же «Nix» чего стоит, например, хрен выгуглишь), а по сути всё очень близко к идеалу. Настолько близко, насколько это вообще возможно без выбрасывания нафиг устоявшихся методов работы с системой (shell, не экзоядерное ядро, init, древовидная файловая система как таковая вообще, и без транзакций в частности).

Но и это ещё не всё, у них есть Disnix, который продляет эту логику на распределённые системы. Если у вас там какие-то сервисы друг от друга зависят на разных машинах, то оно даже обновлять и перезапускать их в правильном порядке будет. Чёртова магия.

Так вот, последние несколько недель в свободное время я хачил NixOS под свои нужды (как оказалось, там уже почти всё есть, хачил там-сям, по мелочи). Сделал ещё один уровень абстракции над nixos/modules, который из моего описания кластера генерирует отдельные описания всех машин для nixos/modules, а уже из них оно генерирует содержимое корня и всю ту шелуху, без которой юниксы не работают.

Сегодня, собственно, я закончил переводить последнюю машину в кластере на этот магический дистрибутив. На десктопе тут пока Arch, в универе Debian, но, я чувствую, что это ненадолго.

Фотография стенки рядом с центральным сетевым узлом в доме:
фотография двух сетевых свичей и модема
Стамегабитный свич полностью занят, в гигабитный воткнуты только те, кто делают между собой сетевой RAID1. На переднем плане чифтековский корпус одной из машин (6 винчестеров 3.5 + 3 пятидюймовых корзины для приводов, вместо которых тоже винчестеры), на нём внешний eSATA-бокс для винчестеров, не поместившихся внутрь. Между этим корпусом и стенкой стоит ещё одна машина с большим обёмом RAM, но всего двумя корзинами для винтов (я не хотел ещё один большой корпус, ставить некуда). eSATA-box подключён к ней. Также можно видеть зукселевский модем без крышки. На его CPU лежит чайная ложка, на микросхеме, отвечающей за WAN — десертная ложка на термопасте. Летом в них я воду кипячу. Остальные машины раскиданы по дому.

Если бы в моей деревне был нормальный интернет, то все свои хостинговые нужды я обслуживал бы сам :(

Что касается катания по Европе и последствий, то это самое вкусное, оставлю на следующий десерт. А в заголовке другого блога есть моя фотография из Франции, например.
|, me, hikki, ok

Лабораторный тотализм как версия метода контроля над мозгами студентов

Вам никогда не казалось, что традиционный способ подготовки и сдачи лабораторных работ — это ад какой-то?

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

Во-вторых, принимать лабораторные в интерактивном режиме (когда студент сидит под боком) — стресс для обеих сторон. Если что-то не работает, то начинаются всякие fastfixы. Это раздражает. Время оборачиваемости fastfixов не даёт параллельно с принятием лабораторной заниматься чем-то полезным.

Наконец, студентов нужно заставлять приходить в какое-то определённое время и самому тоже заставляться. Обычно я веду себя добросовестнее студентов и прихожу раньше положенного, а когда все опаздывают, очень печалюсь, ибо 40 впустую потраченных минут я всегда мог бы потратить с пользой.
И вообще, тяжело заставить себя делать что-то, если знаешь, что через 30 минут нужно будет начать делать что-то совсем другое, и это совсем другое будет длиться очень долго. Как бы незачем загружать в оперативную память то, что всё равно будет из неё выгружено по мере делания совсем другого.

Барабанная дробь.

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

Вообще, чиста философски, я люблю Git (потому что формат хранения данных очень ня), но Меркуриал выруливает по нескольким причинам:
* его команды cli понятны даже детям;
* можно pushать в удалённые репозитории без головной боли;
* на всяких странных операционных системах не приходится ставить Cygwin.

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

Можно пялиться на историю изменений. Плагиатить код, делая разумную историю, очень тяжело. Читерить, имея за спиной персистентную историю — тоже.

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

Можно править код и делиться патчами с выполняющим лабораторную (доброта mode on).

Можно собирать статистику, рисовать графики, смотреть где у людей возникают проблемы.

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

Можно не до конца специфицировать задание, а потом делать тесты, направленные на выявление неспецифицированного поведения. Два решения ведут себя одинаково на всех неспецифицированных тестах? Не плагиат ли?

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

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

И последнее. Я несколько лет назад делал чудесный конспект по своему предмету, но в процессе меня осенило, что писать очередной невнятный учебник мне не хочется. Предмет в достаточной степени устоялся, чтобы в базовой его части можно было найти приличное количество приличной литературы. Поэтому я написал ровно две лекции:
* про юридические ужасы и лицензии (чтобы попытаться разобраться в этом самому);
* про ABI и линковку (потому что, объективно, про это на русском языке нигде нормально не написано; правда у меня тоже очень хорошо не получилось).
Ещё я хотел было написать про файловые системы и всякие интересные смежные вещи связанные с RAIDами и durability, но интерес как-то поугас.

Поэтому несколько недель назад я решил не прятать от мира своё творение. Желающие могут проследовать на страницу конспекта на github. Там есть все исходники в ТеХе и уже скомпилированные pdfки.

Если у вас есть желание посмеяться над моим пониманием четвёртой части гражданского кодекса или немного просветиться (или снова посмеяться) по поводу Application Binary Interface, различных видов линковок (статическая, динамическая, динамическая линковка статических объектов, etc), релокации кода (PIC, GOT, etc), то милости прошу.
|, me, hikki, ok

Мультиварка на Андроиде

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

Кстати, забавно, купить рисоварку на американском Амазоне, где доставка стоит дороже самой рисоварки, потом купить к ней коробку для переделывания 220 в 110 Вольт в России, а потом ещё переходник с обычной на полярную американскую розетку в Китае, получается дешевле, чем просто купить мультиварку в РФ. Если бы я аккуратнее поискал рисоварку откуда-нибудь из ЕУ, то можно было бы раза в два выйграть. Мне кажется, что это маразм какой-то. Мультиварки в РФ считаются элитной кухонной утварью, да?

Несколько месяцев назад сломался микрофон на моей Нокии 5200. Долго бесил окружающих возможностью общаться только смсками. Купил универсальную (!) гарнитуру для телефонов Nokia. С моим телефоном она работает только как наушники. Вау, ну ок. В порыве отчаяния купил Samsung Galaxy 580. Вот уже месяц не могу заставить себя начать им пользоваться как телефоном, потому что этот девайс явно считает меня за идиота, постоянно держа поднятое соединение по 3G, если воткнуть в него SIM-карту, и передавая все мои действия в ZOG Google. Зато гарнитура от Самсунга прекрасно работает с Нокией. Ад какой-то.

За этот месяц я немного поковырялся в Андроиде и многие вещи меня смешат.

Наблюдение первое. В самом низу у Андроида — Linux. Повыше — библиотеки на C, которые реально работают с железом, звонят, рисуют гуй, хранят базы данных. Потом гугловская виртуальная машина Dalvik. А потом уже весь тот хлам, что пишут простые смертные на Java.

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

Около года назад на лекции, посвящённой DSLям, когда речь зашла о классификации языков на DSLи и не-, я пошутил, что, может быть, однажды, очередная версия CSS станет Тьюринг-полной, позволяя манипулировать цветовыми ячейками произвольным образом, а потому рано отказывать себе в удовольствии называть CSS языком общего назначения. Я пошутил, а вселенная нет.
В HTML5 Canvas нет двойной буферизации и люди для игр на Java Scriptе изобретают велосипеды, частично перерисовывая области канваса. Почему-то мне это отчаянно напоминает конец восьмидесятых. Мир сошёл с ума.

Я люблю тихие девайсы со слабыми ЦПУ, а новый веб-интерфейс Твиттера любит четырёхядерные компьютеры. Постоянная 100% загрузка ЦПУ при пользовании веб-сайтом, с отключёнными глюкавыми плагинами типа flash — это теперь типа нормально, да? Мир сошёл с ума.

Но вернёмся к Андроиду. Очевидно, пользоваться веб-твиттером на телефоне невозможно, а добиться нормального отображения элементов управления любого сайта на экране с таким разрешением — тем более. Что делают разработчики Твиттера, Реддита, СлешДота, etc? Правильно, они выпускают приложение для телефонов, которое просто рисует юзабельный отзывчивый интерфейс на экране, и без лишних извращений с HTML, CSS, JavaScript, AJAXом и прочей веб2.0 хренью. Спрашивается, почему нельзя в обычные браузеры добавить песочницу, исполняющую какой-нибудь LLVM, после чего скомпилировать в этот LLVM какой-нибудь рендер от WebKit и Java Script VM, выбросить рендеринг HTML, CSS и исполнение JavaScript из самого браузера, оставив там только фетчер ресурсов, запрашиваемых песочницами, закладки, историю, рисование гуя и управление превилегиями? URLы даже можно было бы оставить как есть. Будет прямо как всеми любимый Андроид, только в браузерах. Или Андроид — это круто, но в вебе без веб2.0 и AJAX никак нельзя?

Когда я стал рассказывать эту мысль окружающим IRL, общую идею поддержали почти все, но стали холиварить, что вместо LLVMа надо Java-машину, потому что стековые машины рулят и работают везде, а регистровые — это трешак, и типа вообще Андроид рулит. Вопрос номер один: почему тогда в Андроиде Java, но с регистровой виртуальной машиной? Вопрос номер два: почему Java-апплеты не прижились? Вопрос номер три: почему в Java-машине постоянно находят глупые баги, типа переполнений?
Отвечаем. Стековые машины тормозят, интерпретировать их байткод ничем не лучше интерпретации Java Scriptа, для нормальной их работы нужен JIT, все современные компьютеры — регистровые, JIT из стековой VM в регистровую — сложный и багообразующий процесс.

Я считаю, что в Гугле это всё понимают, а API-интерфейс на Java — это просто маркетинг какой-то. Linux и драйвера — не Java. Библиотеки на C — не Java. Dalvik VM — какая-то совсем другая архитектура, а не Java. Транслятор из Java в байткод для Dalvik. Сверху API для Java. 90% системы ничего не знает о Java. Теперь покажем людям оставшиеся 10% и они будут плясать от радости, что можно и дальше киснуть мозгом на Java. Маркетинг ок. Мир сошёл с ума.

Ешё мне интересно, а чего боятся производители телефонов? Дайте мне драйвера от моего Самсунга, чтобы я смог звонить из программы на C и рисовать на экране, и через два месяца мне не нужен будет никакой Андроид, я сам всё нужное мне на Плюсах и Хаскеле напишу. Бред какой-то.
|, me, hikki, ok

Езда на медведях как метод объектно-ориентированного программирования

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

После наболевшего от прожужжанных «паттернами» ушей ехидного предыдущего поста, последовавшего эпического срача в твиттере, поста zahardzhan и приезда сильно увлеченного объектно-ориентированными свистелками иностранного профессора, я даже на несколько дней засомневался в том, что адекватно воспринимаю происходящее, поскольку мои ответы на вопросы «что не так с X?» собеседников не устраивали. Однако, на прошедшей неделе я случайно для себя открыл замечательный метод рассуждений, позволяющий делать забавные умозаключения о современном state of art, и сейчас я немного их сюда повыписываю, стараясь аргументированно указать видимые мною недостатки.

Я бы рад снова начать с «паттернов», но ведь скажут, что я помешанный. Потому начну с (не) биологии. Итак.

С рождения человечества и до девятнадцатого века люди в качестве тяги использовали исключительно лошадей (и собак, а особенно увлечённые ещё и медведей). Однако, с появлением паровозов, а потом и автомобилей, желающих кататься на почтовых становилось всё меньше. Почему? Я думаю, на то три основные причины. Во-первых, даже самые ранние автомобили были сравнимы выходной мощностью с лошадьми (иначе откуда взялись «лошадиные силы»). Во-вторых, вырастить вдвое более быструю кобылу, жрущую втрое меньше сена и не требующую конюха — шансов мало, в то время как прогресс автомобилестроения обещал сделать достижимыми очень высокие планки производительности (а потом и экономичности). И, наконец, автомобиль — куда более предсказуемый в управлении и обслуживании объект, нежели лошадь.

Перестали ли люди ездить на лошадях (собаках, медведях)? Нет (нет, вроде да). Почему? В экстремальных северных условиях собаки ведут себя предсказуемее техники, и по степи, где нет бензоколонок, кататься на лошади приятнее, например. Это объективно. Но ещё бывают всякие адепты натурализма, утверждающие, что удобрять асфальт лошадиными навозом очень полезно для окружающей среды. Я уверен, что и во время переходного периода между лошадьми и автомобилями существовали клубы приверженцев реакционных мнений о том, что автомобили не нужны, а лошадей хватит для всего. Только штука в том, что если один и тот же результат можно получать биологически и автоматически, то второй вариант производственного процесса рано или поздно выигрывает. Что, однако, не мешает существовать кругу добровольных ценителей и кругу вынужденных пользователей «натурального».

Мне кажется, что в программировании наблюдается весьма схожая ситуация. Современный аппарат для доказательства корректности программ дорос до уровня, когда приложив немного усилий на самообразование, можно начать выигрывать на порядки во времени отладки. Число свойств, которые я не могу поручить проверить компилятору, уменьшается чуть ли не ежедневно. Но большинство программистов считает, что доказательства о программах — это к Дейкстре и Хоару, требуют много ручной работы, и там всё равно остаются ошибки (и зачем тогда стараться, да?). А адепты биологического подхода предпочитают все современные достижения просто игнорировать.

Языки, построенные на стековых виртуальных машинах, в этом плане очень показательны. С точки зрения разработчиков на них, авторы языков вроде Haskell и Agda сделали «ужасную» вещь — они отобрали у программиста все его привычные инструменты.

А после стали понемногу добавлять всякие «странные вещи», типа ADT, монад, Typeable, type families и индукцию по структуре (вместо неограниченной рекурсии). «Jonny the programmer» недоволен, как писать программы — непонятно, Джонни чертыхнулся и пошёл дальше писать на дотNet. Но те, кто таки поддался соблазну, внезапно обнаружили, что 80% полезных участков кода даже не требуют Тьюринг-полноты, а 19% из оставшихся не требуют отказа от строгости в типах (например, потому что они вдруг становятся рекурсивными). Да и вообще, плюсы вписывания всего, что только можно, в этот новый базис приятны: о программах можно автоматически (ыц!) рассуждать, можно их автоматически (ыц! ыц!) трансформировать (смотри, например, на трансформацию в векторные операции у Data Parallel Haskell), действительно сложные и неразрешимые вещи (IO и рекурсивные типы, например) можно чудесно изолировать и статически гарантировать эту изоляцию (то есть автоматически (ыц! ыц! ыц!) её проверять). Правда остаётся ещё один процент программ, где нужно очень аккуратно работать с ресурсами, или где всё действительно должно быть Dynamic и типы бесполезны, и обозначенные языки туда (пока?) лучше не совать.

Однако, оказывается, что эти «странные вещи» ещё и позволяют очень просто делать то, что раньше считалось сложным. Тут Джонни начинает крутить головой по сторонам, облизываться и требовать, чтобы и в его любимом языке дотNet появился вывод типов, и анонимные функции, и какие-нибудь монады, и ещё ADT, и ещё континюэйшоны, а теперь хорошо бы ещё и тайпклассы, да, да и это тоже было бы не плохо, и вывод типов (ой, он уже есть, но теперь есть тайпклассы и надо его сделать умнее), о, и ограниченные типы тоже хочу, и ещё нормальную редукцию мне, а не только макросы, и от зависимых типов не откажусь... В итоге, в погоне за упрощением методов выражения ограниченного класса типичных идиом, вместо solidного языка получается каша из фич, надёрганных из разных мест (например, делегаты и анонимные функции в C#).

Но Джонни теперь может в три раза короче описывать парсеры, так какие проблемы? Такие, что, если в язык, в котором было нельзя автоматически рассуждать о программах, добавить штуки, о которых можно автоматически рассуждать, то о языке рассуждать всё равно не получится. В общем, досыпали синтаксического сахара, а польза близка к нулю. Что же делать, если Джонни вдруг понял, что иногда уж очень хочется сбросить на компилятор однообразную работу.
— А! А давайте введём специальный тип модулей, в которых будем использовать только те инструменты о которых можно автоматически рассуждать! — в порыве энтузиазма восклицает Джонни.
— Мистер, ваше предложение означает, что эти модули вы будете писать на Haskell.
— Ой.

«Биология» в программах — это то, от чего хочется избавиться, но, это не значит, что «биология» — всегда плохо. Бывают программы, где выразительности современных систем типов недостаточно (двигатель всё время замерзает) и приходится/проще работать без типов вообще (гонять на собачьих упражках), или нужно очень мудро управлять ресурсами (есть только степь с травой и нет бензина), или, наконец, видимо есть какой-то ментальный барьер, стимулирующий для быстрой и грязной работы выбирать язык с утиной типизацией, а не со строгой. Другое дело, что по асфальту на собаках ездить глупо. И я вообще сомневаюсь, что бывают программы, которые не смогли бы ничего выиграть от доступа к нормальной системе типов. Иначе говоря, я сомневаюсь, что бывают программы, в которых все полезные свойства, которые хотелось бы проверить, неразрешимы.

Итак, если не запомните ничего другого.
* Eсли один и тот же результат можно получать биологически и автоматически, то второй вариант производственного процесса рано или поздно выигрывает.
* «Странные вещи» из функциональных языков хороши не тем, что на них коротко выражаются «паттерны», а тем, что о них можно автоматически рассуждать.
* Добавление этих «странных вещей» в существующие языки ничего полезного в этом аспекте не добавляют, поскольку, как правило, в этих языках уже достаточно мусора, о котором не получается автоматически рассуждать.
* Автоматические рассуждения о программах очень помогают писать хорошие программы. Доказывать корректность программ (в разумных пределах) намного проще и полезнее, чем об этом рассказывают.
* Сплошная «биология» — маразм, но выражать страшные вещи, не лезущие в известные разрешимые системы типов, иногда тоже хочется, потому от неё (пока?) никуда не деться.

А вот теперь снова про «паттерны».Collapse )
|, me, hikki, ok

Паттерны проектирования, гриды и прочая безответственность

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

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

Одним из фактов об этой стране, усвоенным на военных сборах, являлось то, что уйма граждан не может или не хочет даже выполнять своих элементарных служебных обязанностей. В принципе, это можно наблюдать в любом местном отделении какого-нибудь государственного органа, где никто не хочет ни за что отвечать, только целыми днями гоняют чай, а мою посылку из Китая, долетевшую в эту страну оттуда за сутки, «сортируют» на почте уже двадцать четвёртый день. Однако, если тут почти месяц лёжбыща мелкого пакета на складе вызывает народное недовольство, то в армии подобное поведение возведено в норму.
После последнего семинара во мне окончательно укрепилось мнение, что между многими учёными и виданными мной военными не такая уж и большая разница. Сейчас объясню почему.

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

В таком же смысле лямбда-исчисление и теория типов значительно проще, чем объектно-ориентированное программирование и паттерны проектирования. При этом, мне кажется, между первым—третьим и вторым—четвёртым куда больше сходства, чем может показаться на первый взгляд. В каком-то интервью (которое я не смог загуглить) вроде Simon Peyton-Jones говорил, что там, где ООП-кодеры начинают совать UML, хаскелисты расчехляют дополнительные стрелки в типовых аннотациях (вот ещё тред почти про это же на sof). Также и большинство паттернов занимается эмуляцией поведения шашечек из функционального мира (выборочно иду по часто упоминаемым из списка паттернов в Википедии): Adapter — замыкания, Interpreter — GADTs + eval, Listener (тут обман, его в списке в Вики нет) — замыкания, Mediator — ещё раз замыкания, Nullable — пахнет Maybe monad transformer, Proxy — тайпклассы и снова замыкания, Visitor — и тут снова тайпклассы. Ля-ля-ля, все всё давно поняли, а я — Капитан О.

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

В общем, наблюдается ярко выраженная любовь человечества к дисциплинам с огромным количеством мелких деталей, где можно строить из себя умного, вообще по сути ничего не понимая. В этом свете, любовь к преподаванию ООП на всяких «языках, используемых в индустрии», типа там C++, или Java, становится мотивационно оправданной: когда больше нечего сказать, можно пофилософствовать почему условие
(a < b) || (a == b) || (a > b)

для a и b целочисленного типа, может никогда не выполниться.

Надеюсь, я достаточно прямо выразил свою простую мысль: ООП, UML, паттерны и прочая «инженерия ПО» — это (за мелкими исключениями) философия, философия — не математика, программирование — математика. Любовь к такой философии легко объяснить отсутствием достаточного уровня абстрактного мышления, ибо ковыряться в деталях всегда проще, чем построить общую теорию. А работать-то не хочется.

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

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

В заключение хочу отметить, что со времени последних постов, полных уважения к философии, я пришел к выводу, что всякие философы, любители UMLя, паттернов и прочей мути — вовсе не вредны для общества. Смотрите сами, если бы по мгновению волшебной палочки вдруг все фишеры и спамеры исчезли из сети, то люди так расслабились бы, что появление очередного вида мошенничества могло бы вызвать катастрофу глобального масштаба. Философия, РАЕН и ООП с паттернами просто необходимы обществу, чтобы у адекватных его членов не скисли мозги.