<?xml version="1.0"?><!-- generator="bbPress" -->

<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
>

<channel>
<title>Erlang по-русски. Форум: Последние 35 сообщений</title>
<link>http://erlang.dmitriid.com/forum/</link>
<description>Erlang по-русски. Форум: Последние 35 сообщений</description>
<language>en</language>
<pubDate>Fri, 25 Jul 2008 02:39:44 +0000</pubDate>

<item>
<title>Argo   "таблицы с {local_content,true} в кластере"</title>
<link>http://erlang.dmitriid.com/forum/topic/26#post-92</link>
<pubDate>Sat, 14 Jun 2008 09:19:23 +0000</pubDate>
<dc:creator>Argo</dc:creator>
<guid isPermaLink="false">92@http://erlang.dmitriid.com/forum/</guid>
<description>&lt;p&gt;Имеем кластер, код взят из rabbitmq_mnesia.&lt;br /&gt;
Некоторые таблицы имеют атрибут {local_content,true}.&lt;br /&gt;
Через какое-то время записи в таких таблицах пропадают.&lt;/p&gt;
&lt;p&gt;&amp;lt;(main@root.home)17&amp;gt; io:format(&quot;~p~n&quot;, [mnesia:table_info(client, all)]).&lt;br /&gt;
[{access_mode,read_write},&lt;br /&gt;
{active_replicas,['main@root.home']},&lt;br /&gt;
{arity,11},&lt;br /&gt;
{attributes,[Список полей]},&lt;br /&gt;
{checkpoints,[]},&lt;br /&gt;
{commit_work,[{index,set,[{3,{ram,210}},{6,{ram,209}}]}]},&lt;br /&gt;
{cookie,{{1213,369727,190492},'main@root.home'}},&lt;br /&gt;
{cstruct,{cstruct,client,set,[],&lt;br /&gt;
['main2@root.home','main@root.home'],&lt;br /&gt;
[],0,read_write,&lt;br /&gt;
[6,3],&lt;br /&gt;
[],true,client,&lt;br /&gt;
[Список полей],&lt;br /&gt;
[],[],&lt;br /&gt;
{{1213,369727,190492},'main@root.home'},&lt;br /&gt;
{{2,7},{'main2@root.home',{1213,423604,61968}}}}},&lt;br /&gt;
{disc_copies,['main2@root.home','main@root.home']},&lt;br /&gt;
{disc_only_copies,[]},&lt;br /&gt;
{frag_properties,[]},&lt;br /&gt;
{index,[6,3]},&lt;br /&gt;
{load_by_force,false},&lt;br /&gt;
{load_node,'main@root.home'},&lt;br /&gt;
{load_order,0},&lt;br /&gt;
{load_reason,local_only},&lt;br /&gt;
{local_content,true},&lt;br /&gt;
{master_nodes,[]},&lt;br /&gt;
{memory,279},&lt;br /&gt;
{ram_copies,[]},&lt;br /&gt;
{record_name,client},&lt;br /&gt;
{record_validation,{client,11,set}},&lt;br /&gt;
{type,set},&lt;br /&gt;
{size,0},&lt;br /&gt;
{snmp,[]},&lt;br /&gt;
{storage_type,disc_copies},&lt;br /&gt;
{subscribers,[]},&lt;br /&gt;
{user_properties,[]},&lt;br /&gt;
{version,{{2,7},{'main2@root.home',{1213,423604,61968}}}},&lt;br /&gt;
{where_to_commit,[{'main@root.home',disc_copies}]},&lt;br /&gt;
{where_to_read,'main@root.home'},&lt;br /&gt;
{where_to_write,['main@root.home']},&lt;br /&gt;
{wild_pattern,{client,'_','_','_','_','_','_','_','_','_',&lt;br /&gt;
'_'}},&lt;br /&gt;
{{index,3},210},&lt;br /&gt;
{{index,6},209}]&lt;br /&gt;
ok&amp;gt;&lt;br /&gt;
---------------&lt;br /&gt;
Куда копать?
&lt;/p&gt;</description>
</item>
<item>
<title>camui   "unix timestamp"</title>
<link>http://erlang.dmitriid.com/forum/topic/22#post-88</link>
<pubDate>Tue, 03 Jun 2008 14:41:12 +0000</pubDate>
<dc:creator>camui</dc:creator>
<guid isPermaLink="false">88@http://erlang.dmitriid.com/forum/</guid>
<description>&lt;p&gt;в общем вот, получилось. выкладываю код:&lt;/p&gt;
&lt;p&gt;timestamp_to_datetime(T) -&amp;gt;&lt;br /&gt;
	calendar:now_to_universal_time({T div 1000000,T rem 1000000,0}).&lt;/p&gt;
&lt;p&gt;возвращает {{Y,M,D},{h,m,s}}
&lt;/p&gt;</description>
</item>
<item>
<title>camui   "unix timestamp"</title>
<link>http://erlang.dmitriid.com/forum/topic/22#post-87</link>
<pubDate>Thu, 29 May 2008 13:06:06 +0000</pubDate>
<dc:creator>camui</dc:creator>
<guid isPermaLink="false">87@http://erlang.dmitriid.com/forum/</guid>
<description>&lt;p&gt;ну например у меня в базе хранится timestamp. как мне его перевести? эти функции я знаю, то это переводит текущее время. может быть можно timestamp перевести в формат который возвращает now()?&lt;br /&gt;
подскажи как руками перевести..
&lt;/p&gt;</description>
</item>
<item>
<title>architect   "unix timestamp"</title>
<link>http://erlang.dmitriid.com/forum/topic/22#post-86</link>
<pubDate>Wed, 28 May 2008 14:42:54 +0000</pubDate>
<dc:creator>architect</dc:creator>
<guid isPermaLink="false">86@http://erlang.dmitriid.com/forum/</guid>
<description>&lt;p&gt;calendar:now_to_universal_time(now()).&lt;br /&gt;
есть ещё&lt;br /&gt;
calendar:now_to_local_time(now()).&lt;br /&gt;
Вообще мог бы и руками сам перевести ;)
&lt;/p&gt;</description>
</item>
<item>
<title>camui   "unix timestamp"</title>
<link>http://erlang.dmitriid.com/forum/topic/22#post-85</link>
<pubDate>Mon, 26 May 2008 12:36:06 +0000</pubDate>
<dc:creator>camui</dc:creator>
<guid isPermaLink="false">85@http://erlang.dmitriid.com/forum/</guid>
<description>&lt;p&gt;Проблема вот возникла. Как найти unix timestamp  я нашел в прицнипе:&lt;br /&gt;
timer:now_diff(now(), {0,0,0}) div 1000000.&lt;/p&gt;
&lt;p&gt;а вот как получить из таймстэмпа удобочитаемые дату и время??? помогите плиз.
&lt;/p&gt;</description>
</item>
<item>
<title>Natalya   "Программист ERLANG 100 тыс."</title>
<link>http://erlang.dmitriid.com/forum/topic/21#post-84</link>
<pubDate>Mon, 28 Apr 2008 10:58:21 +0000</pubDate>
<dc:creator>Natalya</dc:creator>
<guid isPermaLink="false">84@http://erlang.dmitriid.com/forum/</guid>
<description>&lt;p&gt;Город: Москва&lt;/p&gt;
&lt;p&gt;О компании:&lt;br /&gt;
Фирма работает в сфере информационных технологий и является динамично развивающейся компанией обеспечивающей качественные научно-технические разработки в сети интернет. Компания располагается в деловом центре «Панорама» у Триумфальной площади.&lt;br /&gt;
Требования:&lt;/p&gt;
&lt;p&gt;    * Глубокие знания в области функционального и декларативного программирования.&lt;br /&gt;
    * Опыт практического применения таких языков, как Erlang/OTP, Common Lisp,&lt;br /&gt;
    * Prolog, Scheme, SQL.&lt;br /&gt;
    * Хорошие знания систем Unix, в первую очередь Solaris, Linux и FreeBSD.&lt;br /&gt;
    * Опыт создания web-приложений, знание соответствующих сетевых протоколов,&lt;br /&gt;
    * протоколов приложений.&lt;br /&gt;
    * Представление об особенностях работы СУБД Oracle и MySQL.&lt;br /&gt;
    * Желание на практике реализовывать приемущества как новых технологий, так и&lt;br /&gt;
    * новых подходов в области разработки ПО.&lt;/p&gt;
