Стоит отметить, что Rust, который изначально был сделан с уклоном в функциональщину, зелёные потоки и асинхронное IO под капотом, теперь окончательно оформляется в C++ с современной системой типов.
Возможно это и хорошо, т.к. в функциональные языки он ничего особо нового не привнёс бы, а для C давно уже есть необходимость в современных альтернативах.
Кстати, присоединяюсь к вопросу — этот javascript выполняется не в браузере? Как вообще получается, что JS (который, вроде как в браузере должен работать) получает доступ к ФС и запуску исполняемых файлов? Или это какая-то особенность почтовых клиентов на Windows?
Да не, достаточно удобно. Главное, что если вы функцию опишете как возвращающую что-то, но влепите лишнюю ';', то оно не скомпилируется.
fn add(a: uint, b: uint) -> uint {
a + b;
}
<anon>:5:1: 7:2 error: not all control paths return a value
<anon>:5 fn add(a: uint, b: uint) -> uint {
<anon>:6 a + b;
<anon>:7 }
<anon>:6:10: 6:11 note: consider removing this semicolon:
<anon>:6 a + b;
^
error: aborting due to previous error
К слову, язык Rust тоже не поддерживает исключений, а факт ошибки определяется типом возвращаемого значения. Но Rust поддерживает макросы, и за счёт этого проброс ошибки наверх становится очень лаконичным:
my_fun(val) — так записывается вызов функции my_macro!(val) — так записывается обращение к макросу.
fn do_smth() -> Result {
let res1 = try!(do_sub1());
let res2 = try!(do_sub2());
return Ok(res1 + res2)
}
try! — это макрос, после разворота которого функция будет выглядеть так:
fn do_smth() -> Result {
let res1 = match do_sub1() {
Ok(v) => v,
Err(e) => return Err(e)
};
let res2 = match do_sub2() {
Ok(v) => v,
Err(e) => return Err(e)
};
return Ok(res1 + res2)
}
Т.е. если do_subX() вернула ошибку, то она возвращается из функции с помощью return, а если вернулось нормальное значение — оно присваивается переменной для дальнейшего использования.
Ваша история очень похода на мою — я тоже на Erlang на работе пишу пауков уже пару лет (Одного сложного дорабатываю постоянно и штуки 4 помельче). И отчасти я с вами согласен.
* HTTP клиент lhttpc работает отлично, ни разу проблем не возникало. Использовал 500-800 параллельных потоков в штатном режиме. Особо приятный момент — возможность жёстко ограничить время на скачивание странички — не уложился в 20 секунд — отбой. Но поддержку кукисов пришлось дописать. Помимо lhttpc есть вполне годные hackney и ibrowse.
* Для парсинга HTML тоже использую mochiweb_html. Даже бенчмарк делал — работает достаточно шустро, быстрее чем парсеры на большинстве динамических языков, по потреблению памяти так вообще почти всех делает. Зачем вы использовали list — строки вместо binary не знаю, видимо по неопытности…
* Для XPath брал тот же mochiweb_xpath — тут действительно была сильно урезанная версия и пришлось некоторые вещи дописывать — их сейчас влили в апстрим, так что поддержка XPath сейчас практически полная.
Насчёт zezro-deployment — не совсем понимаю что под этим подразумевается, не могу прокомментировать.
Насчёт надёжности не понял какие могут быть вопросы.
Что я получил в замен на свои «мучения»:
* Приемлемую производительность (первоначальная версия паука на Python + gevent + mongoDB для общих данных выдавала в ~10 раз меньше запросов и хрен поймёшь в каком месте был затык)
* Возможность подпатчить код без остановки паука (зашел на сервер, сделал nano src/cookie_storage.erl; rebar compile; erl -remsh spider@localhost; l(cookie_storage). и вот уже паук работает на подправленной версии).
* Удалённый шелл сам по себе отличная штука — можно подключиться к работающему процессу и что-то там посмотреть (включить профилирование / покопаться в памяти / изменить настройки / включить-отключить подсистему). Пользуюсь постоянно.
* Относительно легко подключать другие языки — у меня к пауку подключены интерпретаторы JS и Python.
* Выпилил лишние сущности (в Python версии шаренные данные /списки proxy, статистика, cookies etc/ складывали в MongoDB, т.к. gevent по ядрам CPU не умеет расползаться, в Erlang они хранятся прямо в памяти)
* Сам код стало проще структурировать и поддерживать, т.к. OTP к этому располагает.
С вебсокетами тоже баловался — вот этот сервис написал полностью на Erlang: http://dropmail.me/ru/ и там самые что ни на есть вебсокеты.
Как в Akka не знаю, в Erlang: Пусть есть акторы A B и C. Коллекцию хранит C. A и B отправят каждый по сообщению C «измени что то», сообщения попадут в мейлбокс C. C прочитает первое сообщение — изменит коллекцию, потом прочитает второе сообщение — ещё раз изменит коллекцию.
Возможно после изменения отправит в ответ сообщение «я изменил, вот новое значение» — тут уж как запрограммируешь.
Кстати, можете пояснить, почему любители Go постоянно упоминают «формальный стандарт» или «спецификацию». Ни от кого больше такого упора на её наличие не встречал.
У Rust есть doc.rust-lang.org/rust.html — тут весь язык расписан довольно подробно. Крупные публичные проекты на нём уже есть. Сторонних библиотек пока не так много разве что.
Оба варианта выглядят как сложение, хотя внутри умножение.
* Насчёт системы типов — всё-таки приятнее, когда типизация продуманная и РАБОТАЕТ, а не добавлена «для галочки» и страдает дырявостью.
* Pattern matching — я лично не понимаю что вообще можно иметь против него — штука то крайне удобная (что в Erlang, что в Rust). Сложным бы я его тоже не назвал.
Возможно это и хорошо, т.к. в функциональные языки он ничего особо нового не привнёс бы, а для C давно уже есть необходимость в современных альтернативах.
';'
, то оно не скомпилируется.is.gd/9tD5AB — пример.
man iptables
не пробовали?is_map
,binary_to_{integer,float}
,integer_to_binary
,float_to_binary
.my_fun(val)
— так записывается вызов функцииmy_macro!(val)
— так записывается обращение к макросу.try!
— это макрос, после разворота которого функция будет выглядеть так:Т.е. если
do_subX()
вернула ошибку, то она возвращается из функции с помощьюreturn
, а если вернулось нормальное значение — оно присваивается переменной для дальнейшего использования.* HTTP клиент lhttpc работает отлично, ни разу проблем не возникало. Использовал 500-800 параллельных потоков в штатном режиме. Особо приятный момент — возможность жёстко ограничить время на скачивание странички — не уложился в 20 секунд — отбой. Но поддержку кукисов пришлось дописать. Помимо lhttpc есть вполне годные hackney и ibrowse.
* Для парсинга HTML тоже использую mochiweb_html. Даже бенчмарк делал — работает достаточно шустро, быстрее чем парсеры на большинстве динамических языков, по потреблению памяти так вообще почти всех делает. Зачем вы использовали list — строки вместо binary не знаю, видимо по неопытности…
* Для XPath брал тот же mochiweb_xpath — тут действительно была сильно урезанная версия и пришлось некоторые вещи дописывать — их сейчас влили в апстрим, так что поддержка XPath сейчас практически полная.
Насчёт zezro-deployment — не совсем понимаю что под этим подразумевается, не могу прокомментировать.
Насчёт надёжности не понял какие могут быть вопросы.
Что я получил в замен на свои «мучения»:
* Приемлемую производительность (первоначальная версия паука на Python + gevent + mongoDB для общих данных выдавала в ~10 раз меньше запросов и хрен поймёшь в каком месте был затык)
* Возможность подпатчить код без остановки паука (зашел на сервер, сделал
nano src/cookie_storage.erl; rebar compile; erl -remsh spider@localhost; l(cookie_storage).
и вот уже паук работает на подправленной версии).* Удалённый шелл сам по себе отличная штука — можно подключиться к работающему процессу и что-то там посмотреть (включить профилирование / покопаться в памяти / изменить настройки / включить-отключить подсистему). Пользуюсь постоянно.
* Относительно легко подключать другие языки — у меня к пауку подключены интерпретаторы JS и Python.
* Выпилил лишние сущности (в Python версии шаренные данные /списки proxy, статистика, cookies etc/ складывали в MongoDB, т.к. gevent по ядрам CPU не умеет расползаться, в Erlang они хранятся прямо в памяти)
* Сам код стало проще структурировать и поддерживать, т.к. OTP к этому располагает.
С вебсокетами тоже баловался — вот этот сервис написал полностью на Erlang: http://dropmail.me/ru/ и там самые что ни на есть вебсокеты.
Возможно после изменения отправит в ответ сообщение «я изменил, вот новое значение» — тут уж как запрограммируешь.
У Rust есть doc.rust-lang.org/rust.html — тут весь язык расписан довольно подробно. Крупные публичные проекты на нём уже есть. Сторонних библиотек пока не так много разве что.
вместо
Оба варианта выглядят как сложение, хотя внутри умножение.
* Насчёт системы типов — всё-таки приятнее, когда типизация продуманная и РАБОТАЕТ, а не добавлена «для галочки» и страдает дырявостью.
* Pattern matching — я лично не понимаю что вообще можно иметь против него — штука то крайне удобная (что в Erlang, что в Rust). Сложным бы я его тоже не назвал.
Сервера уже повыключали? Я бы мог вам на Erlang для сравнения написать аналог.
sip_caller.sh <recipient> <path-to-audio-file>
иsip_sendim.sh <recipient> <message>
.