<?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 по-русски. Форум Тема: Как обойтись без наследования?</title>
<link>http://erlang.dmitriid.com/forum/</link>
<description>Erlang по-русски. Форум Тема: Как обойтись без наследования?</description>
<language>en</language>
<pubDate>Tue, 18 Nov 2008 04:33:06 +0000</pubDate>

<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>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>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>

</channel>
</rss>