&lt;p&gt;Если Вас заинтересовала вакансия, то пожалуйста присылайте свои резюме по ниже указанным реквизитам с пометкой «bet_erlang».&lt;br /&gt;
Также можете обратиться к нам и узнать, что за компания открыла эту позицию и задать любые вопросы, не отправляя при этом своё резюме.&lt;br /&gt;
Контакты - Червякова Наталия&lt;br /&gt;
E-Mail: n.chervyakova()ludiagency.ru&lt;br /&gt;
ICQ UIN: 485-701-834&lt;br /&gt;
Телефон: (495) 930 8997
&lt;/p&gt;</description>
</item>
<item>
<title>Alexandr   "Требуется программист Erlang"</title>
<link>http://erlang.dmitriid.com/forum/topic/20#post-83</link>
<pubDate>Sun, 13 Apr 2008 19:08:22 +0000</pubDate>
<dc:creator>Alexandr</dc:creator>
<guid isPermaLink="false">83@http://erlang.dmitriid.com/forum/</guid>
<description>&lt;p&gt;Требования:&lt;br /&gt;
-Глубокие знания в области функционального и декларативного программирования.&lt;br /&gt;
-Опыт практического применения таких языков, как Erlang/OTP, Common Lisp, Prolog, Scheme, SQL.&lt;br /&gt;
-Хорошие знания систем Unix, в первую очередь Solaris, Linux и FreeBSD.&lt;br /&gt;
-Опыт создания web-приложений, знание соответствующих сетевых протоколов, протоколов приложений.&lt;br /&gt;
-Представление об особенностях работы СУБД Oracle и MySQL.&lt;br /&gt;
-Желание на практике реализовывать приемущества как новых технологий, так и новых подходов в области разработки ПО.&lt;br /&gt;
Условия:&lt;br /&gt;
-Оформление в соответствии с ТК, сменный график работы&lt;br /&gt;
-3/3, офис в центре Москвы.&lt;br /&gt;
Просьба резюме отправлять на мейл &lt;a href=&quot;mailto:oraclevac@gmail.com&quot;&gt;oraclevac@gmail.com&lt;/a&gt;
&lt;/p&gt;</description>
</item>
<item>
<title>Cyberon   "Литература"</title>
<link>http://erlang.dmitriid.com/forum/topic/7#post-80</link>
<pubDate>Sun, 06 Apr 2008 10:31:38 +0000</pubDate>
<dc:creator>Cyberon</dc:creator>
<guid isPermaLink="false">80@http://erlang.dmitriid.com/forum/</guid>
<description>&lt;p&gt;Спасибо
&lt;/p&gt;</description>
</item>
<item>
<title>architect   "Стек вызовов функций"</title>
<link>http://erlang.dmitriid.com/forum/topic/19#post-79</link>
<pubDate>Mon, 31 Mar 2008 18:16:24 +0000</pubDate>
<dc:creator>architect</dc:creator>
<guid isPermaLink="false">79@http://erlang.dmitriid.com/forum/</guid>
<description>&lt;p&gt;Перерыл документацию но так и не нашёл. Можно ли как-то увидеть стек вызова ф-ций?, т.е. историю вызовов: из какой функции вызвали ту, в которой находишься в данный момент. Хотя бы в отладочном режиме. Ведь в эмуляторе эта информация полюбому сохранена, он без неё не может работать.
&lt;/p&gt;</description>
</item>
<item>
<title>architect   "Как сделать ПРОСТОЙ запуск своего кода в windows?"</title>
<link>http://erlang.dmitriid.com/forum/topic/18#post-78</link>
<pubDate>Mon, 31 Mar 2008 18:10:31 +0000</pubDate>
<dc:creator>architect</dc:creator>
<guid isPermaLink="false">78@http://erlang.dmitriid.com/forum/</guid>
<description>&lt;p&gt;Ситуация: я написал приложение и мне надо чтобы пользователь запускал его обычным для себя способом. Т.е. чтобы кликал на файл и запускалось моё erlang приложение.&lt;br /&gt;
У меня только 1 способ решения возник: написать свой exe, который тупо запускает erl.exe с необходимой командной строкой, после чего просто выходит.&lt;br /&gt;
И второй вопрос: что надо по минимуму залить у пользователью (окромя моих .beam файлов), чтобы у него заработало моё приложение? Оно пользуется некоторыми библиотеками (stdlib и kernel в том числе). И как все файлы должны быть раскиданы по директориям?
&lt;/p&gt;</description>
</item>
<item>
<title>Ronin   "Литература"</title>
<link>http://erlang.dmitriid.com/forum/topic/7#post-77</link>
<pubDate>Thu, 13 Mar 2008 13:53:07 +0000</pubDate>
<dc:creator>Ronin</dc:creator>
<guid isPermaLink="false">77@http://erlang.dmitriid.com/forum/</guid>
<description>&lt;p&gt;А англоязычные учебники с примерами есть для бесплатного скачивания?
&lt;/p&gt;</description>
</item>
<item>
<title>yushi   "Как обойтись без наследования?"</title>
<link>http://erlang.dmitriid.com/forum/topic/16#post-76</link>
<pubDate>Tue, 22 Jan 2008 22:21:26 +0000</pubDate>
<dc:creator>yushi</dc:creator>
<guid isPermaLink="false">76@http://erlang.dmitriid.com/forum/</guid>
<description>&lt;p&gt;Действуя по подсказкам уважаемого architect, сделал на пробу два &quot;класса&quot;: один хранит значение x и имеет &quot;методы&quot; set_x и get_x, другой является &quot;потомком&quot; первого, а кроме того, имеет &quot;поле&quot; y и, соответственно, методы set_y и get_y. Однако у меня остаётся подозрение, что я в ряде мест изобретаю велосипед...&lt;/p&gt;
&lt;p&gt;Получилось вот что:&lt;br /&gt;
&lt;strong&gt;&lt;br /&gt;
common.erl&lt;br /&gt;
&lt;/strong&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
-module(common).&lt;br /&gt;
-export([rpc/2, loop/2]).&lt;/p&gt;
&lt;p&gt;rpc(Pid, Query)-&amp;gt;&lt;br /&gt;
    Pid ! {self(), Query},&lt;br /&gt;
    receive&lt;br /&gt;
        {Pid, Answer}-&amp;gt;&lt;br /&gt;
            Answer&lt;br /&gt;
    after 1000-&amp;gt;&lt;br /&gt;
        {error, &quot;Timeout&quot;}&lt;br /&gt;
    end.&lt;/p&gt;
