thedeemon: (psychosis)
Пользуясь википедией в качестве словаря, можно узнать, что "closet" по-русски будет "Осиирэ"!
thedeemon: (office)
Сегодня утром:


Краска была из йогурта с пищевым красителем, никто не пострадал. :)
thedeemon: (psychosis)
И там уже n-категории да топосы.

Куда только власти смотрют!
thedeemon: (office)
Давно заметил, что если нужно перевести слово, вместо рыскания по словарям, дающим сразу десяток значений, часто самый адекватный перевод получается, если открыть по этому слову страницу в википедии и посмотреть, как называется эта страница на русском.



Сейчас сделал себе из этого консольный переводчик. Теперь могу в консоли так делать:
>ru meerkat
Сурикат

>ru sodium
Натрий

Вот весь исходник с парой занятных моментов:
import std.stdio, std.net.curl, std.json;

auto rus(string s) { 
  version(Windows) { import std.windows.charset, std.conv; return toMBSz(s, 866).text; }
  else return s;
}

void main(string[] argv) {
  scope(failure) return;
  if (argv.length < 2) return writeln("usage: ru word");
  get("https://en.wikipedia.org/w/api.php?action=query&format=json&prop=langlinks&lllang=ru&titles="~argv[1])
    .parseJSON["query"]["pages"].object.values[0]["langlinks"][0]["*"].str.rus.writeln;
}

Старожилы рассказывают, что в древнем наречии Visual Basic было заклинание On Error Resume Next, которое говорило в случае ошибки ее тупо игнорировать и идти дальше. Часто его вспоминаю, когда использую в D другое заклинание - scope(failure) return. Конструкция scope заворачивает код до конца скоупа в try-catch и позволяет указать некоторый код, который будет выполнен если вылетело исключение (scope(failure)), если не вылетело (scope(success)) или в любом случае (scope(exit)). Удобно для всяких RAII-подобных вещей, когда лень писать честный try-catch-finally или создавать обертку с деструктором. Так вот, если в scope(..) засунуть return, это приведет к тихому выходу из функции без дальшейшего пробрасывания исключения. В данном примере это означает, что если не удалось сделать запрос или найти в ответе искомое, программа завершается молча.
Другой забавный момент - как точки помогают писать в бесточечном стиле. :) За счет активного использования UFCS (universal function call syntax), методов и свойств, в теле main вообще ни одной переменной. В Окамле, F# или Elm'e это было бы много слов, разделенных |>, а в хаскеле - точками или $ да еще в обратном порядке. D-ивный вариант бесточечной записи через точки мне сейчас субъективно симпатичней.
Если вдруг кому нужно, виндовый бинарник можно взять тут, а можете и на свой любимый язык переложить, там логики-то на две строчки.
thedeemon: (office)

железные сапоги от граблей! (грабель?)

one more )
thedeemon: (office)
Когда понадобилось численно просчитать эволюцию системы из ее производной по времени, и наивное решение не заработало, вспомнил слова "Рунге-Кутта", которые со студенческой скамьи не использовал. Быстро находимые описания в интернетах не супер понятные, а конкретные примеры порой слишком частные, но оказалось, что алгоритм можно очень просто выразить в довольно общем виде. Он работает для любого типа (представления состояния системы), для которого даны всего три операции: сложение, умножение на вещественное число и вычисление производной по времени. Такой вот тайпкласс. Например, состоянием может быть набор координат и скоростей точек, тогда сложение и умножение на число делается с координатами и скоростями поэлементно, а производная по времени ставит скорости вместо координат и вычисленные из координат и скоростей ускорения - вместо скоростей. У меня состоянием был массив комплексных чисел - волновая ф-я. Весь код получения состояния системы через шаг времени dt выглядит так:

type alias DiffVecSpace v = {
  timeDerivative : v -> v,
  mulByFloat : Float -> v -> v,
  add : v -> v -> v
}

