Log in

No account? Create an account

Специализни шаблонца!

Becoming a successful developer

  1. Create a ticket in Chrome's bugtracker asking for a vertical tab list

  2. Wait 2 years for developers to reply

  3. Have a nice day seeing a "wontfix" (because fuck you that's why) in your mailbox one day

  4. Start writing a Chrome App browser that uses <webview> in a nice handy vertical tree tab GUI

  5. (Google breaks "Back" button)

  6. Get a nice message from your RSS feed that Google decided to get rid of Chrome Apps (because fuck you that's why)

  7. (After 3 years of doing nothing Google lowers priority on a feature request that asks to stop script instead of killing a page if it hanged)

  8. ???????

  9. PROFIT!

I'm unsure if I should port the code to Electron. Google may buy Github and close Electron project. Because fuck you that's why, y'know.

Retards strike back
This time Chrome retards turned off "backspace" as "back" button, totally breaking muscle memory for thousands of users, and replaced it with [left alt] + [left arrow] double-handed keystroke. The recommended solution is to have a third-party spyware addon that eats no less than 8 MiB of memory and asks permissions for all the data on all websites. Previously I've been disappointed by these dumb motherfuckers when they declined to add vertical tabs to Chrome, and more than this, it took them several years to reply. Those idiots tell that they know, what they're doing, yet they're not telling, because who the hell we are and why should they explain it to untermensch. That's not even funny. It seems they followed those dumbasses from Firefox team who broke Tree Style Tab several weeks ago while coercing addon devs to sign extensions.

So, please, if you're one of those people that broke all the decent browsers lately and you're reading this, go fuck yourself.
Метки: ,

fmap fmap fmap

Запишите тип выражения fmap fmap ... fmap, где fmap повторяется 10^9 раз.
Метки: ,

Нужен дотнет архитектор в Севастополе

  • Architecture and engineering planning within a variety of disciplines (API specifications, DB Schemas, Feature implementation, System Performance);

  • Jump into an existing complex projects and establish a command of the environment;

  • Work both on the tactical and strategic level initiatives.


  • 8+ years experience in the field of software engineering;

  • Expert in C#/ASP/.NET;

  • Expert in various databases and modeling paradigms (SQL Server 2008, Graph);

  • Deep understanding of web architecture including HTTP, caching, REST & microservices;

  • Expert in common software engineering practices; version control, unit tests, continuous integration & automated deployment;

  • Experience developing and interfacing with APIs;

  • Experience architecting software and system infrastructure;

  • Strong understanding of designing secure systems.

Even better if:

  • Frontend experience with Angular, JQuery & Javascript;

  • Windows domain / active directory experience.

Комментарии скрыты.

ES6 is so ES6
Загадка 1: что выводит этот код?
Загадка 2: почему он это выводит?

var i = f();
function* f() {
    console.log(yield 1);

Ох уж этот common sense

Автор утверждает, что распределённый DNS невозможен, потому что люди не могут одновременно договориться, что что-то правильно, и что кеширование всё почему-то ломает.

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

Ещё немного деревьев Меркла и прочей оптимизации, и, вуаля, P2P DNS.

Oh my god

def replicateM(n, xs) {
    let res = [];
    for (let i = 0; i < n; ++i) {
        push(res, bind xs);
    wrap res;

print(replicateM(2, [1, 2, 3]);

// [[1, 1], [1, 2], [1, 3],
//  [2, 1], [2, 2], [2, 3],
//  [3, 1], [3, 2], [3, 3]]



How to install React from master
It's just as simple as
git clone https://github.com/facebook/react.git
cd react
npm install -g grunt-cli
npm install
grunt build
cd build\packages\react
npm link
cd ..\react-dom
npm link
npm link react
npm link react
npm link react-dom

Как разработать свой 3D-принтер
3D-принтер должен содержать

  • Напечатанные на 3D-принтере запчасти, невоспроизводимые с помощью пилы и сверла;

  • Метрические метизы;

  • Имперские метизы;

  • Продукцию с кикстартера с тиражом менее 1000 экземпляров;

  • Мерзко жужжащий вентилятор;

  • Прецизионные NEMA17 шаговые двигатели и корпус из экструдированного алюминия, собираемые вместе эпоксидкой;

  • Зубчатые ленты;

  • Кусок фанеры, нарезанной лазером;

  • Ардуино с экранчиком;

  • Набор независимой от него самостоятельной электроники в 4 экземплярах;

  • Дух опенсорсности;

  • Драйверы шаговиков, произведённые, по словам старожилов, в Южной Корее с 1943 по 1945 год.

С днём Великой Октябрьской социалистической революции

Screw Scala
Development in C++ seemed OK while I knew nothing about path-dependent types. I've just been writing a parser that would be 10x more simple with PD-types and realized there's no way even to emulate some.

UPD. I've just got terrorized by the fact that I don't even need path-dependent types. There are places where C++ is not type safe through all the sorts of compile-time magic I've put into that program. Java-style child classes would be enough. I don't even see a way child classes are incompatible to "zero overhead" rule. Gosh, there's something in Java that is not disgusting after all.

For all the interested among the readers, here's a description of the use case. Write a PEG-parser combinator language in C++ that is optimized by having primitives implemented via CRTP. Avoid passing end iterator of the parsed range through all the combinators.

What do I do when there's no STL algorithm I need

  1. template <class NeedleIterator, class HaystackIterator>

  2. bool equals_zip(

  3.  NeedleIterator needle_begin, NeedleIterator needle_end,

  4.  HaystackIterator haystack_begin, HaystackIterator haystack_end

  5. ) {

  6.  while (needle_begin != needle_end) {

  7.    if (haystack_begin == haystack_end)

  8.      return false;

  9.    if (!(*needle_begin == *haystack_begin))

  10.      return false;

  11.    ++needle_begin;

  12.    ++haystack_begin;

  13.  }

  14.  return true;

  15. }

Увидел Nim
Слёзы счастья. Ещё бы GC было легче отключать.

Как натолкнуть косу на камень
Bitcoin хранит всю историю транзакций в блокчейне. Персистентность блокчейна -- одно из базовых свойств технологии. Любой человек может провести транзакции, и любой человек может проверить, что таковые действительно произошли.

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

1. Лол, ну попробуйте теперь их оттуда убрать.
2. Ну давайте, признайте теперь биткойн экстремистской технологией.

UPD. Конечно же, я не первый человек, которому эта идея пришла в голову.
UPD. Даже уже написали!

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

Отрывочно про веб
Добрый вечер+03:00, дорогой читатель. Сегодня я хотел бы поговорить про веб-разработку.

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

Все, наверное, слышали, про такую игру как испорченный телефон. Она описывает именно то социологическое явление, когда изначально правдоподобные данные становятся абсурдно не похожи на оригинал в процессе передачи информации по цепочке людей. А вы слышали доклад Уильяма Танниклифа в Канадской государственной типографии в 1967 году? Я вот не слышал, и даже не смог найти стенограмму. Но почему-то считается, что именно Танниклиф был первым, кто сформулировал принцип разделения представления и содержимого, используемый сейчас для того, чтобы оправдать разделение HTML и CSS.

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

За него отвечал бы XML, если бы веб вовремя перешёл на XSLT. Да, сейчас ещё есть следы от начала развития XML в вебе: есть XHTML, есть processing instruction xml-stylesheet. Проблема в том, что из JS на странице оригинальный XML стандартным образом получить уже нельзя. Скорее всего, такой подход исключил бы необходимость во всех этих MV*-фреймворках, которыми пестрит веб. "Скорее всего" потому что XSLT Тьюринг-полон, и многие вещи, которые бы мы ожидали видеть происходящими автоматически, вроде сохранения фокуса на input при обновлении XML-DOM, уже не были бы доступны. Всегда можно было бы сделать well-behaved подмножество, но в этом направлении все полимеры уже просраны.

Сейчас я бы мог верстать практически все страницы, используя только div и ещё несколько тегов, всё остальное бы лежало в CSS. Осталось бы некоторое дерево, которое можно было бы считать отвечающим некой реальной структуре данных, представляемых страницой. Но некоторые из этих div мне пришлось бы написать только из-за того, что в CSS просто пока что нет нужных селекторов или свойств. Борьба комитета стандартизации с попыткой вводить ещё больше селекторов и свойств напоминает рыбака, активно черпающего воду из своей прохудившейся лодки. Ничто не сможет исправить тот факт, что CSS это не нормальный Тьюринг-полный язык.

Кстати, даже несмотря на то, что широко распространено мнение, что CSS не Тьюринг-полон, это, скорее всего, не так. Учитывая, что даже крайне простые вещи вроде Rule 110 полны, представляется крайне сомнительным, что в CSS с жирной как тюлень спекой нельзя найти хоть какой-нибудь вычислительный контекст. Комитет стандартизации явно и недвусмыслено с этим борется, конечно, поэтому я потратил добрых 16 часов на поиск такового контекста, подготавливая материал для этого поста, но так и не смог привести рабочий пример. Где-то так же обстоит ситуация с тем, что комитет стандартизации С++ явно пытался сделать так, чтобы порядок объявлений не влиял на семантику программы, но нихрена у них не получилось. Даже частные члены класса можно без всякого undefined behavior воровать. Впрочем, вот, как обстоят дела.

CSS явно сделан так, чтобы пройтись по списку всех правил один раз, не возвращаясь обратно. Типичная идея well-founded recursion. Проблема в том, что это относится только к ядру языка.

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

  • Во-вторых, мы можем воспользоваться селектором focus. Если исчезает поле, на котором стоит фокус, то он переходит к следующему полю, и стили пересчитываются. Если возможно сделать так, чтобы focus циклически перемещался по набору полей, до Тьюринг-полноты рукой подать. Этот подход заработал не так хорошо, как мне бы хотелось, потому что в разных браузерах работал по разному. В Chrome все поля теряли фокус, а в Firefox фокус с точки зрения CSS стоял на невыделенном поле. Разобраться, как это должно работать, я так и не смог. Может, кто-то из вас осилит этот собачий бред.

  • В-третьих, state можно сохранять с помощью hover. Мы просто делаем так, что элемент, на котором сейчас стоит hover, скрывается с глаз долой, и попутно это тянет появление другого элемента, у которого тоже обрабатывается hover. Возможно, это не работает, поскольку текущий элемент под hover'ом это состояние нашей программы, а это количество конечно и зависит от того, сколько элементов у нас есть в исходнике. Но точно это хорошо работать не будет, потому что авторы браузеров решили оградить эпилептиков от говнодизайнеров, у которых на страницах в связи с hover появляется мерцание. (В этом примере попробуйте подвести курсор справа к тексту. Если у вас нет эпилепсии, конечно.) Фикс заключается в том, что hover не пересчитывается, если курсор не движется.

  • Наконец, есть media query, которые позволяют получить ширину окна. Засовывая media query внутрь iframe мы можем получить размер обрамляющего элемента, а это означает, что у нас появляется возможность зависеть от результата вычислений CSS наружного документа. Если при этом возможно было бы настроить потенциально бесконечное количество вложенных iframe, то мы получили бы Тьюринг-полноту. Впрочем, этот подход станет намного ближе, когда появятся element query.

Подводя итог: и почему нельзя было бы просто сделать нормальный язык программирования?

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

  • А что, HTML не переиспользуется?

  • А что, если бы язык был один, то часть определений нельзя было бы закешировать?

Обычно после этих двух вопросов этот аргумент отпадает. Остаётся ещё один, относительно более серьёзный: так что мне, повторять style на каждом элементе, как это делалось в раннем вебе (cellspacing помните)?

А почему бы и нет? Давайте писать стиль на самом элементе. Вас не устраивает, что стили будут встречаться более одного раза? Code reuse падает? А что обычно делают люди, чтобы с этим бороться? Вводят бесчисленные селекторы? Или, может, всё-таки переменные, функции и, на худой конец, классы? Функции в случае HTML представить себе очень просто: все серьёзные веб-разработчики так или иначе уже пользуются шаблонами.

Что вы там раньше использовали, миксины в SASS/SCSS? Не напоминает наследование? Не напоминает про ФВП? Так зачем городить дополнительные абстракции, если всё делается старыми добрыми приёмами императивного и функционального программирования?

JS, конечно, тоже бесит. Этот ублюдок Эйха имеет ровно одну положительную сторону: красивый способ работы с событиями. Всё остальное там омерзительно: и коэрции с перегрузками, и прототипное наследование с return в конструкторах, где нельзя сделать прототип функционального объекта, кроме как стандартный Function, и где не работает нормально typeof, который вообще хорошему языку не нужен был бы. Оптимизации хвостовых вызовов нет. Зато есть JIT, работу которого понимают только разработчики, а почти все остальные программисты, даже из команды Google Closure, продолжают настаивать, что это панацея, и что JIT волшебно решит неразрешимую задачу и оптимизирует любой код.

Бесит то, что вообще что-то нужно писать. Я, например, люблю сидеть за компьютером ночью в тёмной комнате. Сейчас так и делаю, кстати. И вот, передо мной интерфейс ЖЖ с чистым белым фоном, освещающий всю чёртову комнату. Ребята, мне глаза режет. Что, прикажете каждому сайту имплементить систему смены фона?

Подобного рода проблемы решались и ранее. В Windows почти все кнопки, независимо от программы, рисуются одинаково, и это зависит от темы. Строки вроде "OK" и "Отмена" в текущей локализации прописаны в user32. Короче говоря, программе позволяют избавиться от того, что можно настроить и общесистемно.

Почему же тогда сайты не начнут отдавать просто API? Уже просто по описанию функций, которые доступны в API, легко понять, как это должно выглядеть в интерфейсе. Для сложных сайтов можно добавить какие-нибудь легковесные рекомендации по их выводу. Ответов два:

Во-первых, до сих пор нет нормального стандарта на веб-API. REST крайне тяжеловесен и не позволяет делать вызовы с сервера на клиент. WebSocket ничего не говорит про формат отдельного пакета (хотя уже моменты вроде binary/text формата сообщения говорят, что WS это дерьмо, но об этом дальше). Хорошо работает связка WebSocket + ProtoBuf, правда, формат сообщений всё равно приходится описывать. Правильно это выглядело бы просто как одно общее приложение, где лежит код клиента и сервера, и где компилятор сам придумывает всю логику позади вызова c клиента метода, определённого на сервере, и наоборот. Для этого нужно, чтобы клиент и сервер были написаны на одном языке, а генератору нужна статическая типизация. Cерверный JS уже есть, статическую типизацию, наверное, может дать TypeScript.

Во-вторых, уже есть попытки делать что-то подобное. Все хотят пострелять по лягушкам в Германии лазером из космоса со спутника, создавая микроформаты, RSS/Atom, semantic web, pubsubhubbub, OpenID и прочие микроскопически частные способы делиться чем-нибудь относительно структурированным, не замечая леса за деревьями.

Отдельно хотелось бы поговорить про существующие протоколы. Вот вы читаете этот текст. Вы читаете его в исходном виде, или это уже его представление? Вы ведь не можете воспринимать напрямую номера символов, так? Любой текст на компьютере это представление данных в человекочитаемом виде. Тогда объясните, почему у протоколов вроде HTTP тот факт, что они обмениваются "человекочитаемым" текстом, вызывает предоргазменное состояние у их разработчиков? А сделать GUI поумнее нельзя? Ну ладно, вы можете утверждать, что текстового редактора вам достаточно. Ну сделайте стандартный редактор деревьев или стандартизируйте наконец-то формат описания протоколов, чтобы редактор мог подтянуть из файла или сети биекцию бинарного представления и текста, в чём проблема?

Отдельно гадок сам HTTP. Всем известен принцип single responsibility. Почему тогда HTTP занимается запросом страниц, отправкой данных, хранением персистентного состояния на клиенте (cookie), авторизацией, перенаправлениями, отчётами об ошибках всех сортов и ещё кучей всякого дерьма, полное описание которого даже в один RFC не влезло (7230-7237)? Изначально этот протокол вообще должен был использоваться для того, чтобы можно было редактировать страницы веба напрямую в браузере, что потом напрочь забыли, а недавно присунули какой-то нерабочий contentEditable взамен.

Не понятно вообще, зачем делать всякие URL и e-mail текстом, и потом морочиться с его разбором (ой, нерегулярный язык!), если можно это было сделать деревом, и потом его автоматически (де)сериализовать.

Анонимность, криптографические подписи и P2P тоже должны входить в состав новых стандартов веба.

Я вижу только один выход из сложившейся ситуации.

  1. Всё это говно полностью отправляется на помойку.

  2. W3C бойкотируется.

  3. Стандарты начинают разрабатываться с использованием научного метода.

  4. В первую очередь решается, как сделать так, чтобы никакие решения не уходили в legacy. ProtoBuf показывает хороший пример.

  5. В качестве основных языков веба вводятся байткод с содержимым по типу LLVM и статический язык программирования без небезопасных конструкций, но и без GC, JIT и прочих тормозов. В первый компилируются другие ЯП, которые люди хотели бы использовать для веба, второй используется по умолчанию.

  6. Программам на этом языке выдаются разнообразные API, в первую очередь -- canvas, заменяющий HTML.

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

  8. Для существующих браузеров предоставляются расширения, позволяющие ходить в новый веб.

  9. Если кто-то не хочет расширения, тому выдаётся HTML с Asm.js, полученный в результате компиляции чем-то вроде Emscripten.

Правила манглинга в GCC

10x triampurum

Наконец-то я знаю, как можно сделать реманглер.

Короче, в Node.js поломали уже два встроенных пакета, https и fs (конкретнее, watch). Я думал, что в 0.12 станет как-то сурово лучше, даже несмотря на то, что авторы ноды пеняют на libuv, а libuv говорит только, что пулреквестам будет рад. Ребята, какие, к чёрту, пул реквесты, если это у вас регрессии, а у вас даже регрессионного тестирования нет?

Вот, казалось бы, что может быть проще, когда у вас есть целый npm под рукой: сделать регрессионное тестирование. Ломаете https? Ну скачайте хотя бы самые популярные пакеты, которые юзают https, прогоните в них тесты на старом и на новом коде. Если раньше работало, а теперь нет, то у вас руки из жопы. Всё.

Я, допустим, не хочу работать с JS без генераторов. Генераторы + промисы = нормальная работа с колбеками. Регенератор для серверных исходников мне тоже что-то не очень хочется использовать, потому что билдить серверные сырцы, включая скрипты для билда, это уже перебор.

Появление io.js у меня вызывало ранее некоторое удивление, поскольку ничего не предвещало. Я же сейчас попробовал позапускать код на io.js, и там fs.watch и https работают, как положено. Короче, время валить туда.

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

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

Овощи и фрукты и без того вкусные. Ешьте их сырыми.

NB. Я таки люблю мясо.

Ну ладно, я тоже
В ответ на новую политику "ЖЖ" настоящим я объявляю, что все мои персональные данные, фотографии, рисунки, переписка и так далее, являются объектами моего авторского права (согласно Бернской Конвенции). Для коммерческого использования всех вышеупомянутых объектов авторского права в каждом конкретном случае необходимо мое письменное разрешение.
"ЖЖ" теперь является публичной компанией. Именно поэтому всем пользователям данной социальной сети рекомендуется разместить на своих страницах подобное «уведомление приватности», в противном случае (если уведомление не опубликовано на странице хотя бы однажды), вы автоматически разрешаете любое использование данных с вашей страницы, ваших фотографий и информации, опубликованной в сообщениях на стене вашей страницы.
Каждый, кто читает этот текст, может скопировать его на свою стену в "ЖЖ". После этого вы будете находиться под защитой законов об авторском праве. Этот коммюнике оповещает "ЖЖ" о том, что разглашение, копирование, распространение моей личной информации в коммерческих целях или любые другие противоправные действия по отношению к моему профилю в социальной сети строго запрещены. Некоммерческое использование и копирование моих фотографий, произведений и других записей разрешаю безусловно, с обязательным указанием авторства.

HOAS + data type a la carte
Я попытался собрать a la carte тип для значений интерпретатора лямбда-исчисления. Так как в лямбда-исчислении бывают функции-значения, мне понадобилось определить

data VFun e = VFun (e -> e)

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

Это ведь синтаксическая причина. А мне интересно, в чём причина семантическая: какого именно дьявола призывают HOAS, что я не могу собрать катаморфизм для такого типа? Я не вижу никаких реальных семантических проблем в том, чтобы пройтись по AST в HOAS-форме и что-то от такого AST посчитать. Товарищи, посоветуйте, пожалуйста.

Про динамику и статику
Только что решил одну простую задачу на Python и Haskell с целью сравнения динамической и статической типизации в функциональных языках. Есть последовательность чисел, в которой сначала один раз записывается единица, два раза двойка и так далее. Нужно получить первые N элементов этой последовательности.

  1. import Data.List

  2. main = interact $ intercalate " " . map show . flip take (concat $ map (\x -> replicate x x) [1..]) . read

  1. from itertools import *

  2. print(' '.join(islice(chain.from_iterable(map((lambda x: repeat(str(x), x)), count())), 0, int(input()))))

(EDIT. Для C++ oneliner тоже приведу, конечно.)

  1. #include <iostream>

  2. int main() { int N; std::cin >> N; if (N--) std::cout << '1'; for (int i = 2; ; ++i) { for (int j = 0; j < i; ++j) { if (!N--) return 0; std::cout << ' ' << i; } } }

Если присмотреться, то станет заметно, что на Python решение получилось на 7 символов длиннее. Учитывая, что авторам Python для этого пришлось прыгать через хулахуп, придумывая новые названия функциям над генераторами, и что найти нужную функцию уже не так просто, я закрываю в своём ЖЖ тему о динамической типизации раз и навсегда. Удачного дня.


10x triampurum

Тов. Лавсан опять в ударе
Третья Теорема Лавсана (о бесполезности статической типизации)
Статическая типизация не добавляет ничего действительно полезного и только лишь отбирает время.
via LOR

Первый Принцип Пиздежа: выдавай гипотезу за теорему.

Тов. Лавсан опять затрудняется прочесть хотя бы базовую литературу по теме, в которой пытается выступать в роли эксперта. Типы нужны для того, чтобы доказать отсутствие определённых типов нежелательного поведения, что явно не похоже на "ничего". Механизм отбора времени у трудящихся не описан.

C праздником!
Поздравляю вас с ещё одной годовщиной того светлого дня, когда великая коммунистическая идея сменила беспросветную монархическую глупость. Ура, товарищи!

Знакомые лица
И тут я такой имплеменчу Хиндли-Милнера в императивном языке, лезу на цстеорию


А там nponeccop. Мог бы сразу у него спросить.

Ждите новостей

9 лет всё та же самая история
template <class T, T ptr>
struct make_call {
    static const size_t init_size = 128;
    template <class... U>
    wstring operator() (U... args) {
        size_t curr_size = init_size;
        wstring res(curr_size, L'X');
        decltype(ptr(args..., &res[0], curr_size)) ret_size;
        while ((ret_size = ptr(args..., &res[0], curr_size)) + 1 == curr_size) {
            curr_size *= 2;
        return res.substr(0, ret_size);
auto GetProcessImageFileNameX = make_call<decltype(GetProcessImageFileNameA), GetProcessImageFileNameA>();
>> fatal error C1001: An internal error has occurred in the compiler.

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

Оригинал взят у __diogen__ в Товарищи попросили составить опросник для программистов на C#
Я, естественно, не стал отказывать хорошим людям.
ВуаляСвернуть )

options = options || {}; или обращение к говнокодерам на JS
Давайте поговорим про джаваскрипт. А точнее, про омерзительную традицию, которая лезет во все библиотеки npm из тормозного насквозь jQuery: про передачу аргументов ассоциативным массивом.

Ребята, зачем так делать? Я понимаю, что упоротые по никсам программисты не получают никакого когнитивного диссонанса, говоря про unix way и single responsibility, делая программы с туевой хучей аргументов командной строки, и потом пытаясь через man man понять, как ими пользоваться, через history вспомнить, как это, блядь, делалось, и через лишний пробел в rm почистить себе весь диск. Но должны же быть адекватные люди, да?

Ребята, этот подход не модульный. Вы никогда не вынесете в опции всё, что мне хотелось бы пофиксить внутри вашей убогой библиотеки. Зачем, зачем вы продолжаете это делать? У вашего кода слишком маленький memory footprint? Он слишком мало тормозит? JIT слишком хорошо понимает, как убрать оттуда весь дохлый код, которого у вас там 90% для отдельного применения либы?

Ботайте, блин, Хаскелл, делайте комбинаторы, экспозьте API из элементарных запчастей, пусть пользователь собирает.

Как заставить node-gyp таки работать
Node.js использует для модулей, написанных на С++, ублюдочный пакет под названием node-gyp. Ублюдочный он потому, что авторам глубоко посрать на все операционные системы, кроме их любимой убунты.

Ни разу не видел, чтобы node-gyp заработал под виндой с первого раза. Три самых частых его бага:

1. Переменной окружения PYTHON не должно быть. Она по дефолту ссылается папку с Python, node-gyp от этой наглости входит в ступор и вылетает. Зачем ему питон, спросите вы? Да потому что ублюдок джаваскрипта и С++ просто обязан внутри использовать скрипты на тормозном питоне. (Посмотрите, например, на билд-скрипты Google Closure.)
Проверка: %PYTHON% в cmd должен говорить, что такой переменной нет.
Как исправить: set PYTHON= (и ничего после знака равно) перед тем, как вы будете делать npm install <пакет>.

2. Если у вас, не дай боже, что-то кроме iso-8859-1 в имени пользователя, то node-gyp работать не может, потому что они не умеют работать с юникодом. Переименовать пользователя будет недостаточно, потому что папка пользователя, в которой Node.js хранит настройки, будет называться всё так же. Создайте нового пользователя, убедитесь, что ваше VPN-подключение к Интернет расшарено на всех пользователей, и делайте действия оттуда. Ну или подправьте имя папки в реестре и на диске руками, на свой страх и риск.

3. Если у вас стояло много версий Visual Studio, и зачем-то одну из них удалили, то есть шанс, что node-gyp попытается откомпилировать именно ей. Подотрите остатки от студии и удалите соответствующую переменную окружения VSxxCOMNTOOLS.

Если всё это не помогло, то вы внимательно читаете логи, смотрите, какой конкретно пакет node-gyp не сумел скомпилировать, качаете его исходники в отдельную папочку npm'ом, правите, делаете npm link из этой папки. Теперь возвращаетесь на то место, где должен быть этот пакет в устанавливаемом, делаете оттуда npm link <имя пакета>, и всё!

И да, если ваc это достало так же, как и меня, напишите этим дебилам, что они дебилы.

External annotations in Java
Сегодня рассказывал коллегам, что аннотации неплохо было бы выносить отдельно, потому что когда одна либа требует от классов другой либы аннотаций, которых там нет, юзер из своего кода сделать так-то ничего не может. Спустя пару часов коллега ответил вот этой ссылкой


Дата выпуска 1 августа 2014. Я на джаве писал где-то недели две.

Это мне напоминает статистику по тому, как психологи отвечают на профессиональные вопросы, показывая на 14% лучшие результаты, чем непсихологи. Автор там как бы намекает нам, что с сопроматом это уже не прокатило бы.

Там что-то не так с датой или профессиональные джависты не нужны?

Представьте себе следующую ситуацию. Вы качаете два файла, размером в 100 и 200 мегабайт. Процесс загрузки начался одновременно. Оба сервера способны отдавать файлы с большей скоростью, чем позволяет ваше Интернет-соединение. Поэтому ваши 2 мегабайта в секунду соединения делятся поровну, и для первого файла ожидаемое время закачки вычисляется в 100 секунд, а для второго -- в 200. Но вы, конечно же, понимаете, что это неправда, поскольку первый файл скачается через 100 секунд, и вторая загрузка полностью потребит ваше соединение, закончившись через 150 секунд, а не через 200, как предполагалось. Мы, конечно, понимаем, что за счёт всякой турбулентности говнософта и говножелеза на вашем компьютере никакого точного времени закачки мы получить не можем, и поэтому обычно кладём что-нибудь большое на эти 50 секунд разницы.

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

Объясняя тут гугловским разработчикам в публичном мейллисте, почему JIT не панацея, и если у них баг, то его нужно пофиксить, а не ожидать, что JIT всё разрулит, я понял, что что-то здесь не так.

Вопрос про расширяемые парсеры
Под расширяемостью я буду подразумевать, что

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

  2. множество генерируемых (или принимаемых) строк новой грамматики включает в себя множество генерируемых строк старой,

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

Есть, допустим, у нас следующая грамматика (псевдокод):
g1 {
    r1 = r2*
    r2 = "a" | "b"
Мы хотим создать новую грамматику, используя дополнение по оператору выбора
g2 extends g1 {
    r2 = ... | "c"
Очевидно, g2 расширяет g1, потому что она так же принимает все строки из а и b, но теперь ещё и позволяет c.
Однако, дополнение по оператору выбора позволяет сделать и следующее:
g3 extends g1 {
    r2 = ... | "ab"
Теперь п.3 не исполняется, потому что вместо отдельных совпадений с "a" и "b" мы получаем совпадение с "ab".

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

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

VS2013 Update2 FTW
template <class> struct Z {};
struct B : Z
<int> {};
struct C : B, Z<int> {};
void f(Z<int> const &) {}
int main() { f(C()); }

Clang: ambiguous conversion from derived class 'C' to base class 'Z':
GCC: ‘Z’ is an ambiguous base of ‘C’
Visual Studio 2013:

Пару лет назад собрал себе тихий компьютер с радиатором на ЦПУ. Каждое лето я получаю BSODы от перегрева оперативки. Нормально отладить эту проблему я не могу. Нужна ИК-камера, чтобы понять, кто греет оперативку. Мораль: сборка IBM PC-совместимых компьютеров с повышением их энергопотребления перестала быть задачей для гаража.

Авторы Google Chrome потрясли меня сегодня своим интеллектом, последовав пути IE, и воткнув в обход W3C крайне раздражающую фичу в виде XSS Auditor. Я использую сервак с закрытыми исходниками, который ажаксом подтягивает код со скриптом, и где я не могу воткнуть нестандартный заголовок. Теперь у меня не работают скрипты. Спасибо, Google.

Пришлось адский воркараунд совать, добавляя скрипты картинками, и засовывая CSS внутрь JS.

UPD Олимпиадный привет ЛГБТ-движению весьма ясно даёт понять, почему всё так. Потому что пидарасы.

jQuery vs Google Closure
function select(elem, f) {
    elem.toggleClass('tab-selected', f);
    $('#' + elem.data('link')).toggle(f);

$('.tab-button').each(function () {
    select($(this), $(this).hasClass('tab-selected'));
    $(this).click(function () {
        select($(this).closest('.tab-header').find('.tab-selected'), false);
        select($(this), true);

Google Closure:
function select(elem, f) {
  goog.dom.classes.enable(elem, 'tab-selected', f);
  goog.style.showElement(goog.dom.getElement(goog.dom.dataset.get(elem, 'link')), f);

goog.array.forEach(goog.dom.getElementsByClass('tab-button'), function (cmdTab) {
  select(cmdTab, goog.dom.classes.has(cmdTab, 'tab-selected'));
  goog.events.listen(cmdTab, goog.events.EventType.CLICK, function () {
    goog.array.forEach(goog.dom.getElementsByClass('tab-selected'), function (cmdCurrTab) { select(cmdCurrTab, false); });
    select(cmdTab, true);

Несмотря на то, что я категорически не согласен с известной явно проплаченной статьёй, где автор пытается двумя с половиной багами доказать, что Closure трогать не стоит, и jQuery так-то ещё то говно, но всё же не стоит.

UPD. Собсно, мне прояснили, что http://jsperf.com/google-closure-vs-jquery-dom/3

Руки крюки

И у меня тоже.

Туда и обратно
#include <iostream>
#include <vector>
#include <string>
#include <iterator>
#include <algorithm>
using namespace std;

template <typename T> istream & operator >> (istream & i, back_insert_iterator<T> & b) {
    typename T::value_type x; if (i >> x) b = x; return i;

int main() {
    vector<string> w; while (cin >> *back_inserter(w));
    copy(begin(w), end(w), ostream_iterator<string>(cout, " "));

А можно просто банить всех, у кого не 0?
Оригинал взят у wizzard0 в Срачиометр
Оригинал взят у dargot в Вынесу-ка из комментов:


В ЖЖшечке давно пора заставить всех принудительно анкету заполнять, пунктов эдак из ста, оценивая свою позицию в баллах (2,1,0,-1,-2) по шкалам:

Политический раздел:
За СССР / Против совков
За национал-социализм / Против нациков
За демократию / Против дерьмократов
За либерализм / Против либерастов

Национальный раздел:
За евреев / Против жидов
За кавказцев / Против чурок
За украинцев / Против хохлов
За русских / Против москалей

Половой вопрос:
За геев / Против п.доров
За женщин / Против баб
За мужчин / Против мужиков

Ну и так далее, по всем дисциплинам Специальной Олимпиады - легалайз, курение, собаки, автомобили, чайлдфри, аборты, копирайт, линукс, прививки...

И результаты, соответственно, показывать при наведении курсора на юзерпик - "СО-Профиль пользователя совпадает с Вашим на 72%, основные отличия - по гееп.дорской (2 балла против Ваших -2) и женобабской шкалам (-2 балла против Ваших 1) шкалам." Сразу ясно - стоит ли на человека вообще тратить время, какие темы с ним лучше не обсуждать, как его троллить.

Прошу считать данный пост официальной просьбой администрации ЖЖ:D

С уважением, Dargot.

P.S. Update. А еще лучше будет прикрутить спец.алгоритм, который по употребляемой лексике и адресатам сообщений пользователя будет проставлять ему этот рейтинг автоматически. "Вам присвоен рейтинг геезащитника", так как-то. Особые лулзы доставит сравнение СО-Профиля пользователя по его представлениям и автоматически вычисляемого:)

There's is an amount of sources stating there's an industry-wide movement into "semantisation" of Web. I'd like to tell you (in case you don't know it yet) that's just a blatant lie.

Consider HTML. There's a shameful mix of makeup elements (div, span, i, b, pre, em, strong, p), semantic elements (kbd), user controls (input) and information about how to process actions (form, label). There's no certainity at all on what does it mean to write a tag. In case one would like to go really sematic, it could be done in the following way (keeping as much existing infrastructure as possible). Common web page is just an XML with only the data that are significant for that page. It has xml-stylesheet processing instruction. Linked XSLT contains several (intersecting) levels of mapping of those data into low-level makeup. CSS, ids and classes should never show at any stage of desugaring. The possible levels are (in order of increasing level)

  1. Give browser instructions to show the page and make UI (tag: span, screen, article, grid, row, cell, padding, spring, ellipsis; attr: link, xlink).

  2. Tell what kind of information is shown (kbd, paragraph, sentence, term, em, header, list, person).

  3. Tell what kind of UI is shown (spoiler, splitter, tree, datagrid, editor, toolbar, navbar).

There's just no way to create a Semantic Web until we don't start writing it in a consistent semantic way.

The problem of this approach is that one has to somehow manage dynamic content on page, while exposed DOM is the one of the already transformed XML. There was some movement towards standardisation of DOM access to the source XML, but it haven't got enough support.

In case we would ever be ready to forget all that HTML/CSS/JS stuff as a nightmare, there are even better approaches. We could finally make web based on extensible binary protocols (like protobuf). It would solve all the problems of minification: there wouldn't be a single name of CSS class, space character in HTML or identifier in JS.

It's easy to intercept page loads
While looking for a way to make an addon for better web experience, I found these articles:


So, I can stop the page from loading even before it actually makes any HTTP request. For example, instead of Yandex front page (213,8 KiB) I can show prepared input field, which loads in approx. 0 seconds, and takes 0 bytes of traffic. These're the good news, aren't they?

A month with Ubuntu
(and several more, which I'm not set to gather into this link dump)

Holy. Fuck.

TIL that Ubuntu 13.10 is not a target for GHC. There's just no way to install it without removing half of the system libraries. At least, no easy way. Though I've successfully installed it in a few clicks via Haskell Platform in a Windows under VM. So, beware: there're potentailly only 3 good Linux distribs: NixOS, ArchLinux, Gentoo. It's damn right time to check these out.

Lambda methods
There's an annoying problem in PHP, JS and other languages with OOP and lambda functions: this keyword in a lambda defined in some method. Lambda function's scope differs from method's scope: there's just no this. Even worse, methods and fields may be declared private in PHP, so if we somehow pass this into lambda function, we still won't be able to access those fields and methods. I suppose the most significant reason for this is that methods are not just functions, and using function keyword for them is a misnomer. Methods are functions with one more implicit parameter named this (in C++ world it's called "thiscall" calling convention).

So why don't we call them method etc.? Then if we saw
class Test {
    private $x;
    method f() {
        return g(method() {
            return $this->x;

we would be sure that lambda method took the same this as its enclosing method, and the problem would disappear. In case of Javascript, library authors (e.g. Google) wouldn't have to create optional arguments to take something that would be substituted as this for callback function.

There's something wrong with our industry if we don't see it.

Tabs Outliner я собирался написать сам, а он уже, оказывается, написан.

Суть в том, что это не просто древовидные вкладки в браузере, это ещё и нотесы, где можно сохранить ссылки, доки или кусок текста.