Posts tagged ‘erlang’

Что-ж это было-то

Ну ответ на это очень простой — это древовидное представление 192.168.2.1. То, что это дерево, угадал Тоботрас — на то он и великий. А уж то, что кому-то не лень будет ветки считать я и не расчитываю. :)

Я тут просто классический велосипед реализовываю  — попадание адреса в список масок (да-да, стандартная задача: локальное/мир/всё остальное).

Что это

кто догадается? :)

[[],[[],[[[[[[[[],[[[],[[[],[[[[[[[[[[[],[[[[[[[[[[],[nil,nil]],[]],[]],[]],[]],[]],[]],[]],[]]],[]],[]],[]],[]],[]],[]],[]],[]],[]]],[]]],[]]],[]],[]],[]],[]],[]],[]]]]

Психи

Решил выяснить, откуда на свежеустановленной Ubuntu 10.04/Desktop взялся установленный ерланг.
Вскрытие показало, что автоматом ставится gwibber. Это такая приблуда для микроблоггинга.
Которая написана на Питоне и, похоже, испоьзует python-desktopcouch.
Который, понятно дело, использует desktopcouch.
Которая использует couchdb-bin.
Которая написана на ерланге.

И эти люди вынесли из стандартной установки Gimp со смехотворной мотивацией, что он много места занимает…

Aho–Corasick string matching algorithm

Потребовалось тут — реализовал.

Причем оно, на самом деле, на строки не завязано.

ahocorasik:match([[{1,2,3}],[{3,2,1}], [{3,3,3},{1,2,3}]],[{1,2,3},4,5,6,7,8,{3,3,3},{1,2,3}]).
[{[{1,2,3}],[1,8]},{[{3,3,3},{1,2,3}],[7]}]

Continue reading ‘Aho–Corasick string matching algorithm’ »

Расстояние Левенштейна

Хорошая реализация. Главное — быстрая. А то я тут «в лоб» написал было. Всё хорошо, но на 1000 элементах мой вариант ушёл в несознанку. Еще-бы…

Только это не чистый Левенштейн, это Дамерау — Левенштейн.
Спёр себе, что-б было.
Continue reading ‘Расстояние Левенштейна’ »

dict vs lists

Стало интересно, в какой момент имеет переходить с простых списков на dict.

Проверил.

Из за того, что timer:tc точнее 1 микросекунды не считает, пришлось
для каждого варианта считать время выполнения 100 одинаковых операций.
Каждая такая итерация делалась 100000 раз и бралось среднее.

dict:find: при любом размере время выполнения 50-70 микросекунд
(напоминаю, это на 100 подряд вызовах, т.е. один вызов — где-то 0,5 -
0,7).

lists:keyfind:
номер элемента — время (здесь тоже помним про 100 вызовов).
1 — 4
10 — 8
20 — 12
30 — 15
100 — 46
150 — 67
200 — 87
300 — 130

Вобщем, где-то начиная с 300 элементов в списке имеет смысл переходить
на dict (если, конечно, нам не нужен постоянно последний элемент).

Откуда у хлопца испанская грусть

Я попытаюсь объяснить что именно меня заставляет постоянно испытывать когнитивный диссонанс при написании на ерланге. И пример из «Erlang programming» очень для этого подходит:

Допустим мы пишем функцию возвращающую номер месяца по его имени:

month('January') -> 1;
month('February') -> 2;
...
month('December') -> 12.

Что произойдёт, если вызвать эту функцию с «неправильным» параметром? Процесс упадёт, так как Ерланг не найдёт подходящей функции. А дальше у меня возникает «естественное» желание это отловить. Варианта три:
Совсем неправильный вариант — дописать

month(_other) -> {error, badmonth}.

Чуть менее неправильный вариант — переписать всё вот так:

month('January') -> {ok, 1};
month('February') -> {ok, 2};
...
month('December') -> {ok, 12};
month(_other) -> {error, badmonth}.

Особо изощренный неправильный вариант:

try
    M = month(MonthName)
catch
    _:_ -> ....
end

Есть еще варианты, но это, на самом деле, не важно. Потому что в этом месте ловить эту ошибку не нужно. Совсем не нужно. Оно должно упасть и пусть себе падает, всё равно никакого другого разумного выхода из этой ситуации нет, кроме как упасть и перезапуститься.
А почему приходится себя заставлять не делать эти проверки — это как раз «тяжелое наследие C/Pascal и иже с ним». Когда в течение многих лет приходилось помнить, что malloc может вернуть не только указатель, что fopen может вернуть не только хендл файла, когда неправильные параметры могут привести к не предсказуемым результатам.

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

Распечатать и повесить на стену.

Do not future-proof your code. Don’t try to write code that will be able to deal with
every possible eventuality as the system evolves. It will make your code harder to un-
derstand and maintain, adding unnecessary complexity.

Но писать после этого на «обычных» языках становится немного сложно.

Старый стал

30 строк кода в день — маловато как-то.
С другой стороны — иногда оно вот такое:

 Continue reading ‘Старый стал’ »

Очень не хватает

языка программирования с транзакциями.

Что бы можно было для функции написать три «тела» — что делать в обычном случае, что делать в случае «отката» и что делать в случае «откат не удался». Приходится писать настолько феерически некрасиво и многословно, отрабатывая на каждом шагу каждый чих, что в результате основной алгоритм теряется в нагромождении if/case/try.

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

Попутно задумался о применимости dz-товского фантома. Может я, конечно, чего-то не понимаю, но по моим ощущениям применимость идеи фантома ограничена случаем «нечто в себе с очень ограниченным взаимодействием со внешним миром». Ну т.е. настолько редкий и мизерный выигрыш от пресловутой persistence, что даже не смешно.