evolveRK : DiffVecSpace v -> Float -> v -> v
evolveRK ops dt state = 
  let a = ops.timeDerivative state
      b = ops.add state (ops.mulByFloat (dt/2) a) |> ops.timeDerivative
      c = ops.add state (ops.mulByFloat (dt/2) b) |> ops.timeDerivative
      d = ops.add state (ops.mulByFloat dt c) |> ops.timeDerivative
  in List.foldl ops.add state [ops.mulByFloat (dt/6) a,
                               ops.mulByFloat (dt/3) b,
                               ops.mulByFloat (dt/3) c,
                               ops.mulByFloat (dt/6) d]


(тут на Elm'e)
Если выразить на языке с нормальными тайпклассами или ООЯ с определяемыми операторами, получится еще проще. С другой стороны, возможно операцию вычисления производной стоит не вносить в тайпкласс, а передавать явно. Тогда можно для одного типа состояния считать его эволюцию при разных внешних условиях (разных методах вычисления сил/ускорений/операторов/whatever), что у меня активно используется в программе.

Elm 0.17

Jun. 22nd, 2016 12:52 pm
thedeemon: (office)
Elm - это хаскелеподобный чистый функциональный язык для всяких безобразий в браузере, т.е. "компилирующийся" в JavaScript. Знаменит прежде всего тем, что на нем написан визуализатор квантовой механики из предыдущего поста. :)
Три года назад я писал про тогдашний Elm, с тех пор он заметно изменился, а в последней на сегодня версии произошло существенное изменение в архитектуре, отчего большая часть старого кода и описаний перестала быть актуальной.
Изначально он появился как воплощение идей FRP, и thesis (дипломную работу?) автора Elm'a я могу всем рекомендовать как замечательное изложение идей и разных подходов к FRP, плавно переходящее в объяснение исходной архитектуры Elm'а (и без этого объяснения научиться тогдашнему Elm'у было трудно). Там вся динамика была построена на идее сигналов, когда есть обычные иммутабельные данные типов A,B,C... и есть отдельная категория типов A',B',C'... описывающих такие же данные, но меняющие свои значения со временем (навроде Time -> A'), и есть функтор Signal из первой категории во вторую. Пишешь чистый код, работающий с простыми иммутальными данными, потом этим функтором лифтишь свои чистые функции в мир динамически меняющихся значений. Есть набор внешних источников событий/данных, вроде координат мыши, т.е. уже живущих во второй категории, и нужно построить в ней функцию из нужных источников событий/данных в некое дерево контролов, элементов. А рантайм уже сам позаботится о том, чтобы все события и новые данные проходили как надо через все преобразования и получающееся на выходе дерево превращалось в DOM страницы. Ну и были во второй категории специальные комбинаторы для обращения с временнЫми потоками данных, вроде соединения, сворачивания и пр.
Потом в Elm'е появились Mailbox'ы и Elm Architecture, в которой программа описывалась двумя функциями view и update и начальным значением пользователького типа Model (содержащего все данные). update получала значение произвольного заданного пользователем типа Action (обычно это перечисление разных действий) и текущее значение модели, возвращала обновленное значение модели, а view отображала значение модели в дерево элементов, принимая одним из параметров "адрес" (значение специального типа Mailbox). Возвращаемые ф-ей view элементы в своих атрибутах могли иметь функции "что делать при нажатии/изменении", эти функции получали тот самый "адрес", чтобы слать свои оповещения туда. Так все оставалось иммутабельным и чистым, а рантайм заботился о доставке всех событий в форме пользовательского типа Action в функцию update, так осуществлялся круговорот событий-реакций в колесе сансары. Как видите, в явном виде сигналы уже не участвовали в Elm Architecture, но в разных API еще оставались.
В свежей версии 0.17 авторы сказали "прощай FRP" и выкинули все сигналы нафиг. Read more... )
thedeemon: (office)
Сегодня и вы их увидите. Сначала нарисуем вещественную прямую и возьмем какую-нибудь простую вещественную функцию, которая каждой точке вещественной прямой x сопоставляет некоторое вещественное число y, можем эти x и y использовать в качестве координат точек на плоскости и нарисовать график:

А теперь возьмем функцию f, которая возвращает не вещественное число, а комплексное. Это пара вещественных чисел (Re,Im), и их можно тоже использовать в качестве координат, надо только добавить еще одно измерение. (x,y,z) = (x, Re (f x), Im (f x))

У нас по-прежнему есть вещественная прямая, и через каждую ее точку проходит перпендикулярная ей комплексная плоскость, на которой можно точками или векторами рисовать комплексные числа. Этого достаточно, чтобы изобразить одномерную волновую функцию из квантовой механики. Read more... )
Read more... )
А теперь десерт. Этот пост инспирирован (а идея визуализации сперта) вот этим замечательным роликом. Увидев его, мне захотелось самому пощупать такую 3D визуализацию и позапускать разные численные эксперименты. И тогда я сделал такой вот интерактивный playground, в котором и были сделаны картинки и гифки из поста, и теперь вы тоже можете поиграться с разными функциями и операторами, слава WebGL! Там можно мышой хватать и крутить в разные стороны. Играться можно прямо в браузере здесь:
http://data.infognition.com/wavefun/
Read more... )
thedeemon: (bednota)
Группа ученых под руководством Дэниела Лебреро из Лаборатории Торговых Программных Интерфейсов британской компании IG Markets Ltd провела статистическое исследование о связи числа баг-репортов и языков программирования на базе информации об открытых проектах на сайте "Центр деятельности мерзавцев" (GitHub.com, организация разрешена в России, за исключением некоторых периодов, когда она запрещена). Выяснилось, что наличие статической типизации и продвинутой системы типов не помогает в уменьшении ошибок, а порой даже вредит, в то время как меньше всего ошибок получается в программах на максимально простых языках.