&lt;p&gt;loop(Fun, State)-&amp;gt;&lt;br /&gt;
    receive&lt;br /&gt;
        {Pid, Method}-&amp;gt;&lt;br /&gt;
            NewState = Fun(State, {Method, Pid}),&lt;br /&gt;
            loop(Fun, NewState)&lt;br /&gt;
    end.&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;strong&gt;&lt;br /&gt;
parent.hrl&lt;br /&gt;
&lt;/strong&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
-record(parent, {x=0}).&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;strong&gt;&lt;br /&gt;
child.hrl&lt;br /&gt;
&lt;/strong&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
-include_lib(&quot;parent.hrl&quot;).&lt;br /&gt;
-record(child, {parent=#parent{}, y=0}).&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;strong&gt;&lt;br /&gt;
parent.erl&lt;br /&gt;
&lt;/strong&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
-module(parent).&lt;br /&gt;
-include_lib(&quot;parent.hrl&quot;).&lt;br /&gt;
-export([init/0, do/2]).&lt;/p&gt;
&lt;p&gt;do(State, {{set_x, NewX}, Pid})-&amp;gt;&lt;br /&gt;
    NewState = State#parent{x=NewX},&lt;br /&gt;
    Pid ! {self(), {ok, NewX}},&lt;br /&gt;
    NewState;&lt;br /&gt;
do(State, {{get_x}, Pid})-&amp;gt;&lt;br /&gt;
    Pid ! {self(), {ok, State#parent.x}},&lt;br /&gt;
    State;&lt;br /&gt;
do(State, {Any, Pid})-&amp;gt;&lt;br /&gt;
    Pid ! {self(), {error, [&quot;Unknown method&quot;, Any]}},&lt;br /&gt;
    State.&lt;/p&gt;
&lt;p&gt;init()-&amp;gt;&lt;br /&gt;
    spawn(fun()-&amp;gt; common:loop(fun parent:do/2, #parent{}) end).&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;strong&gt;&lt;br /&gt;
child.erl&lt;br /&gt;
&lt;/strong&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
-module(child).&lt;br /&gt;
-include_lib(&quot;child.hrl&quot;).&lt;br /&gt;
-export([init/0, do/2]).&lt;/p&gt;
&lt;p&gt;do(State, {{set_y, NewY}, Pid})-&amp;gt;&lt;br /&gt;
    NewState = State#child{y=NewY},&lt;br /&gt;
    Pid ! {self(), {ok, NewY}},&lt;br /&gt;
    NewState;&lt;br /&gt;
do(State, {{get_y}, Pid})-&amp;gt;&lt;br /&gt;
    Pid ! {self(), {ok, State#child.y}},&lt;br /&gt;
    State;&lt;br /&gt;
do(State, {Any, Pid}) -&amp;gt;&lt;br /&gt;
    NewParent = parent:do(State#child.parent, {Any, Pid}),&lt;br /&gt;
    NewState = State#child{parent=NewParent},&lt;br /&gt;
    NewState.&lt;/p&gt;
&lt;p&gt;init()-&amp;gt;&lt;br /&gt;
    spawn(fun()-&amp;gt; common:loop(fun child:do/2, #child{}) end).&lt;br /&gt;
&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Поймите меня правильно: не то, чтобы я был таким уж фанатом ООП. Но, ИМХО, есть области (например, имитационное моделирование), где без ОО-решений действительно бывает тяжело.
&lt;/p&gt;</description>
</item>
<item>
<title>sergesokolov   "Как обойтись без наследования?"</title>
<link>http://erlang.dmitriid.com/forum/topic/16#post-75</link>
<pubDate>Sun, 13 Jan 2008 14:58:12 +0000</pubDate>
<dc:creator>sergesokolov</dc:creator>
<guid isPermaLink="false">75@http://erlang.dmitriid.com/forum/</guid>
<description>&lt;p&gt;только не забывайте, что таким же образом - то есть совершенно правильно - Госплан считал, сколько Советскому Человеку надо туалетной бумаги.(и прочего)&lt;br /&gt;
В тему - лично меня Erlang имено тем и устроил, что нет нужды в запутанной иерархи классов, и проблему можно решать не надувая предварительно абстрактый базовый пузырь.
&lt;/p&gt;</description>
</item>
<item>
<title>yushi   "Как обойтись без наследования?"</title>
<link>http://erlang.dmitriid.com/forum/topic/16#post-74</link>
<pubDate>Wed, 09 Jan 2008 13:39:11 +0000</pubDate>
<dc:creator>yushi</dc:creator>
<guid isPermaLink="false">74@http://erlang.dmitriid.com/forum/</guid>
<description>&lt;p&gt;Второй вариант просто великолепен, спасибо! Это, собственно, пример того подхода, ради которого я и изучаю Эрланг (и Scheme): лаконичный и выразительный результат достигается не за счёт синтаксического сахара, а за счёт продуманности и гибкости базовых конструкций языка (первый вариант мне не подошёл бы, так как часто аналог StateA --- это крокодил на двадцать с лишним полей, и передавать их явно было бы, мягко выражаясь, утомительно =)).&lt;/p&gt;
&lt;p&gt;И, конечно, как всякое красивое решение, теперь оно кажется очевидным, да.
&lt;/p&gt;</description>
</item>
<item>
<title>architect   "Как обойтись без наследования?"</title>
<link>http://erlang.dmitriid.com/forum/topic/16#post-73</link>
<pubDate>Tue, 08 Jan 2008 13:58:26 +0000</pubDate>
<dc:creator>architect</dc:creator>
<guid isPermaLink="false">73@http://erlang.dmitriid.com/forum/</guid>
<description>&lt;p&gt;Это я копипастом увлёкся. Вообще хотел так написать:&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
b(State, {do2, Num, Pid}) -&amp;gt;&lt;br /&gt;
Pid ! {Return, Num * 2},&lt;br /&gt;
State;&lt;br /&gt;
b(State, Any) -&amp;gt;&lt;br /&gt;
a(State, Any).&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
Теперь касательно State. Сам если честно опыта не имею, всего пол года эрланг знаю и ещё ничего стоящего не написал. Поэтому опять ИМХО.&lt;br /&gt;
Безтиповость эрланга даёт полную абстракцию данных. Т.е. в переменной может быть любая структура, любой сложности, но ты видишь её всего лишь как 1 переменную. Это способ скрыть сложность. А скрыть сложность - цель лубого программирования на ЯВУ. В отличие от типизованых языков в эрланге есть возможность вызывать функцию сначала для одного типа, а потом ту же самую функцию вызвать для другого типа. И этим надо пользоваться.&lt;br /&gt;
&quot;State ведь будет записью довольно сложной структуры&quot; - да, во время выполнения будет. Но тебя не должно это волновать. Ты скроешь эту сложность в полях State. Вернёмся к нашим функциям a и b. Пусть a нужны данные data1 и data2. А b нужны data3 и data4. Если b знает что кушает a (и что возвращает a) и сама пользуется этими данными, то ещё State будет выглядеть как {data1, data2, data3, data4}, а при вызове функции a она будет передавать ей только поля {data1, data2}:&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
%Базовый процесс (объект)&lt;br /&gt;
a({Data1, Data2} = State, {do1, Num, Pid}) -&amp;gt;&lt;br /&gt;
Pid ! {retun, Num + 1},&lt;br /&gt;
State.&lt;/p&gt;
&lt;p&gt;%производный процесс (объект)&lt;br /&gt;
b({Data1, Data2, Data3, Data4} = State, {do1, Num, Pid}) -&amp;gt;&lt;br /&gt;
Pid ! {Return, Num * 2},&lt;br /&gt;
State;&lt;br /&gt;
b({Data1, Data2, Data3, Data4}, Any) -&amp;gt;&lt;br /&gt;
 {NewData1, NewData2} = a({Data1, Data2}, Any),&lt;br /&gt;
 {NewData1, NewData2, Data3, Data4}.&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
Если b не знает, что кушает a, то она будет передавать её просто переменную StateA, и State у функции b будет таким: {data3, data4, StateA}. Разве это похоже на сложные структуры?). Даже если функция a потом вызывает функцию c, то b об этом ничего не знает, и соответственно не видит сложность структуры StateA. Этот вариант предпочтительнее первого.&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
%Базовый процесс (объект)&lt;br /&gt;
a({Data1, Data2} = State, {do1, Num, Pid}) -&amp;gt;&lt;br /&gt;
Pid ! {retun, Num + 1},&lt;br /&gt;
State.&lt;/p&gt;
&lt;p&gt;%производный процесс (объект)&lt;br /&gt;
b({Data3, Data4, StateA} = State, {do1, Num, Pid}) -&amp;gt;&lt;br /&gt;
Pid ! {Return, Num * 2},&lt;br /&gt;
State;&lt;br /&gt;
b({Data1, Data2, StateA}, Any) -&amp;gt;&lt;br /&gt;
 NewStateA = a(StateA, Any),&lt;br /&gt;
 {Data3, Data4, NewStateA}.&lt;br /&gt;
&lt;/code&gt;
&lt;/p&gt;</description>
</item>
<item>
<title>yushi   "Как обойтись без наследования?"</title>
<link>http://erlang.dmitriid.com/forum/topic/16#post-72</link>
<pubDate>Mon, 07 Jan 2008 23:29:40 +0000</pubDate>
<dc:creator>yushi</dc:creator>
<guid isPermaLink="false">72@http://erlang.dmitriid.com/forum/</guid>
<description>&lt;p&gt;О, то что надо, спасибо (единственное что --- я не очень понимаю, зачем в функции b сопоставление с образцом State, {do1, Num, Pid} --- ведь в функции a уже есть обработка этого случая, и b вызовет её благодаря&lt;br /&gt;
b(State, Any) -&amp;gt;&lt;br /&gt;
    a(State, Any),&lt;br /&gt;
правильно?&lt;/p&gt;
&lt;p&gt;Вы, собственно, практически ответили на мой вопрос --- я, действительно, слишком увлёкся метафорой &quot;процесс это объект&quot; и не сообразил, что для вызова функции из другого модуля не обязательно запускать функцию разбора сообщений из этого модуля.&lt;/p&gt;
&lt;p&gt;Единственный оставшийся вопрос --- в реальной ситуации State ведь будет записью довольно сложной структуры, правильно? Кроме того, функции модулей-&quot;потомков&quot; могут ожидать обнаружить в ней разный набор дополнительных полей. Как правильно поступить в этом случае? Завести одно нетипизированное поле, как предлагает gogabr (а в нём --- ещё одно, на случай дополнительного &quot;наследования&quot;, и т.д.)? Или есть ещё какие-то решения?&lt;/p&gt;
&lt;p&gt;&quot;Вообще мыслить объектами (т.е. их методами) ИМХО неправильно&quot; --- опять же, повторюсь: целью исходного поста и было выяснить, каков  &quot;Erlang way&quot; в таких ситуациях, а не &quot;как реализовать наследование на Эрланге&quot;. См, например, тему этого треда. =)
&lt;/p&gt;</description>
</item>
<item>
<title>dmitriid   "xmlrpc"</title>
<link>http://erlang.dmitriid.com/forum/topic/17#post-71</link>
<pubDate>Mon, 07 Jan 2008 12:27:14 +0000</pubDate>
<dc:creator>dmitriid</dc:creator>
<guid isPermaLink="false">71@http://erlang.dmitriid.com/forum/</guid>
<description>&lt;p&gt;Однако :)
&lt;/p&gt;</description>
</item>
<item>
<title>architect   "Как обойтись без наследования?"</title>
<link>http://erlang.dmitriid.com/forum/topic/16#post-70</link>
<pubDate>Sun, 06 Jan 2008 19:58:18 +0000</pubDate>
<dc:creator>architect</dc:creator>
<guid isPermaLink="false">70@http://erlang.dmitriid.com/forum/</guid>
<description>&lt;p&gt;Везде же написано, что аналог объекта в эрланге - это процесс. А что такое процесс? Это функция. Данные храним в переменных состояния, запросы/ответы получаем через механизм сообщений. Приведу пример.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&lt;br /&gt;
start() -&amp;gt;&lt;br /&gt;
 A = new_proc(a, [[]]),  %Создали &quot;объект&quot; А,&lt;br /&gt;
 B = new_proc(b, [[]]),  %А теперь Б&lt;br /&gt;
 B ! {do1, 10, self()}.  %вызвали &quot;метод&quot;.&lt;/p&gt;
&lt;p&gt;%Базовый процесс (объект)&lt;br /&gt;
a(State, {do1, Num, Pid}) -&amp;gt;&lt;br /&gt;
 Pid ! {retun, Num + 1},&lt;br /&gt;
 State.&lt;/p&gt;
&lt;p&gt;%производный процесс (объект)&lt;br /&gt;
b(State, {do1, Num, Pid}) -&amp;gt;&lt;br /&gt;
  Pid ! {Return, Num * 2},&lt;br /&gt;
  State;&lt;br /&gt;
b(State, Any) -&amp;gt;&lt;br /&gt;
  a(State, Any).&lt;/p&gt;
&lt;p&gt;loop(Fun, State) -&amp;gt;&lt;br /&gt;
 receive&lt;br /&gt;
  Data -&amp;gt;&lt;br /&gt;
   NewState = Fun(State, Data)&lt;br /&gt;
 loop(Fun, NewState).&lt;/p&gt;
&lt;p&gt;new_proc(Fun, Arg) -&amp;gt;&lt;br /&gt;
 spawn(?MODULE, loop, [Fun, Arg]).&lt;br /&gt;
&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Но это одниночное наследование. А вот множественное:&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
%одно свойство объекта&lt;br /&gt;
a(State, {do1, Num, Pid}) -&amp;gt;&lt;br /&gt;
 Pid ! {retun, Num + 1},&lt;br /&gt;
 State.&lt;/p&gt;
&lt;p&gt;%второе свойство объекта&lt;br /&gt;
b(State, {do2, Num, Pid}) -&amp;gt;&lt;br /&gt;
  Pid ! {Return, Num * 2},&lt;br /&gt;
  State.&lt;/p&gt;
&lt;p&gt;start() -&amp;gt;&lt;br /&gt;
  A = create_proc( [a/2], []),&lt;br /&gt;
  B = create_proc( [b/2], []),&lt;br /&gt;
  AB = create_proc( [b/2, a/2], []),&lt;br /&gt;
  AB ! {do1, 10, self()}.      %вызвали &quot;метод&quot;.&lt;/p&gt;
&lt;p&gt;runner(Fun, Args) -&amp;gt;&lt;br /&gt;
  case catch Fun(Args) of&lt;br /&gt;
    {'EXIT', _} -&amp;gt;&lt;br /&gt;
      Args;&lt;br /&gt;
    NewState -&amp;gt;&lt;br /&gt;
      throw {ok, NewState}&lt;br /&gt;
    end.&lt;/p&gt;
&lt;p&gt;poly_object(Components, State) -&amp;gt;   %Components - список функций,&lt;br /&gt;
                                    %объединённых в объекте&lt;br /&gt;
  case catch lists:foldl( runner/2, State, Componets ) of&lt;br /&gt;
    {'ERROR', _} -&amp;gt;&lt;br /&gt;
      poly_object(Components, State);&lt;br /&gt;
    {ok, NewState} -&amp;gt;&lt;br /&gt;
      poly_object(Components, NewState);&lt;br /&gt;
  end.&lt;/p&gt;
&lt;p&gt;create_proc(Components, InitState) when is_list(Components) -&amp;gt;&lt;br /&gt;
  spawn(?MODULE, poly_object, [Components, InitState]).&lt;br /&gt;
&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Вообще играясь с высокоуровневыми ф-ями можно получить любой &quot;объект&quot; и собирать &quot;объекты&quot; прямо во время выполнения - своего рода самомодифицирующийся код.&lt;/p&gt;
&lt;p&gt;PS. Вообще мыслить объектами (т.е. их методами) ИМХО неправильно, у эрлага все данные слишком абстрактны и работать надо с ними на высоком уровне. В конце концов можно вызвать ЛЮБУЮ функцию для ЛЮБЫХ данных, в ООП языках так низя, там есть типы, поэтому там и &quot;назначают&quot; функции типам - обединяют их в объект. В эрланге &quot;назначают&quot; задачи процессам...
&lt;/p&gt;</description>
</item>
<item>
<title>architect   "Как обойтись без наследования?"</title>
<link>http://erlang.dmitriid.com/forum/topic/16#post-69</link>
<pubDate>Sun, 06 Jan 2008 19:56:38 +0000</pubDate>
<dc:creator>architect</dc:creator>
<guid isPermaLink="false">69@http://erlang.dmitriid.com/forum/</guid>
<description>&lt;p&gt;удалите плиз это сообщение, случайно 2 раза запостил
&lt;/p&gt;</description>
</item>
<item>
<title>yushi   "Как обойтись без наследования?"</title>
<link>http://erlang.dmitriid.com/forum/topic/16#post-68</link>
<pubDate>Sun, 06 Jan 2008 15:00:32 +0000</pubDate>
<dc:creator>yushi</dc:creator>
<guid isPermaLink="false">68@http://erlang.dmitriid.com/forum/</guid>
<description>&lt;p&gt;Задача модели: запуститься с некоторыми характеристиками транзакционных издержек и проработать некоторое время. Затем вывести граф получившихся торговых связей. Соответственно, задача потребителя: оценить своё состояние, если испытывается потребность в ресурсе, найти его продавцов, оценить выгодность сделки с каждым из них, приобрести ресурс наиболее выгодным образом. Задача продавца: произвести ресурс, предложить его потребителям, если никто не покупает --- изменить характеристики предложения. Мне, в принципе, казалось, что это очевидно из моей предыдущей реплики. Ну, в любом случае теперь для обсуждения архитектуры, кажется, точно сказано достаточно.&lt;/p&gt;
&lt;p&gt;&quot;на С++ ... необязательно затевать иерархию&quot; --- обязательно, если не хочется одноразового неподдерживаемого кода.&lt;/p&gt;
&lt;p&gt;Что тут &quot;с лёгкостью ложится на Эрланг&quot;, мучительно не понимаю. Попробую ещё раз, м.б., мне не удалось как следует объяснить: &quot;функциональность экономики&quot; выходит за рамки обсуждаемой темы. Я рассказывал о &lt;em&gt;части&lt;/em&gt; задачи по имитационному моделированию, в которой есть агенты, умеющие определённый набор вещей. Но при этом одна часть этих агентов имеет один набор дополнительных умений и данных о своём состоянии, а другая --- другой.&lt;/p&gt;
&lt;p&gt;Вопрос: как спроектировать систему на Эрланге для реализации этой модели? С помощью behaviours, как предлагает пользователь gogabr? А если, действительно, уровней в иерархии больше двух (экономические агенты делятся на потребителей и производителей, а производители на производителей пушек и производителей масла, например)? А как хранить характеристики агентов?
&lt;/p&gt;</description>
</item>
<item>
<title>Tonal   "Как обойтись без наследования?"</title>
<link>http://erlang.dmitriid.com/forum/topic/16#post-67</link>
<pubDate>Sat, 05 Jan 2008 18:21:14 +0000</pubDate>
<dc:creator>Tonal</dc:creator>
<guid isPermaLink="false">67@http://erlang.dmitriid.com/forum/</guid>
<description>&lt;p&gt;Тут, даже на С++, на мой взгляд, необязательно затевать иерархию.&lt;br /&gt;
Вполне достаточно вынести обшюю функциональность в отдельный модуль.&lt;br /&gt;
Что с лёгкостью ложиться на Erlang - модуль процессов для продавцов, модуль процессов для покупателей и модуль с функциональностью экономики. :-)&lt;/p&gt;
&lt;p&gt;Но, ты рассказал только устройство модели, в объектах и их функциональности. А задачи, ею решаемые не рассказал.&lt;/p&gt;
&lt;p&gt;Соответственно, с позиций чистого ФП здесь решать пака нечего. :-)&lt;/p&gt;
&lt;p&gt;P.S. Кстати, сам работаю на Qt + Python.&lt;br /&gt;
Жасль, что для Erlang-а (да и для Haskell) до сих пор нет биндинга к Qt.
&lt;/p&gt;</description>
</item>
<item>
<title>yushi   "Как обойтись без наследования?"</title>
<link>http://erlang.dmitriid.com/forum/topic/16#post-66</link>
<pubDate>Sat, 05 Jan 2008 01:18:47 +0000</pubDate>
<dc:creator>yushi</dc:creator>
<guid isPermaLink="false">66@http://erlang.dmitriid.com/forum/</guid>
<description>&lt;p&gt;Как оно устроено &quot;в ФП вообще&quot;, я примерно понимаю, благо, опыт написания всякой мелочи на Scheme имеется. Интересует именно Эрланг, который, во-первых, благодаря своим независимым процессам в каком-то смысле как раз ОО-язык, более того, &quot;ОО-язык as it shall be&quot; (я по работе много пишу на Qt и регулярно замечаю, как легко было бы многие подаваемые как killer feature возможности этой библиотеки реализовать на Эрланге), а во-вторых, в отличие от Scheme/Haskell/*ML, широко применяется на практике, благодаря чему уже должны были сложиться типовые решения типовых проблем. Шаблоны проектирования, ага.&lt;/p&gt;
&lt;p&gt;Ладно, что-то разговор беспредметный получается. Приведу конкретный пример.&lt;/p&gt;
&lt;p&gt;Предположим, что мы пишем программу имитационного моделирования. Модель описывает покупателей и продавцов. И продавцы, и покупатели умеют а)вносить деньги на свой расчётный счёт и тратить их, б)оценивать своё географическое положение, географическое положение партнёра и транзакционные издержки, зависящие от удалённости партнёра. Продавцы при этом умеют также производить единицы продукции; потребители умеют испытывать нужду в единицах продукции и покупать их у продавцов. В реальном коде на C++ был написан базовый класс &quot;экономический агент&quot;, в котором были расписаны операции с банковским счётом и вычисление издержек; от него были унаследованы классы &quot;продавец&quot; и &quot;покупатель&quot;, реализовывавшие свои специфические методы.&lt;/p&gt;
&lt;p&gt;Как ту же самую модель следовало бы писать на Эрланге?
&lt;/p&gt;</description>
</item>
<item>
<title>Tonal   "Как обойтись без наследования?"</title>
<link>http://erlang.dmitriid.com/forum/topic/16#post-65</link>
<pubDate>Fri, 04 Jan 2008 23:33:35 +0000</pubDate>
<dc:creator>Tonal</dc:creator>
<guid isPermaLink="false">65@http://erlang.dmitriid.com/forum/</guid>
<description>&lt;p&gt;Есть, но разбиение здесь совершенно другое.&lt;br /&gt;
В ООП разбиение идёт от сущьностей (объекты) и их иерархий, а в ФП разбиение идёт от действий, которые тебе нужно выполнить. :-)
&lt;/p&gt;</description>
</item>
<item>
<title>yushi   "Как обойтись без наследования?"</title>
<link>http://erlang.dmitriid.com/forum/topic/16#post-64</link>
<pubDate>Fri, 04 Jan 2008 23:00:50 +0000</pubDate>
<dc:creator>yushi</dc:creator>
<guid isPermaLink="false">64@http://erlang.dmitriid.com/forum/</guid>
<description>&lt;p&gt;Ну да, так и есть. Собственно, в этом и заключался вопрос --- &quot;есть ли в Эрланге типовое решение для проблем, которые в ООП решают с помощью наследования?&quot;, а не &quot;как в Эрланге реализовать наследование?&quot;.&lt;/p&gt;
&lt;p&gt;Плохо получилось сформулировать, к сожалению.
&lt;/p&gt;</description>
</item>
<item>
<title>17dufa   "xmlrpc"</title>
<link>http://erlang.dmitriid.com/forum/topic/17#post-63</link>
<pubDate>Fri, 04 Jan 2008 22:03:11 +0000</pubDate>
<dc:creator>17dufa</dc:creator>
<guid isPermaLink="false">63@http://erlang.dmitriid.com/forum/</guid>
<description>&lt;p&gt;дело было в антивирусе, он блокировал работу.
&lt;/p&gt;</description>
</item>
<item>
<title>17dufa   "xmlrpc"</title>
<link>http://erlang.dmitriid.com/forum/topic/17#post-62</link>
<pubDate>Fri, 04 Jan 2008 20:09:59 +0000</pubDate>
<dc:creator>17dufa</dc:creator>
<guid isPermaLink="false">62@http://erlang.dmitriid.com/forum/</guid>
<description>&lt;p&gt;Здраствуйте&lt;br /&gt;
взял либу для работы с xmlrpc, start_link отрабатывает, а вот call постоянно вылетает - {error,closed}. запустить пытаюсь стандартный пример на числа фибоначчи:&lt;br /&gt;
xmlrpc:start_link(4567,1000,100000,{fib_server,handler},undefined)&lt;br /&gt;
это отрабатывает, а вот это:&lt;br /&gt;
xmlrpc:call({127, 0, 0, 1}, 4567, &quot;/&quot;, {call, fib, [0]}).&lt;br /&gt;
вылетает
&lt;/p&gt;</description>
</item>
<item>
<title>gogabr   "Как обойтись без наследования?"</title>
<link>http://erlang.dmitriid.com/forum/topic/16#post-61</link>
<pubDate>Fri, 04 Jan 2008 16:32:49 +0000</pubDate>
<dc:creator>gogabr</dc:creator>
<guid isPermaLink="false">61@http://erlang.dmitriid.com/forum/</guid>
<description>&lt;p&gt;Я бы просто хранил поля родителя впрямую, а для детских имел бы в родительской структуре отдельное нетипизированное поле (вообще говоря, вся типизация ведь динамическая). В каких-то случаях только его можно передавать детским функциям.&lt;br /&gt;
Но, в общем, у меня уже складывается впечатление, что весь этот OO-разговор -- попытка описать эрланговские идиомы на несвойственном для них языке. Или, наоборот, найти привычные конструкции там, где их нет.
&lt;/p&gt;</description>
</item>
<item>
<title>yushi   "Как обойтись без наследования?"</title>
<link>http://erlang.dmitriid.com/forum/topic/16#post-60</link>
<pubDate>Fri, 04 Jan 2008 15:13:59 +0000</pubDate>
<dc:creator>yushi</dc:creator>
<guid isPermaLink="false">60@http://erlang.dmitriid.com/forum/</guid>
<description>&lt;p&gt;Ага, спасибо. Примерно понял, буду смотреть.&lt;/p&gt;
&lt;p&gt;А как при этом принято хранить состояние? Мне кажется правильным делать структуру state, у которой будут поля, скажем, parent и child, хранящие &quot;поля&quot; родителя и потомка соответственно. Но слегка смущает, что при этом получается, что state будет описываться несколько раз --- для родителя (как имеющая только поле child) и каждого из потомков (для каждого со своим типом в поле parent); позволяет ли такое Эрланг и если да, то как?
&lt;/p&gt;</description>
</item>
<item>
<title>gogabr   "Как обойтись без наследования?"</title>
<link>http://erlang.dmitriid.com/forum/topic/16#post-59</link>
<pubDate>Thu, 03 Jan 2008 08:23:24 +0000</pubDate>
<dc:creator>gogabr</dc:creator>
<guid isPermaLink="false">59@http://erlang.dmitriid.com/forum/</guid>
<description>&lt;p&gt;Disclaimer: у меня у самого опыта негусто.&lt;br /&gt;
Насколько я понимаю, приблизательно для этого предначзнаены behaviours (хотя делают они меньше, чем ты хочешь).&lt;/p&gt;
&lt;p&gt;Это более или менее похоже на твой третий вариант, с точностью до двух деталей:&lt;br /&gt;
1. В &quot;родительском&quot; модуле (собственно описании поведения) запоминаются не функции &quot;потомка&quot; (модуля, реализующего поведение), а просто его имя.  Потом их можно звать через Mod:fun (Arg) (где Mod -- переменная). Язык-то, в общем, интерпретируемый и связывание позднее.&lt;br /&gt;
2. Есть некоторая языковая поддержка, которая позволяет компилятору проверить, все ли нужные   &quot;методы&quot; в &quot;потомке&quot; определены (см. функцию behaviour_info).&lt;/p&gt;
&lt;p&gt;В исходниках библиотек можно посмотреть, скажем, модули gen или gen_server, которые свои поведения реализуют.&lt;/p&gt;
&lt;p&gt;Наследовать одно поведение от другого (то есть строить более чем двухуровневую иерархию) можно, но довольно неудобно.
&lt;/p&gt;</description>
</item>
<item>
<title>yushi   "Как обойтись без наследования?"</title>
<link>http://erlang.dmitriid.com/forum/topic/16#post-58</link>
<pubDate>Thu, 03 Jan 2008 02:26:38 +0000</pubDate>
<dc:creator>yushi</dc:creator>
<guid isPermaLink="false">58@http://erlang.dmitriid.com/forum/</guid>
<description>&lt;p&gt;Доброго времени суток.&lt;/p&gt;
&lt;p&gt;Никто не в курсе, существует ли в Эрланге готовый шаблон проектирования для ситуации, когда есть несколько в значительной степени пересекающихся наборов данных и вещей, которых можно с этими данными делать?&lt;/p&gt;
&lt;p&gt;В ОО-языке я бы, понятно, создавал иерархию классов, запихивая общие поля и методы в базовый класс, а специфичные для конкретных случаев --- в классы-наследники.&lt;/p&gt;
&lt;p&gt;Насколько я понимаю, в Эрланге на смену объекту ОО-языка приходит функция с хвостовой рекурсией, разбирающая сообщения с помощью конструкции receive и вызывающая сама себя с состоянием процесса в качестве аргумента. А существует ли при этом аналог наследования или способ обходиться без него?&lt;/p&gt;
&lt;p&gt;На ум приходит несколько решений, и каждое из них чем-нибудь да кажется уродливым:&lt;br /&gt;
-в функции, запускающей процесс &quot;потомка&quot; (модуля, работающего со специфичными для конкретного случая данными), spawn-ить процесс &quot;родителя&quot; (модуля, работающего с общими данными), запоминать его PID и передавать ему все сообщения, которые &quot;потомок&quot; не смог распарсить сам;&lt;br /&gt;
-для хранения состояния процесса определять структуру (в смысле запись, record) с общими данными, для полей и методов &quot;потомка&quot; выделить 2 списка или ETS и в &quot;конструкторе&quot; (т.е. функции, вызываемой при старте процесса) заполнять этот список кортежами вида {имя_поля, значение} и {имя_метода, метод}; при разборе сообщений каждый раз искать поля и методы в этой структуре;&lt;br /&gt;
-состояние процесса (аргумент рекурсивной функции, содержащей конструкцию receive) сделать замыканием (closure), возвращающим функцию-диспетчер, возвращающую, в свою очередь, поля и методы &quot;объекта&quot;; в функциях-диспетчерах &quot;потомков&quot; предусмотреть обращение к функции-диспетчеру &quot;предка&quot;.&lt;/p&gt;
&lt;p&gt;(Если получилось мутно, могу проиллюстрировать каждую из идей небольшим примером.)&lt;/p&gt;
&lt;p&gt;Подозреваю, что правильное решение вообще не предполагает рукосуйной имитации ООП --- но мой искалеченный C++ мозг его не находит. =)
&lt;/p&gt;</description>
</item>
<item>
<title>qrilka   "Как посылать сообщения?"</title>
<link>http://erlang.dmitriid.com/forum/topic/14#post-57</link>
<pubDate>Tue, 18 Dec 2007 14:20:32 +0000</pubDate>
<dc:creator>qrilka</dc:creator>
<guid isPermaLink="false">57@http://erlang.dmitriid.com/forum/</guid>
<description>&lt;p&gt;Естественно оно выдаст undef - функция-то не экспортирована, поэтому spawn её не видит.
&lt;/p&gt;</description>
</item>
<item>
<title>Cyberon   "Как посылать сообщения?"</title>
<link>http://erlang.dmitriid.com/forum/topic/14#post-56</link>
<pubDate>Fri, 14 Dec 2007 22:06:20 +0000</pubDate>
<dc:creator>Cyberon</dc:creator>
<guid isPermaLink="false">56@http://erlang.dmitriid.com/forum/</guid>
<description>&lt;p&gt;Отказался от идеи посылки сообщений о вычисленном хеше клиентам. Написал код сервера и набросок кода клиента. Сервер запускается без проблем, но клиент не может к нему подсоединиться - выдает ошибку.&lt;br /&gt;
Запуск сервера&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
erl -sname brute
Eshell V5.6  (abort with ^G)
(brute@warez)1&amp;gt; server:start_server([{[1,2],[\&quot;abcde\&quot;,\&quot;abjasf\&quot;,\&quot;ds\&quot;,\&quot;1234\&quot;,\&quot;12345\&quot;]}]).
User list = []
 Task list = [{[1,2],
               [\&quot;ds\&quot;,\&quot;1234\&quot;,\&quot;12345\&quot;],
               [{1,5,\&quot;abcde\&quot;},{1,6,\&quot;abjasf\&quot;}]}]
true
(brute@warez)2&amp;gt; 

Запуск клиента
erl -sname client
Eshell V5.6  (abort with ^G)
(client@warez)1&amp;gt; client:start_client(brute@warez).
 &amp;lt;0.37.0&amp;gt;

=ERROR REPORT==== 14-Dec-2007::22:01:36 ===
Error in process &amp;lt;0.37.0&amp;gt; on node 'client@warez' with exit value: {undef,[{client,client,['brute@warez']}]}

(client@warez)2&amp;gt; 

Код сервера
&amp;lt;%%% Процесс сервера службы отправки сообщений
%%% task[{[Hash],[RangeSymbol]}] 

-module(server).
-export([start_server/1, server/1, server/2, next/1, next2/1]).
-import(lists, [keymember/3, keysearch/3, keydelete/3, keyreplace/4, unzip/1,
  subtract/2, keyreplace/4, split/2, nth/2, map/2]).
-include(\&quot;mess_interface.hrl\&quot;).

%%% Список пользователей имеет формат [{ClientPid1, Hashes1, String1, Task1},
%%% {ClientPid22, Hashes22, String22, Task22}, ...]
%%% Tasks = [ { [{I, L, Sym}], [Hash], ClientRange} ]
%%% Task = {[Hash], Prefix, Range}
%%% Result = [{Hash, Pass}]
server(User_List, [{Prefix, Hashes, ClientRange}|Task_List]) -&amp;gt;
  io:format(\&quot;User list = ~p~n Task list = ~p~n\&quot;, [User_List,[{Prefix, Hashes, ClientRange}|Task_List]]),
  receive
  #logon{client_pid=From} -&amp;gt;
    case keymember(From, 1, User_List) of
      true -&amp;gt;
        server(User_List, Task_List);
      false -&amp;gt;
        String = makeString(Prefix),
        From!{Hashes, String, ClientRange},
        New_User_List=[{From, Hashes, String, ClientRange}|User_List],
        server(New_User_List, next([{Prefix, Hashes, ClientRange}|Task_List]))
    end;
  {'EXIT', From, _} -&amp;gt;
    {value, {_, Old_Hashes, String, Task} } = keysearch(From, 1, User_List),
    New_User_List=keydelete(From, 1, User_List),
    server(New_User_List, [makeTask(String, Old_Hashes, Task)|Task_List]);
  #notfound{client_pid=From} -&amp;gt;
    String = makeString(Prefix),
    New_User_List = keyreplace(From, 1, User_List, {From, Hashes, String, ClientRange}),
    From!{Hashes, String, ClientRange},
    server(New_User_List, next([{Prefix, Hashes, ClientRange}|Task_List]));
  #found{client_pid=From, result=Result} -&amp;gt;
    {Solved_Hashes,_} = unzip(Result),
    New_Hashes=subtract(Hashes,Solved_Hashes),
    String = makeString(Prefix),
    From!{New_Hashes, String, ClientRange},
    master!Result,
    New_User_List = keyreplace(From, 1, User_List, {From, Hashes, String, ClientRange}),
    server(New_User_List, next([{Prefix, New_Hashes, ClientRange}|Task_List]))
end;
server(_, []) -&amp;gt;
  exit(normal).

server(Task_List) -&amp;gt;
  process_flag(trap_exit, true),
  New_Task_List = makeTasks(Task_List),
  server([], New_Task_List).

%%% Запуск сервера

start_server(Task_List) -&amp;gt;
  register(bruteserver, spawn(?MODULE, server, [Task_List])).

makeTasks([{Hashes,Range}|Rest]) -&amp;gt;
  {ServerRange,ClientRange}=split(length(Range)-3, Range),
  [{Hashes, ClientRange, makeServerSide(ServerRange)}|makeTasks(Rest)];
makeTasks([]) -&amp;gt; [].

makeString([{I,_,Sym}|Rest]) -&amp;gt; [nth(I,Sym)|makeString(Rest)];
makeString([]) -&amp;gt; [].

makeTask(String, Old_Hashes, Task) -&amp;gt;
  {map(fun(x)-&amp;gt;{1, 1, x} end, String), Old_Hashes, Task}.

makeServerSide([Sym|Rest]) -&amp;gt; [{1, length(Sym), Sym}|makeServerSide(Rest)];
makeServerSide([]) -&amp;gt; [].

next([{Prefix, _, _}|Rest]) -&amp;gt;
  {F,Pnext}=next2(Prefix),
  if
    F==1 -&amp;gt; [Pnext|Rest];
    true -&amp;gt; Rest
  end.

next2([])-&amp;gt;	{0,[]};
next2([{I,L,Sym}|Rest])-&amp;gt;
  if
    I&amp;lt;L-&amp;gt;	{1,[{I+1,L,Sym}|Rest]};
    true-&amp;gt;
      {Flag,R}=next2(Rest),
      {Flag,[{1,L,Sym}|R]}
  end.
&amp;gt;

Код клиента
&amp;lt;-module(client).
-export([start_client/1, passes/2, pass/1]).

client(Server_Node)-&amp;gt;
{bruteserver, Server_Node}!{logon, self()},
receive
  A-&amp;gt;io:format(\&quot;client got ~p~n\&quot;,[A])
end.

start_client(Server_Node)-&amp;gt;
spawn(client, client, [Server_Node]).

passes(Hashes,Range)-&amp;gt;
  [P||P&amp;lt;-pass(Range), H&amp;lt;-Hashes, erlang:md5(P)==H].

pass([X|Xs])-&amp;gt;
[[A|B] || A&amp;lt;-X, B&amp;lt;-pass(Xs)];
pass([])-&amp;gt; [[]].&amp;gt;
&lt;/code&gt;&lt;/pre&gt;</description>
</item>
<item>
<title>dmitriid   "Литература"</title>
<link>http://erlang.dmitriid.com/forum/topic/7#post-55</link>
<pubDate>Sun, 18 Nov 2007 11:42:15 +0000</pubDate>
<dc:creator>dmitriid</dc:creator>
<guid isPermaLink="false">55@http://erlang.dmitriid.com/forum/</guid>
<description>&lt;p&gt;Еще обширный ответ здесь: &lt;a href=&quot;http://rsdn.ru/forum/message/2733230.aspx&quot; rel=&quot;nofollow&quot;&gt;http://rsdn.ru/forum/message/2733230.aspx&lt;/a&gt;
&lt;/p&gt;</description>
</item>
<item>
<title>dmitriid   "Литература"</title>
<link>http://erlang.dmitriid.com/forum/topic/7#post-54</link>
<pubDate>Sat, 17 Nov 2007 11:33:31 +0000</pubDate>
<dc:creator>dmitriid</dc:creator>
<guid isPermaLink="false">54@http://erlang.dmitriid.com/forum/</guid>
<description>&lt;p&gt;К сожалению, именно эту статью найти пока не смог. Есть вот такое: &lt;/p&gt;
&lt;p&gt;Towards a Strongly Typed Functional Operating System (2003)&lt;br /&gt;
Arjen van Weelden, Rinus Plasmeijer&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://citeseer.ist.psu.edu/vanweelden03towards.html&quot; rel=&quot;nofollow&quot;&gt;http://citeseer.ist.psu.edu/vanweelden03towards.html&lt;/a&gt;
&lt;/p&gt;</description>
</item>
<item>
<title>Cyberon   "Литература"</title>
<link>http://erlang.dmitriid.com/forum/topic/7#post-53</link>
<pubDate>Fri, 16 Nov 2007 20:07:29 +0000</pubDate>
<dc:creator>Cyberon</dc:creator>
<guid isPermaLink="false">53@http://erlang.dmitriid.com/forum/</guid>
<description>&lt;p&gt;На сайте softcraft.ru нашел статью &quot;Сильные стороны функционального программирования&quot;. В списке литературы в конце упоминалась книга P.Henderson. Purely Functional Operating Systems. 1982 Было бы интересно почитать что такое функциональная операционная система. Выложите, пожалуйста, ссылку.
&lt;/p&gt;</description>
</item>

</channel>
</rss>
