Category: литература

Category was added automatically. Read all entries about "литература".

Vash

options = options || {}; или обращение к говнокодерам на JS

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

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

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

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

Set : Set

Наконец-то относительно разобрался с сабжем.
Возьмём некоторую систему типов, в которой
1) типы описывают области определения функций-суждений (_+_ не работает с Tree)
2) можно делать функции, которые работают над всеми суждениями, т.е. Set : Set (для любого P(.) верно, что существуют A и B, такие что P(A) = P(B))
3) суждения = типы
В ней мы можем сформулировать парадокс Жирара и доказать False. Впрочем, я с этой конструкцией так и не разобрался, даже в упрощённом виде. Существует два подхода к тому, чтобы заставить соответствие Карри-Ховарда работать в такой системе. Мартин-Лёф выбросил пункт 2 (т.е. Set : Set), а Коканд выбросил пункт 3, и в CoC верно, что Prop : Prop, но Prop != Set. Так что через Prop : Prop доказать False таки нельзя. Фух.

Список литературы.
http://plato.stanford.edu/entries/type-theory/
http://mathoverflow.net/questions/18089/what-is-the-manner-of-inconsistency-of-girards-paradox-in-martin-lof-type-theory
Vash

Curring in C++

Как просто каррировать функцию на С++ (код): оборачиваем указатель на функцию во враппер, который перегружает оператор применения, который конструирует объект вложенного класса, передавая ему указатель, и у которого перегружен оператор применения, который уже и вызывает оригинальную функцию.

Ну это как-то некрасиво. Нужно сделать это через лямбды (код). Боромир подсказывает, что нельзя так просто взять и узнать, какого типа у лямбды аргументы, и что она там себе возвращает. Сначала нужно уяснить, что лямбда это безымянный класс с перегруженным оператором применения, который ещё и объявлен, как неизменяющий, поэтому тип лямбды нам не скажет ничего, а тип её operator () скажет. Несколько минут брутфорса подсказывают, что есть только один способ правильно взять его тип:
typedef decltype(f) temp;
typedef decltype(&temp::operator()) type;

Подстановка тела temp, отсутствие взятия адреса и прочие мелочи делают код некомпилируемым, но это у меня, видимо, скилла не хватает.

Получив тип, запасаемся оптимизмом, ведь в стандартной библиотеке, в отведённом месте нет и подобия на функции, которые позволят разобрать неизменяющий указатель на метод. Появляется чуток бойлерплейта, который, конечно, нужно вынести в инклюд. Теперь мы можем в С++ писать мономорфные типы из Haskell. Я от радости написал там же ещё и композицию.
Vash

D

Долго собирался, и, наконец, прочитал книгу Александреску. Нет, не ту. Новую. The D Programming Language.

Фабула:
D является чуть меньшим говном, чем С++. Система типов стала чуть проще, синтаксического шума стало чуть меньше.
Vash

(no subject)

Абрамс хитро обошел следующий аспект метапрограммирования в своей книге. Я поделюсь своим решением, а вы, возможно, подскажете что-то более красивое. Пусть функция принимает значения нескольких шаблонных типов (эти типы несут в себе некие данные). В случае, если необходимо вывести ошибку "типы несовместимы" при их несовместимости, что делать? В книге указано два варианта
1) Проверка выведенных типов-аргументов на равенство. Они просто называются одинаково:
template <typename D1, typename D2, typename N>
void f(T<D1, N>, T<D2, N>) { ... }

2) Проверка более сложного условия с помощью typedef с условным boost::static_assert внутри функции. Так как static_assert до сих пор не стандартизирован, большинство компиляторов выводят что-то слабочитаемое.

Мой вариант:
template<typename D, typename N, bool check = true>
struct T { ... };
template <typename D1, typename D2, typename N1, typename N2>
void f(T<D1, N1>, T<D2, N2, compatible<N1, N2>::value>) { ... }

где метапредикатом compatible может быть, по сути, любое выражение.
Кроме того очевидного плюса, что этот код работает, есть минусы:
1) кто-то может воспользоваться этим параметром по умолчанию, что будет, конечно, глупо, но ведь может.
2) мы переложили ответственность за обработку совместимости параметров с функции на тип.

Как заставить этого инвалида работать лучше непонятно.

UPD: [плохой] вариант в духе spirit — локальная переменная некого "правильного" типа, к которой необходимо кастануть параметр(ы), над которой написано "if you see this, the types of args you've supplied into f() are incompatible".