Плотность багов у проектов с 10 звездами и более:


Теперь научно доказано, что [livejournal.com profile] theiced был прав: типы не нужны, а писать надо на Кложури. А также Эрланге и Го. Адептам сложных языков и развитых систем типов надлежит раскаяться, одуматься и перестать уже своими надуманными неработающими идеями отвлекать благородных донов, занятых TDD.
thedeemon: (faculty of numbers)
Говорили, на ноль нельзя делить, а вот британские учоные научились! Берешь хаскель и делишь себе, получаешь конкретные числа:
Prelude> floor (1/0)
179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137216


Для 1, -1 и 0 ответы разные выходят.
thedeemon: (office)
Неплохое и не без юмора совсем вводное введение в ФП для ОО программистов, верующих в дизайн паттерны:

thedeemon: (office)
Как вы, вероятно, знаете, в мире Windows до сих пор COM живее всех живых, и поскольку его должно быть можно использовать и из Си, работа с ошибками там построена на базе кодов возврата: функции обычно возвращают HRESULT, целое число, которое 0 если все ок, отрицательно при ошибке и положительно, если это как бы не ошибка, но и не совсем полный успех. Ошибки надлежит не игнорировать и не пропускать, как-то обрабатывать, однако очень часто вся обработка сводится к тому, чтобы прекратить выполнение текущей ф-ии и передать эту ошибку наверх. В языках вроде Go это превращается в код вида

err := obj1.Action1(a, b)
if err != nil {
    return err
}
err := obj1.Action2(c, d)
if err != nil {
    return err
}
err := obj2.Action3(e)
if err != nil {
    return err
}

и т.д. Каждая строчка превращается в четыре, в лучших традициях


Read more... )
thedeemon: (office)
Пару недель назад довелось участвовать в эксперименте "какова вероятность того, что наугад выбранный популярный дистрибутив линукса запустится и заработает(графика,звук,wifi,тачпад) из коробки(загрузочной флэшки) на наугад выбранном ноутбуке?". Получил ответ 25%. Ну или 40, если присовокупить предустановленную убунту, которая там была раньше. Поскольку нужна была буквально система для домохозяйки, наугад выбранным линуксом был Linux Mint, за ним в очереди стояли вариации убунты. Первые три попробованных образа не запустились совершенно позорным образом. Но зато тот, что запустился (17.1 с KDE в качестве морды), заработал на все сто, даже такая мелочь, как управление яркостью экрана правильными кнопочками клавиатуры. Поставили его, и меня прямо очень радует, что я там вижу, пока что куда ни ткни, все работает как по маслу, очень годно.
thedeemon: (office)
Дочке еще нет двух лет. Планшет она уже давно освоила: сама его включает, запускает разные игры (продираясь в них через несколько экранов от заставки до экшна), включает мультики, меняет громкость. А недавно смотрим: подходит к ноутбуку (с линуксом и KDE, btw) и пальчиком так по тачпаду раз-раз, двигает указатель, перешла с текущего таба в браузере на таб с ютюбом, там выбирает себе мультики, находит значок Play, включает-останавливает, меняет громкость, опять же. А ведь это уже не сенсорный экран, где куда нажал, там и реагирует, это осознанное и ловкое управление курсором на экране через действия на тачпаде. Я впечатлен.
thedeemon: (office)
Блин, похоже как получилось!



( https://www.youtube.com/watch?v=eBRYsAfchkY )
thedeemon: (office)
Году в 1999-2000-м компания Sun на разных конференциях и выездных выступлениях активно что-то пиарила под общим лозунгом и маркой ".com".



И когда год-два спустя Microsoft выпустила свой .NET, было понятно, что это совершенно прямой и однозначный ответ на сановский .com. Только дотнет выжил, а дотком в свете одноименного пузыря куда-то рассосался, и найти что-то в сети о нем крайне сложно. Кто-нибудь вообще помнит, про что там было, что за этой маркой у Сана скрывалось?
thedeemon: (office)
Недавно спрашивали про использование компайл-тайм рефлексии в D, покажу пример. Есть такая знаменитая работа про бесплатные теоремы, где рассказывают о радостях генериков, ничего не знающих о том, что за типы у них в параметрах. Это часто позволяет по одному типу функции понять, что она будет делать, т.к. вариантов что ей делать у нее немного, ибо кроме передачи туда-сюда аргументов она, не зная ничего о них, почти ничего и не может с ними делать. Но что нам достается бесплатно мы часто не ценим, поэтому стоит обратить взор на обратный подход, где теоремы платные, по 72-139 рублей (без НДС) за штуку, в зависимости от набора используемых аксиом (с аксиомой выбора дороже!). Я имею в виду случай, когда генерик-функция, получая на вход тип Т, может во время компиляции позадавать про Т разные вопросы, что там у него внутри и что с ним можно делать, и в зависимости от ответов делать то или иное. Read more... )
void receive(Reactor)(File pipe, Reactor r) {
    uint[2] headerBuf;
    auto header = pipe.rawRead(headerBuf);
    if (header.length < 2) throw new CommException("eof"); 
    switch(header[0]) {
        foreach(T; MessageTypes!Reactor) {
            case MsgTypeHash!T:
                auto data = header[1] > 0 ? pipe.rawRead(new ubyte[header[1]]) : null;				
                return r.react(decerealise!T(data));
        }
        default: ... // обработать случай неизвестного сообщения
    }       
}

Read more... )
thedeemon: (vajrasattva)
В это время важно не упустить случай. Увидеть его крылья, увидеть его перья, и вдруг удивиться "а кто это теперь я?" Кто-то вспомнит про Кастанеду и орла, но всякий тибетский буддист тут легко узнает класс медитаций с визуализациями. "Если долго плакать.." - это первая фаза, сосредоточение. Потом идет мысленное рассматривание определенной 3D картины со всеми деталями ("перьями"), каждая из которых соотносится с определенными аспектами ума, концентрация на этом образе, и как результат медитирующий сам становится тем буддой, что представлял, сживается с образом, узнает его в своем уме. Ну а дальше про "сгореть и вернуться" тоже понятно - отбросить старое тело со старой кармой, вернуться бодхисаттвой для помощи другим.
Разрешаются и другие интерпретации. :)

Profile

thedeemon: (Default)
Dmitry Popov

May 2017

S M T W T F S
 1234 56
789 10 11 1213
14151617181920
21222324252627
28293031   

Syndicate

RSS Atom

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jul. 23rd, 2017 02:53 pm
Powered by Dreamwidth Studios