Статья про развитие идей ООП. Жду комментариев.
От: Voblin Россия http://maslyaew.narod.ru/
Дата: 08.05.03 08:54
Оценка: 34 (7)
Может быть, кому-нибудь будет интересно.
http://voblin.nm.ru/objects_classes.dhtml
Сразу вопрос: стоит ли это опубликовать в RSDN?
Re[5]: Mixins - вариант множественного наследования?
От: Kluev  
Дата: 11.05.03 08:11
Оценка: 41 (4) +1
Здравствуйте, Voblin, Вы писали:

V>То, что предлагаю я, вообще обходися без наследования. То есть в самом прямом смысле — мы можем обойтись безо всякой иерархии классов. Составление "коктейля", содержащего все необходимые "примеси" происходит по мере необходимости.


V>В простейшем случае объект может являться смесью, составленной из любого произвольного сочетания объявленных в программе классов.


V>В более сложном случае (для этого нужно приложить соответствующее усилие при программировании) мы можем наложить условие, что, например, объект может быть либо Male, либо Female, а и тем и другим одновременно быть не может. Да простят меня представители сексуальных меньшинств


V>Насколько я понял, ни в одном из существующих языков программирования нет возможности породить экземпляр более чем двух классов. Например, вот так:


V>
V> ' VB
V> Dim MyObj As (Person, Male)
V>


V>
V> // C++
V> (Person, Male) *MyObj;
V>


Почему же нет возможности? Немного смекалки и все будет

typedef const char cchar_t;

// примесь обьекта
template <class I, class T>
struct Part : I {
    T& self() { return *static_cast<T*>(this); }
};

// Абстрактный фрукт
struct IFruit {
    cchar_t* kind() { return _IFruit_kind(); }
protected:
    virtual cchar_t* _IFruit_kind() = 0;
};

// Абстрактный цветной обьект
struct IColored {
    cchar_t* color_get() { return _IColored_color_get(); }
    void color_set( cchar_t *color ) { _IColored_color_set( color ); }
protected:
    virtual cchar_t* _IColored_color_get() = 0;
    virtual void _IColored_color_set( cchar_t* ) = 0;
};

// цветной фрукт (подразумевается наличие в классе IColored и IFruit)
struct IColoredFruit {
    cchar_t* name() { return _IColoredFruit_name(); }
protected:
    virtual cchar_t* _IColoredFruit_name() = 0;
};

// яблоко
template <class T>
class Apple : public Part<IFruit,T> {
    cchar_t* _IFruit_kind() { return "apple"; }
};

// манго
template <class T>
class Mango : public Part<IFruit,T> {
    cchar_t* _IFruit_kind() { return "mango"; }
};

// абстрактный цветной обьект. реализация
template <class T>
class Colored : public Part<IColored,T> {
    std::string    _m_color;

    cchar_t* _IColored_color_get() { return _m_color.c_str(); }
    void _IColored_color_set( cchar_t *color ) { _m_color = color; }
};

// цветной фрукт
template <class T>
class ColoredFruit : public Part<IColoredFruit,T> {
    cchar_t* _IColoredFruit_name() {
        static char buf[80];
        sprintf( buf, "%s %s", self().IColored::color_get(), self().IFruit::kind() );
        return buf;

    }
};

// а теперь будем химичить
struct MyApple :
    Apple<MyApple>,
    Colored<MyApple>,
    ColoredFruit<MyApple>
{
};

struct MyMango :
    Mango<MyMango>,
    Colored<MyMango>,
    ColoredFruit<MyMango>
{
};

void test() {
    MyApple a;
    MyMango m;

    a.color_set( "green" );
    m.color_set( "red" );

    cchar_t *a_name = a.name(); // green apple
    cchar_t *m_name = m.name(); // red mango
}


Как видите интерфейсы IFruit, IColored, IColoredFruit не связаны узами наследования однако все работает
Re[2]: ВЫШЛА НОВАЯ ВЕРСИЯ
От: _vovin http://www.pragmatic-architect.com
Дата: 17.06.03 12:19
Оценка: 48 (4)
Здравствуйте, Voblin, Вы писали:

V>Прочитать можно там же.


Сдается мне, вас понесло не в ту сторону.

В работе никак не отражены важнейшие результаты, полученные за последние двадцать пять лет.

И упор делает все на тот же статический ООП, который сводит объектный подход фактически на нет.

Об этом постоянно предупреждал Алан Кей.
Он указывал на то, что ООП свели к второстепенным деталям — inheritance и reuse. В то время, когда вся идея целиком построена вокруг messaging. И важнейшим выигрышем является не reuse, как принято считать, а immediacy — опыт непосредственного взаимодействия с объектной системой, что позволяет певратить компьютер в такой же инструмент (для работы или творчества) как карандаш, книгу и т.д.

Эта проблема четко указывается даже в такой критической статье как Objects Have Failed (by Richard Gabriel)
===
Objects, as envisioned by the designers of languages like Smalltalk and Actors—long before C++ and Java came around— were for modeling and building complex, dynamic worlds. Programming environments for languages like Smalltalk were written in those languages and were extensible by developers. Because the philosophy of dynamic change was part of the post-Simula OO worldview, languages and environments of that era were highly dynamic.

But with C++ and Java, the dynamic thinking fostered by object-oriented languages was nearly fatally assaulted by the theology of static thinking inherited from our mathematical heritage and the assumptions built into our views of computing by Charles Babbage whose factory-building worldview was dominated by omniscience and omnipotence.

And as a result we find that object-oriented languages have succumb to static thinkers who worship perfect planning over runtime adaptability, early decisions over late ones, and the wisdom of compilers over the cleverness of failure detection and repair.
===

В последнее годы Алан Кей прочитал ряд интересных лекций:
The Computer Revolution Hasn't Happened Yet
Daddy, Are We There Yet?
Croquet: A Collaboration Architecture

В них стречается ряд интересных высказываний:
* Последние 30 лет были скучными в IT, не сделано никаких сколь-нибудь значительных открытий
* То, что Croquet реализован на Squeak (фактически Smalltalk-80 — технология 75-ого), фактически является показателем ужасного состояния IT индустрии. Получается, с тем пор не было предложено ничего лучшего в рамках объектного подхода.
* Lisp фактически явился главных фундаментом при создании объектного подхода. Это некий математический объект, способный описать самого себя. Оттуда были взяты идеи динамической среды и наличие максимально простой масштабируемой концепции.
* Java не внесла абсолютно ничего нового в науку (изначально являясь языком, разработанным для тостеров). И она преподается в университетах под маркой Computer Science. Ее преподавание сгодилось бы в рамках курсов выходного дня, но никак не CS.

Также Алан Кей считает, что за последние десятилетия наиболее важной работой в этой сфере является PIE — Layered Approach (by Ira Goldstein and Daniel Bobrow).
Туда же можно приплюсовать работу создателей языка Self — A Simple and Unifying Approach to Subjective Objects (by Randall Smith and David Ungar).

В этих работах рассматривается вопрос представления объектной системы по-разному с разных точек зрения. Фактически субъектно-ориентированный подход. По-видимому, это следующий логический шаг в развитии ОО.

--

Владимир.
Re[8]: Ой
От: Kluev  
Дата: 13.05.03 15:01
Оценка: 4 (2)
Здравствуйте, Kluev, Вы писали:

Забыл написать про наследование. Оно используется только для склеивания отдельных кусков в класс реализацию. Такой подход позволяет полностью абстрагироватся от способа реализации интерфейса, Что было показана на примере MyApple и MyMango.

Если вы опасаетесь что шаблоны непомерно раздуют код можно ограничить их использование следующим образом:

// Тяжелый класс (не шаблонный)
class MyObject : public IFoo, public IXoo, public IZoo, public IMoo {
protected:
// этот класс требует для своей работы следующие интерфейсы:
    virtual IxFoo& _MyObject_IxFoo() = 0;
    virtual IxZoo& _MyObject_IxZoo() = 0;

public:

    // 500 функций опущено
};

// Легкая шаблонная обертка
template <class T>
struct TMyObject : Part<MyObject,T> {
// этот код гарантирует поддержку классом Т интерфейсов IxFoo, IxZoo
    IxFoo& _MyObject_IxFoo() { return self(); }
    IxZoo& _MyObject_IxFoo() { return self(); }
};

// Теперь можно собирать по кусочкам:
struct Test1 :
    TMyObject<Test>,
    TMyIxFooImpl<Test1>,
    TMyIxZooImpl<Test2>
{
    // ..............
};

struct Test2 :
    TMyObject<Test2>,
    TMy_Another_IxFoo_And_IxZoo_Impl_in_single_class<Test2>
{
    // ..............
};


Это добавит к разарботке дополнительный шаг (необходимость написания обертки), зато выгоды моут быть потрясающими. К примеру несколько программистов независимо друг от друга разарабатывают очень сложный класс. Каждый их них пишет свою часть, учитывая что его коллеги занимаются реализацией остальных частей которые будут доступны через соответствующие интерфейсы. Пока класс не написан каждый программер пишет для себя урезанную-тестовую реализацию остальных интерфейсов (обычно это не занимает много времени)

// Кусок класса который пишет Иванов
class CIvanovFinalPart : public IIvanovPart {
protected:
    virtual ISidorovPart &_CIvanovPart_SidorovPart() = 0;
    virtual IPetrovPart &_CIvanovPart_SidorovPart() = 0;
};

// Реализация для тестирования
struct CIVanovTest :
    TIvanovFinalPart<CIVanovTest>,
    TSidorovDummyPart<CIVanovTest>,
    TPetrovDummyPart<CIVanovTest>
{
    // .......................
};


Когда все части готовы, они обьединяются в одном классе, а тестовые реализации выкидываются

// окончательная реализация:
class CFinalUltimateClass :
    public TIvanovFinalPart<CFinalUltimateClass>,
    public TSidorovFinalPart<CFinalUltimateClass>,
    public TPetrovFinalPart<CFinalUltimateClass>
{
    // .. здесь могут быть решены мелкие проблеммы
};
Re[7]: Ой
От: Kluev  
Дата: 13.05.03 14:22
Оценка: +2
Здравствуйте, Voblin, Вы писали:

V>Здравствуйте, Kluev, Вы писали:


K>Как видите интерфейсы IFruit, IColored, IColoredFruit не связаны узами наследования однако все работает


V>По-моему, как раз получается связано наследованием. Или я чего-то не понял?

Не связаны — ни один из интерфейсов не наследуется от другого. Реализация, однако, связана отношениями использования.
cchar_t* ColoredFruit::_IColoredFruit_name() {
   static char buf[80];
   sprintf( buf, "%s %s", self().IColored::color_get(), self().IFruit::kind() );
   return buf;
}

Сами понимаете, что "ЦветнойФрукт" не может существовать без "Фрукта" и "Цвета"

V>Вы вообще поняли, насколько СТРАШНЫМ получился код? Насколько запутанная у него логика работы? Насколько тяжёлым будет его сопровождение?

Обычный код, ничего страшного. Логика работы крайне простая т.к. кроме отношений "использования" больше ничего не не используется. Сопровождение и чтение кода наоборот будет лекгим как перышко за счет использования нотации: _Classname_attribname_functionname:
self().IColored::color_get(), self().IFruit::kind() — компилятор сразу покажет какие функции должен поддерживать "верхний" обьект, а по именам легко определить название интерфейсов.

V>За возможность хранить или не хранить информацию о цвете в объекте "Фрукт" мы заплатили такую высокую цену, что победа оказалась пиррова.

О какой цене идет речь?

V>А вообще, спасибо за иллюстрацию применения mixin-ов. Это было очень любопытно


Я долго ломал голову чтобы придумать абстрактный пример в котором не пришлось бы добавлять код в классах реализации. В реальной жизни увы не получится собирать классы из кирпичиков. Почти всегда требуется дополнительная реализация. К примеру если бы мы завели интерфейс
struct IObject {
   const char* _IObject_fullName_get() = 0;
}

То в классах реализации без изменений не обойтись
struct MyApple :
    Apple<MyApple>,
    Colored<MyApple>,
    ColoredFruit<MyApple>,
    Part<IObject,MyApple>
{
    const char* _IObject_fullName_get() {
        static char buf[100];
        sprintf( buf,"%s %s Fruit", color_get(), kind() );
        return buf; // red apple fruit
    }
};


То что предлагаете вы будет работать только в простых случаях не представляющих интереса. Я никогда не поверю в то, что следующий код будет работать
class LinuxWindow;
class Win32Window;
class DBView;

var dbvLnx as (LinuxWindow,DBView)
var dbvWin as (Win32Window,DBView)
Re[12]: Статья про развитие идей ООП. Жду комментариев.
От: WolfHound  
Дата: 22.06.03 06:30
Оценка: +2
Здравствуйте, <Аноним>, Вы писали:

А>Короче, я привел ссылки. Кого интересует программирование, как наука и исскуство, а не только как не особо напряжный способ заработать на жизнь лабая формы в VS, могут найти там что-нибудь интересное.

Есть такой язык называется С++ там есть такое слово template. Его виртуозное использование это функциональное программирование чистой воды. Целью которого служит генерация кода. Что позволяет писать в несколько раз меньше кода. Зная об этом разработчики VC++7.1 сделали просто потряающий оптимизатор который генерирует код по эффективности почти равный ручной работе на asm'е. К стати, а как обстаят дела со скоростью выполнения на этих навороченых функциональных языках?

ЗЫ Прочитай Александреску возможно поймешь что с С++ далеко не все так просто.
ЗЗЫ Кто знает функциональную сортировку O(N*log(N)) дайте линк.
ЗЗЗЫ Для некоторых типов данных возможна сортировка O(N) ищи Radix sort, а на функциональном слабо?
... << RSDN@Home 1.0 beta 6a >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[6]: Mixins - вариант множественного наследования?
От: WolfHound  
Дата: 13.05.03 16:41
Оценка: 12 (1)
Здравствуйте, Kluev, Вы писали:

K>Почему же нет возможности? Немного смекалки и все будет

А если еще подумать то можно прикрутить контроль
template<class I, class T>struct InterfaceCheck{};
#define INTERFACE_CHECK(cur, test)\
STATIC_CHECK(Loki::SuperSubclass<test, T>::value, if_class_is_##cur##_then_it_must_be_##test)

template <class I, class T>
struct Part
    :I
{
    T& self() { return *static_cast<T*>(this); }
private:
    typedef InterfaceCheck<I, T> dummy;
};

struct IColored{};
struct IFruit{};

struct IColoredFruit{};
template<class T>
struct InterfaceCheck<IColoredFruit, T>
{
    INTERFACE_CHECK(IColoredFruit, IColored)
    INTERFACE_CHECK(IColoredFruit, IFruit)
};

Теперь если попробовать создать обьект содержащий IColoredFruit но не содержащий IFruit или IColored то компилятор будет громко ругаться.
ЗЫ Писал без компилятора.
ЗЗЫ Ну что за дурацкая привычка _*?
... << RSDN@Home 1.0 beta 6a >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[6]: Ну при чём здесь singleton?
От: Voblin Россия http://maslyaew.narod.ru/
Дата: 08.05.03 14:48
Оценка: 9 (1)
Здравствуйте, joker6413, Вы писали:

J>Вот только я так и не понял сути — судя по картинке мы отказываемся от одиночного наследования в пользу множественного, плодим singletonы и вуаля — все по новому? В чем новизна?


Если под этим понятием скрывается паттерн проектирования "Одиночка".

Новизна — в сознательном отказе от концепции наследования и в том, что при этом мы получаем даже бОльшую возможность обобщения, бОльшую гибкость в плане полиморфизма, начинаем говорить с реляционными БД на одном языке, значительно улучшается расширяемость систем, отпадает необходимость всяких уродств типа абстрактных классов и темплэйтов и, в конце концов, можем делать объектную модель похожей на реальное положение вещей

Просьба: не надо меня размазывать по стенке за нелюбовь к темплэйтам. Я знаю что это такое и умею применять, но каждый раз после того, как такое случается, с чувством омерзения иду мыть руки. А потом иду смотреть, не добавила ли моя невинная шалось к размеру exeшника лишних килобайт 100
Re[5]: Mixins - вариант множественного наследования?
От: Akzhan Россия http://www.akzhan.midi.ru/devcorner/
Дата: 10.05.03 15:51
Оценка: 9 (1)
Здравствуйте, Voblin, Вы писали:

V>
V> ' VB
V> Dim MyObj As (Person, Male)
V>


В варианте mixin architecture это выглядит так же, но более строго. Поэтому все возможные ошибки ловятся ещё на этапе компиляции. Единственное разлчие — невозможность динамического изменения типа — мутации. Другое дело, что я считаю мутации объектов вредной техникой с точки зрения поддержки кода. Но если нужны мутации, то надо использовать паттерн объект-стратегия.

class CMyObject : 
  public CCompoundObject, CPersonT<CMyObject>, CMaleT<CMyObject>
{
};

CMyObject myObj;
С уважением,
Акжан, http://www.akzhan.midi.ru/devcorner/ — мой уголок разработчика
Re[3]: Статья про развитие идей ООП. Жду комментариев.
От: Akzhan Россия http://www.akzhan.midi.ru/devcorner/
Дата: 09.05.03 10:36
Оценка: 6 (1)
Здравствуйте, Voblin, Вы писали:

A>Типичная mixing library, на мой взгляд, это ATL/WTL.

V>Где можно прочитать про Class mixing?

смотрите тему Mixin-Based Programming in C++ и тому подобные.

например, http://c2.com/cgi/wiki?MixIn
http://www.ddj.com/documents/ddj0101i/
http://citeseer.nj.nec.com/bracha90mixinbased.html
С уважением,
Акжан, http://www.akzhan.midi.ru/devcorner/ — мой уголок разработчика
Re: Статья про развитие идей ООП. Жду комментариев.
От: Akzhan Россия http://www.akzhan.midi.ru/devcorner/
Дата: 14.05.03 07:08
Оценка: 6 (1)
Здравствуйте, Voblin, Вы писали:

http://www.rsdn.ru/Forum/Message.aspx?mid=266637&amp;only=1
Автор: PM
Дата: 14.05.03
С уважением,
Акжан, http://www.akzhan.midi.ru/devcorner/ — мой уголок разработчика
Re[17]: Статья про развитие идей ООП. Жду комментариев.
От: Аноним  
Дата: 25.06.03 12:05
Оценка: 6 (1)
Здравствуйте, Sergey, Вы писали:

Да, спасибо, я уже понял все это на примере приведенном выше. Но у меня есть пара замечаний, которые я привел в том числе и к тому примеру.
Не рекомендовал бы изучать ФП на примере шаблонов. Уж больно там запутанный синтаксис, корявые средства построения программ, да и язык сам по себе уж больно примитивный. Шаблоны по сути довесок к С++ и может сложиться мнение, что ФП в целом малопонятно и нежизнеспособно само по себе. Уж лучше изучить нормальный язык, а потом разбираться с шаблонами, как мне кажется. Кроме того, возникает ощущение, что функциональность шаблонов это side effect, а не главная цель. Хотя я не знаю, какая была мотивация у разработчиков, может и ошибаюсь.

S>На вкус и на цвет... Мне примеры на ocaml'е с непривычки тоже уродливыми кажутся.

Здесь дело не во внешней красоте, а в том, что для шаблонов нужно огромное количество писанины, в которой еще потом и ошибки искать придется, а я помню насколько понятные бывают сообщения об ошибках, когда речь идет о шаблонах.

S>Это издержки исчисления типов, а вовсе не их избыточного указания.

Ну я всего лишь имел ввиду, что могут быть такие исчисления, где их вообще почти ненужно указывать, все само выводится.

S>Это уже я не понял. Че оно делает-то и в чем тут "частичность"?

По научному curring. Одно из главных отличий от императивных языков, мы можем писать f x1 x2 x3 вместо f(x1,x2,x3), а потом явно указать, например x3 и использовать уже функцию от 2-х аргументов. Крайне полезное свойство.
Re[2]: ВЫШЛА НОВАЯ ВЕРСИЯ
От: Akzhan Россия http://www.akzhan.midi.ru/devcorner/
Дата: 17.06.03 08:17
Оценка: 4 (1)
Здравствуйте, Voblin, Вы писали:

V>Прочитать можно там же.


Чем дольше думаю, тем явственнее мысль — не туда забрели.

В своей статье Вы полагаете объект некоей кучей иных объектов

Хотя все Ваши цитаты из реального мира прямо говорят о дргом подходе:
Объекты в природе сами по себе целостны (как Вы говорите, элементарны).

А множество определений для одного и тог же объекта можно строго определить различными точками зрения на один и тот объект (в принципе отсюда в оригинале и пляшет концепция контрактов-интерфейсов).

Вдумайтесь: та же кошка не является кучей точек зрения, вместе собирающихся в нечто единое (подход слепцов и слона). Наоборот — кошка — это строго и заранее определённый (с точностью до реализации) объект, который наше восприятие способно воспринимать с различных точек зрения.

Отсюда вывод: небоходимость динамической генерации комплексных типов взята с потолка. Когка должа быть определена на этапе разработки библиотеки "животный мир/кошачьи".

Можно для нашего класса
WorldObject
создать некие методы
bool queryViewPoint(ViewPointId viewPointId, out ViewPointContract viewPointContract);

static void registerViewPoint(ViewPointId viewPointId, ViewPointContractFactory viewPointContractFactory);

И тогда мы получим возможность один и тот объект рассматривать с различных точек зрения. Причём набор этих точек зрения формируя динамически.

Между прочим, эта метафора реализована в dotNET Component Model — IServiceContainer/IServiceProvider idiom.
С уважением,
Акжан, http://www.akzhan.midi.ru/devcorner/ — мой уголок разработчика
Re: Статья про развитие идей ООП. Жду комментариев.
От: Sinclair Россия https://github.com/evilguest/
Дата: 14.05.03 07:35
Оценка: 3 (1)
Здравствуйте, Voblin, Вы писали:

V>Может быть, кому-нибудь будет интересно.

V>http://voblin.nm.ru/objects_classes.dhtml
V>Сразу вопрос: стоит ли это опубликовать в RSDN?
Что-то я так и не понял, чем же это отличается от "классического ООП в духе Страуструпа".
Ну, вот есть у нас классы. (Все классически). Ну вот может объект принадлежать к нескольким классам — тоже классика. (Вообще говоря, любой ациклический граф соответствует валидной схеме наследования классов).
Связанность цепочек наследования классов — это жупел. Если собака является живым существом, то интерфейс собаки существенно зависит от того, что она живое существо. Говоря проще, появление собаки Айбо (не знаю, кто это такой) нарушает картину только в силу некомпетентности архитектора. В хорошей модели способность собаки гавкать и способность гадить не связаны между собой отношенями наследования:
interface IBark {
  void Bark();
}
interface ICreature {
  void Live();
}
interface IGadget {
  void Execute();
}

class LiveDog : public ICreature, IBark {};
class ElectronicDog : public IGadget, IBark {};


Требование

присутствия возможности задания перечня классов непосредственно для каждого объекта

давно удовлетворено в классике. Никто не мешает писать так:
  class _useonceforIbo_ : piblic IGadget, IBark{} *Ibo = new _useonceforIbo_();

хотя так делать и не стоит. А не стоит потому, что теперь мы получили объект уникального класса. Легкая модификация:
  class _useonceforIbo_ : piblic IGadget, IBark{} *Ibo = new _useonceforIbo_();
  class _useonceforIbo2_ : piblic IGadget, IBark{} *IboSon = new _useonceforIbo2_();

и упс! У нас два объекта различных классов. Хотя набор интерфейсов в точности совпадает.
Так что на диаграмме надо бы стереть слова "Non-classic".
Ага, дальше мы собрались отказаться от наследования и вместо "реального" класса XY: public X, Y {} ввести виртуальный класс XY. Пардон, а чем он так радикально отличается от своего "реального" тезки?

Вооружившись комбинаторикой, можно вспомнить, что количество сочетаний N классов, выбранных среди K существующих (без учета порядка), равно С(K, N) = K!/(N!*(K-N)!))


Обычно создают родительский класс clPersistent, имеющий методы Read() и Save(), и классы clClient и clOrder порождают (возможно, косвенно) от Persistent.
Мы же, вооружившись С++, тоже создадим
class clPersistent {
  virtual void Read()=0;
  virtual void Save()=0;
}

и классы
class clOrder {
  SomeOrderMethod();
}
class clClient {
  SomeClientMethod();
}

Запись реквизитов контрагента в базу данных будет производиться в процедуре Save() класса clPersistentClient: public clPersistent, clClient{}, а реквизитов заказа — в процедуре, реализованной для clPersistentOrder: public clPersistent, clOrder{}.
Ну да, анси паскаль отдыхает. Впрочем, мы и раньше это знали.

Правда, нам не удастся с такой легкостью отказаться от абстрактного класса clPersistent, который только что был нам нужен — он просто не может быть конкретным. Ведь он не знает, что нужно читать или сохранять. Но мы поступим хитро, и, чтобы разработчик не рисковал забыть реализовать спопоб записи ордеров, переделаем класс так, чтобы его методы были просто пустыми. Правда, теперь забывчивый разработчик сможет скомпилировать программу без единой ошибки от компилятора (которая выдается С++) и даже запустить ее без аварийного завершения (стандартное поведение Delphi. Впрочем, в Delphi мы полностью свободны в выборе того, что делать при возниковении Abstract Call во время выполнения). Пользователю останется только гадать, почему его заказы не пишутся в базу.

Я не очень понял пассаж про вызов метода класса XZ для объекта класса XY. Вот если бы наш объект был класса XYZ, тогда бы эта кандидатура была бы оправдана.
Ок, давайте рассмотрим такую ситуацию:
1. У нас есть классы X, Y, и Z. Пусть у нас есть метод X::M().
2. Теперь мы создаем класс XY и переопределяем для него метод XY::M(). В данный момент принудительный вызов обоих версий метода кажется совершенно излишним — если бы классический программист хотел этого добиться, то он бы просто вставил этот вызов в тело XY::M(), при этом полностью управляя последовательностью вызовов.
3. Теперь мы порождаем класс XYZ и снова переопределяем M(). Предыдущее рассуждение все еще остается справедливым — хорошо смеется тот, кто стреляет последним.
4. А вот теперь кто-то приходит и добавляет в систему класс XZ. С точки зрения классического программиста, это не приносит ничего нового, ибо класс XYZ c ним никак не связан. Наша неклассическая система считает себя умнее программиста, и вызывает X::M(), XY::M(), XZ::M(), XYZ::M() в неопределенном порядке, предоставляя каждой версии доступ на чтение к наиболее свежему кандидату на возвращаемое значение. И об этом неклассический программист просто проинформирован. Нда, я пока не готов стать неклассическим программистом — я бы все же предпочел иметь немного больше контроля над развитием событий.

Все дальнейшие рассуждения в статье без особых оговорок применимы к С++, вплоть до реляционных БД.
Проблемы объединения ООП и РСУБД никак не связаны с трудностями отображения объектов на таблицы. И уж конечно, фиксация единственного способа отображения не является решением подобной проблемы, даже если бы она и была. Трудности начинаются в тот момент, когда нужно выбрать те из объектов класса X, у которых метод M() возвращает 0. Если вспомнить о том, что у нас есть еще классы XY, XZ, и XYZ, то можно сразу выбросить на помойку идею применить индекс к этому запросу — увы, метод M виртуален. И даже для детерминированных методов (от которых мы только что отказались, решив вызывать все подряд) поиск оптимального плана выполнения такого запроса значительно сложнее, чем для типичного RDBMS запроса.
А финальную фразу этого раздела я вообще не понял — как это у нас парадигма привязки произвольного набора классов к каждому объекту умудрилась хорошо просочетаться с теорией баз данных, учитывая выбранный способ отображения? Т.е. у нас теперь один объект — одна табличка? Нда, вряд ли бы корифеи реляционной алгебры это одобрили.

Заключение
Помимо очевидных внутренних нестыковок, я сумел найти единственное радикальное отличие предлагаемой технологии от "классического ООП". Это методика разрешения неопределенностей вызова виртуальных методов при множественном наследовании. Возможно, я ее просто не понял, но на первый взгляд она выглядит значительно хуже любой альтернативы, которую я только могу придумать.
... << RSDN@Home 1.0 beta 6a >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re: Статья про развитие идей ООП. Жду комментариев.
От: Sinclair Россия https://github.com/evilguest/
Дата: 14.05.03 07:40
Оценка: 3 (1)
Здравствуйте, Voblin, Вы писали:

Да, вдогонку даю ссылку на цикл статей по теории ООП, который мне очень понравился:

The Theory of Classification, Perspectives on Type Compatibility
The Theory of Classification, Part 2: The Scratch-Built Typechecker
The Theory of Classification, Part 3: Object Encoding and Recursion
The Theory of Classification, Part 4: Object Types and Subtyping
The Theory of Classification, Part 5: Axioms, Assertions and Subtyping
The Theory of Classification, Part 6: The Subtyping Inquisition
The Theory of Classification, Part 7: A Class is a Type Family
... << RSDN@Home 1.0 beta 6a >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: Статья про развитие идей ООП. Жду комментариев.
От: WolfHound  
Дата: 13.05.03 17:06
Оценка: +1
Здравствуйте, <Аноним>, Вы писали:

А>Даже примитивный С++ с его жалкими темплейтами оказался слишком сложен — и вот вам С#!

Я на C# хочу в основном из-за рефлекшена и некоторых других полезных возможностей.
ЗЫ С++ не такой уж и примитивный (я имею в виде С++, а не конкретные реализации) если уметь пользоваться.
... << RSDN@Home 1.0 beta 6a >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[6]: ВЫШЛА НОВАЯ ВЕРСИЯ
От: Voblin Россия http://maslyaew.narod.ru/
Дата: 17.06.03 14:11
Оценка: :)
Здравствуйте, vgrigor, Вы писали:

V>В сети я не нашел.

Эх, придётся наверно купить treeware версию. А значит и прочитать целиком. Чтением по диагонали уже чисто психологически не отделаться. Что обидно.
Re[10]: ВЫШЛА НОВАЯ ВЕРСИЯ
От: Voblin Россия http://maslyaew.narod.ru/
Дата: 17.06.03 14:55
Оценка: :)
Здравствуйте, vgrigor, Вы писали:



V>>Не trial, а treeware. От слова "дерево". Вычитал в руководстве по CVS, очень понравилось.


V>Это все что можешь сообщить?


Во блин, не дадут приколоться без того, чтобы не припёрли к стенке и не потребовали объяснения, в каком месте нужно смеяться.

Итак,

ENG  | RUS
--------------
tree | дерево
ware | изделие


Следовательно, treeware — изделие, сделанное из дерева. Или из его производного. Т.е. бумаги. Не путать с freeware, firmware и trial.

Уфф.
Re[5]: Статья про развитие идей ООП. Жду комментариев.
От: Lloyd Россия  
Дата: 20.06.03 10:40
Оценка: +1
Здравствуйте, Voblin, Вы писали:

L>>А почему на стрелочке Интерфейс — Класс стоит *-1, а не *-*?


V>Потому что "сильно упрощённая схема". Конечно, если подрисовать наследование и делегирование, то получится что-то вроде *-*, но сути это не сильно поменяет, т.к. основные различия, которые и хотелось проиллюстрировать находятся в правой части схемки.


Какое нафик наследование и делегирование?!

*-* означает:

1 класс может реализованть несколько (*) интерфейсов.
1 инетерфейс может быть реалтзован несколькими (*) классами.
Re: Статья про развитие идей ООП. Жду комментариев.
От: MadCoders Россия  
Дата: 08.05.03 09:28
Оценка:
Здравствуйте, Voblin, Вы писали:

V>Может быть, кому-нибудь будет интересно.

V>http://voblin.nm.ru/objects_classes.dhtml
V>Сразу вопрос: стоит ли это опубликовать в RSDN?

ну, написано неплохо, даже хорошо.
Мне понравилось, только по-моему, необходимо перед определением Объекта и экземпляра,дать определение класса.т.е. ты говоришь, что
Объект, экземпляр – информационная сущность, которой можно оперировать как единым целым.

что это за информационная сущность, мне кажеться. что
Класс является информационной сущностью,
а уже объектами класса можно оперировать как единым целым.


после определения класса стоит сказать, что можно создавать множество элементов, обладающих свойствами этого класса, и как раз эти элементы и являются Объектами.
т.е. можно привести жизненный пример:
у нас есть понятие сапожник,
если мы говорим, что Петя- сапожник, то все понимают, что Петя:
1)Мужского пола
2)Много материться

Ну вообще это только мое мнение.
...Почему разум становится более ленивым по мере развития технологий? Он привыкает к ним и не заботится о разработке новых...
Re[2]: Статья про развитие идей ООП. Жду комментариев.
От: Voblin Россия http://maslyaew.narod.ru/
Дата: 08.05.03 09:55
Оценка:
Здравствуйте, MadCoders, Вы писали:

MC>Мне понравилось, только по-моему, необходимо перед определением Объекта и экземпляра,дать определение класса.т.е. ты говоришь, что

MC> Объект, экземпляр – информационная сущность, которой можно оперировать как единым целым.

MC>что это за информационная сущность, мне кажеться. что

MC>Класс является информационной сущностью,
MC>а уже объектами класса можно оперировать как единым целым.

Изюминка в том и состоит, что отталкиваюсь я не от определения класса. Понятие класса появляется только в разделе "классификация". Если отталкиваться от понятия класса, то получится обычное, известное всем с пелёнок ООП, и ничего интересного не произойдёт.
Re: Статья про развитие идей ООП. Жду комментариев.
От: Аноним  
Дата: 08.05.03 10:00
Оценка:
Здравствуйте, Voblin, Вы писали:

V>Может быть, кому-нибудь будет интересно.

V>http://voblin.nm.ru/objects_classes.dhtml

Есть сильное подозрение, что в каких-нибудь исследовательских языках
все это давно рассмотрено и реализовано.
IMHO, в одном из диалектов LISP-а что-то подобное есть.
А в промышленные языки такое все-равно не пойдет — слишком сложно и для реализации,
и для использования.
Элементарные-то вещи реализовать в основных языках (С++, Java, C#, VB) не могут,
а тут такая революция.

V>Сразу вопрос: стоит ли это опубликовать в RSDN?


Конечно!
Re[2]: Статья про развитие идей ООП. Жду комментариев.
От: Voblin Россия http://maslyaew.narod.ru/
Дата: 08.05.03 10:31
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Есть сильное подозрение, что в каких-нибудь исследовательских языках

А>все это давно рассмотрено и реализовано.
Не удивлюсь.

А>IMHO, в одном из диалектов LISP-а что-то подобное есть.

Где-то когда-то всплывал CLOS.
По-моему, предлагаемое решение больше касается "обычных" языков программирования нежели языков логического программирования тип LISP и Prolog.

А>А в промышленные языки такое все-равно не пойдет — слишком сложно и для реализации,

А>и для использования.
Капля камень точит.
Реализация, конечно, сложновата, но, по-моему, овчинка выделки сторит.
Не добежим, так согреемся

А>Элементарные-то вещи реализовать в основных языках (С++, Java, C#, VB) не могут,

А>а тут такая революция.
А что делать?

V>Сразу вопрос: стоит ли это опубликовать в RSDN?

А>Конечно!
Попробую.
Re[3]: Статья про развитие идей ООП. Жду комментариев.
От: Аноним  
Дата: 08.05.03 11:15
Оценка:
Здравствуйте, Voblin, Вы писали:

V>Где-то когда-то всплывал CLOS.


Так он и сейчас есть (и компиляторы, и IDE, и библиотеки), а что толку? Кто на нем пишет?

V>По-моему, предлагаемое решение больше касается "обычных" языков программирования нежели языков логического программирования тип LISP и Prolog.


Что там такого в LISP-е логического?
Вполне "нормальньй" язык (относительно конечно), только возможностей много.
Вот никто и не пользуется — боятся, видимо.

V>Не добежим, так согреемся


Разве что.
Будет ли пользоваться успехом язык, в котором есть только одна фича (по сравнения, скажем с C#),
но зато полно недостатков — нет такой мощной поддержки, кучи библиотек (стандартных и сторонних),
серьезного компилятора и средства разработки, поддержки средств моделирования (например от Rational)
и т.п. и т.д. Можно продолжать бесконечно...

Сейчас наоборот наблюдается деградация языков программирования к более простым вариантам
(видимо программист пошел совсем недалекий).
Наглядный пример Java и VB — полные ничтожества в языковом плане, никаких понят... тьфу возможностей,
однако ведь лидеры промышленной разработки.
Где все разработки 70-х, 80-х годов — вычисляемые типы, контракты, пред- и постусловия, частично параметризованные функции,
лямбды, замыкания и т.д.?
Даже примитивный С++ с его жалкими темплейтами оказался слишком сложен — и вот вам С#!

Если же кого-то интересуют навороченные языковые возможности, то есть тот же CLOS, Smalltalk, SML, Haskell
(последний вроде как уже есть под .NET — H#).
Re[4]: Статья про развитие идей ООП. Жду комментариев.
От: joker6413  
Дата: 08.05.03 12:50
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Сейчас наоборот наблюдается деградация языков программирования к более простым вариантам

А>(видимо программист пошел совсем недалекий).

А по моему все логично. Индустрия развивается, задачи формализуются, приоритеты расставляются... Вспомните операционные системы 70-х, 80-х годов... убожество, с которым пытались справится с помощью навороченных языков. А проблема-то была в другом! В ублюдочных runtime и платформе ...

А>Наглядный пример Java и VB — полные ничтожества в языковом плане, никаких понят... тьфу возможностей,

А>однако ведь лидеры промышленной разработки.

Дык, они могут себе позволить быть ублюдочными... т.к. базируются на мощных платформах. Можно пойти дальше — я встречал проекты (как правило учет), в которых были реализованны системы метаданных (считай расширенная платформа). На абсолютно ублюдочном xml писались системы учета огромных складов, отделов кадров и т.д.

А>Где все разработки 70-х, 80-х годов — вычисляемые типы, контракты, пред- и постусловия, частично параметризованные функции,

А>лямбды, замыкания и т.д.?

И зачем это все? Жалкие попытки проэмулировать возможности COM...

А>Если же кого-то интересуют навороченные языковые возможности, то есть тот же CLOS, Smalltalk, SML, Haskell

А>(последний вроде как уже есть под .NET — H#).

Какие концептуальные задачи вы будете решать этими инструментами?

Игорь
Re[4]: Статья про развитие идей ООП. Жду комментариев.
От: Voblin Россия http://maslyaew.narod.ru/
Дата: 08.05.03 13:28
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Будет ли пользоваться успехом язык, в котором есть только одна фича (по сравнения, скажем с C#),

А>но зато полно недостатков — нет такой мощной поддержки, кучи библиотек (стандартных и сторонних),
А>серьезного компилятора и средства разработки, поддержки средств моделирования (например от Rational)
А>и т.п. и т.д. Можно продолжать бесконечно...
Стоп-стоп-стоп. Речь идёт не только и не столько о том, что неплохо было бы выдумать новый язык программирования и среду разработки к нему. Конечно, хочется слепить что-то по-быстрому для опытов, но создавать какой-то сверхмощный коробочный продукт и двигать его на роль индустриального стандарта... Об этом речь пока что не идёт.

Вопрос в том, имеет ли право на жизнь подход, основанный не на однозначной, а на множественной классификации, когда:


А>Сейчас наоборот наблюдается деградация языков программирования к более простым вариантам

А>(видимо программист пошел совсем недалекий).
Предложенная парадигма не проще и не сложнее обычного ООП. Она просто другая.
Re[5]: Статья про развитие идей ООП. Жду комментариев.
От: Voblin Россия http://maslyaew.narod.ru/
Дата: 08.05.03 13:30
Оценка:
Здравствуйте, joker6413, Вы писали:

А>Сейчас наоборот наблюдается деградация языков программирования к более простым вариантам

А>(видимо программист пошел совсем недалекий).

J>А по моему все логично. Индустрия развивается, задачи формализуются, приоритеты расставляются... Вспомните операционные системы 70-х, 80-х годов... убожество, с которым пытались справится с помощью навороченных языков. А проблема-то была в другом! В ублюдочных runtime и платформе ...


Давайте не будем разводить спор о том, какое средство разработки лучше. Это бессмысленно.
Re[6]: Статья про развитие идей ООП. Жду комментариев.
От: joker6413  
Дата: 08.05.03 13:52
Оценка:
Здравствуйте, Voblin, Вы писали:

V>Давайте не будем разводить спор о том, какое средство разработки лучше. Это бессмысленно.


Да я вобщем-то и не собирался... хороший — плохой, главное кто живой, а кто мертвый .

Игорь
Re[5]: Статья про развитие идей ООП. Жду комментариев.
От: joker6413  
Дата: 08.05.03 14:03
Оценка:
Здравствуйте, Voblin, Вы писали:

V>Стоп-стоп-стоп. Речь идёт не только и не столько о том, что неплохо было бы выдумать новый язык программирования и среду разработки к нему. Конечно, хочется слепить что-то по-быстрому для опытов, но создавать какой-то сверхмощный коробочный продукт и двигать его на роль индустриального стандарта... Об этом речь пока что не идёт.


Да я и не собирался затевать гнилой базар по поводу — "да зачем все это надо я ж на turbo pascal и так фсе напишу"...

V>Вопрос в том, имеет ли право на жизнь подход, основанный не на однозначной, а на множественной классификации, когда:


Вот только я так и не понял сути — судя по картинке мы отказываемся от одиночного наследования в пользу множественного, плодим singletonы и вуаля — все по новому? В чем новизна?

Игорь
Re: Статья про развитие идей ООП. Жду комментариев.
От: Akzhan Россия http://www.akzhan.midi.ru/devcorner/
Дата: 08.05.03 16:07
Оценка:
Здравствуйте, Voblin, Вы писали:

V>Может быть, кому-нибудь будет интересно.

V>http://voblin.nm.ru/objects_classes.dhtml
V>Сразу вопрос: стоит ли это опубликовать в RSDN?

Недостаток данного подхода именно в черзвычайной гибкости. Очевидно, это приведёт в строгому и сложному механизму органичения/разрешения/последовательности наследования.

Достаточно хорошим подходом является так называемый Class mixing. Объявляются так называемые классы-примеси, которые соответствуют строго определённым контрактам. И результирующие классы строятся с использованием классов-примесей, дающих необходимый вкус (flavour).

Типичная mixing library, на мой взгляд, это ATL/WTL.
С уважением,
Акжан, http://www.akzhan.midi.ru/devcorner/ — мой уголок разработчика
Re[2]: Статья про развитие идей ООП. Жду комментариев.
От: Voblin Россия http://maslyaew.narod.ru/
Дата: 08.05.03 17:05
Оценка:
Здравствуйте, Akzhan, Вы писали:

A>Недостаток данного подхода именно в черзвычайной гибкости. Очевидно, это приведёт в строгому и сложному механизму органичения/разрешения/последовательности наследования.

Конечно, если не предпринимать каких-то очень специальных действий, ничто не помешает создавать объекты самых бессмысленных сочетаний. Ну да, можно создать помесь кошки и собаки. Ну да, по команде "Голос" оно гавкнет и мяукнет...

Думаю, в сочетании со строгой типизацией катастроф не будет. Ведь в любом же языке программирования есть возможность написать что-то вроде "а = 1/0".

A>Достаточно хорошим подходом является так называемый Class mixing. Объявляются так называемые классы-примеси, которые соответствуют строго определённым контрактам. И результирующие классы строятся с использованием классов-примесей, дающих необходимый вкус (flavour).


A>Типичная mixing library, на мой взгляд, это ATL/WTL.


Где можно прочитать про Class mixing?
Yandex и Google вываливают кучу мусора
Re[3]: Статья про развитие идей ООП. Жду комментариев.
От: swinger  
Дата: 08.05.03 17:20
Оценка:
Здравствуйте, Voblin, Вы писали:

V>Где можно прочитать про Class mixing?

V>Yandex и Google вываливают кучу мусора

Александреску, Буч. Ключевое слово — "стратегия".
Re: Статья про развитие идей ООП. Жду комментариев.
От: Boris Гондурас  
Дата: 08.05.03 22:10
Оценка:
Здравствуйте, Voblin, Вы писали:

Я тут на досуге средствами C# и с системным подходом пытался моделировать структуры простейших геологических систем. Теперь есть ощущение, что средствами ООП сделать это (по крайней мере логично) нереально.
Ваши идеи выглядят очень привлекательно. Очень заинтересован в их развитии.
Конкретных комментариев, к сожалению, пока дать не могу, т.к. нет еще оформившихся мысел.

Удачи
... << RSDN@Home 1.0 beta 6a >>
Re[4]: Mixins - вариант множественного наследования?
От: Voblin Россия http://maslyaew.narod.ru/
Дата: 10.05.03 15:06
Оценка:
Здравствуйте, Akzhan, swinger

Насколько я понял из Ваших ссылок, механизм примесей по своей сути является вариантом множественного наследования и применяется там, где "лобовое" множественное наследование либо не поддерживается языком либо его не хочется применять.

То, что предлагаю я, вообще обходися без наследования. То есть в самом прямом смысле — мы можем обойтись безо всякой иерархии классов. Составление "коктейля", содержащего все необходимые "примеси" происходит по мере необходимости.

В простейшем случае объект может являться смесью, составленной из любого произвольного сочетания объявленных в программе классов.

В более сложном случае (для этого нужно приложить соответствующее усилие при программировании) мы можем наложить условие, что, например, объект может быть либо Male, либо Female, а и тем и другим одновременно быть не может. Да простят меня представители сексуальных меньшинств

Насколько я понял, ни в одном из существующих языков программирования нет возможности породить экземпляр более чем двух классов. Например, вот так:

 ' VB
 Dim MyObj As (Person, Male)


 // C++
 (Person, Male) *MyObj;


То, что описано в статье, мало того что позволяет так делать (подумаешь, ещё одна спорная "фича", к тому же потенциально весьма опасная), но и основывает на этом механизме технологию проведения безусловно самой главной фазы OOD — описание задачи в виде системы классов.
Re[6]: Шаблоны - не выход. Вернее, не всегда выход.
От: Voblin Россия http://maslyaew.narod.ru/
Дата: 13.05.03 11:31
Оценка:
Здравствуйте, Akzhan, Вы писали:

A>В варианте mixin architecture это выглядит так же, но более строго. Поэтому все возможные ошибки ловятся ещё на этапе компиляции. Единственное разлчие — невозможность динамического изменения типа — мутации. Другое дело, что я считаю мутации объектов вредной техникой с точки зрения поддержки кода. Но если нужны мутации, то надо использовать паттерн объект-стратегия.


A>
A>class CMyObject : 
A>  public CCompoundObject, CPersonT<CMyObject>, CMaleT<CMyObject>
A>{
A>};

A>CMyObject myObj;
A>


Тоже хороший подход. Сразу бросается в глаза вот что:
1. Делается на базе шаблонов. То есть мы заставляем компилятор генерировать некий "промежуточный" исходник, в котором все наши используемые сочетания обявлены явно и жёстко. Мало того, что генерируется большой объём кода (это не страшно, кто сейчас считает мегабайты?), но и за кадром может остаться множество
полезных сочетаний.
2. Мутация бывает очень полезна. Поясняю. Например, пользователь заводит карточку сотрудника. Пол он ещё не ввёл, и поэтому объект не принадлежит ни классу CMale, ни классу CFemale. Выбирает пол сотрудника — "Male". С этого момента неплохо было бы сменить тип редактируемого объекта на (CPerson, CMale).
3. В маленьком примерчике это смотрится нормально. Но если на секунду себе представить, как будет выглядеть система mixin-ов (и особенно результирующая система классов, получающаяся после компиляции шаблонов) какой-нибудь реальной системы, то станет страшно.

Пример из жизни.

Сотрудник — это живой человек (Person), мужчина или женщина
Person может быть сотрудником, а может и не быть сотрудником
Person может быть контрагентом, который, в свою очередь, может быть поставщиком и покупателем (либо и тем, и другим сразу)
Контрагент может быть физ. или юр. лицом (юр. лицо — не Person)
Юр. и физ. лицо бывают резидентами и нерезидентами
В выписываемый счёт в колонку "Item" мы должны иметь возможность вписать сотрудника, товар, услугу, ОС, НМА, материал.
Сотрудник может быть ресурсом (производственный рабочий, бизнес-консультант), а может и не быть ресурсом (бухгалтер, директор).
Ресурс может быть продаваемым (должна быть назначена цена) либо непродаваемым.
Сотрудник может являться пользователем.
Контрагент может являться пользователем (через web-интерфейс).
В базу данных заносятся родственники сотрудников, которые, как правило, сотрудниками не являются, но возможны исключения.
Ой-ой-ой! Чуть не забыл про акционеров!
-----------------------
Уффф... и это только маленький кусок системы!
Кто скажет, что пример надуманный?

Как тут выстроить систему классов? Что сделать mixin-ом и во что подмешивать?

Самое интересное, что если абстрагироваться от необходимости писать бизнес-логику на ОО-языке программирования, структура базы данных такой системы в общих чертах рисуется без особого интеллектуального перенапряжения. Но уложить такое в классы — свихнёшься.
Re[6]: Ой
От: Voblin Россия http://maslyaew.narod.ru/
Дата: 13.05.03 12:00
Оценка:
Здравствуйте, Kluev, Вы писали:

K>Как видите интерфейсы IFruit, IColored, IColoredFruit не связаны узами наследования однако все работает


По-моему, как раз получается связано наследованием. Или я чего-то не понял?

Вы вообще поняли, насколько СТРАШНЫМ получился код? Насколько запутанная у него логика работы? Насколько тяжёлым будет его сопровождение?

За возможность хранить или не хранить информацию о цвете в объекте "Фрукт" мы заплатили такую высокую цену, что победа оказалась пиррова.

А вообще, спасибо за иллюстрацию применения mixin-ов. Это было очень любопытно
Re[8]: Ой
От: Voblin Россия http://maslyaew.narod.ru/
Дата: 13.05.03 16:24
Оценка:
Здравствуйте, Kluev, Вы писали:

V>По-моему, как раз получается связано наследованием. Или я чего-то не понял?

K>Не связаны — ни один из интерфейсов не наследуется от другого. Реализация, однако, связана отношениями использования.
Пардон

V>Вы вообще поняли, насколько СТРАШНЫМ получился код? Насколько запутанная у него логика работы? Насколько тяжёлым будет его сопровождение?

K>Обычный код, ничего страшного. Логика работы крайне простая т.к. кроме отношений "использования" больше ничего не не используется. Сопровождение и чтение кода наоборот будет лекгим как перышко за счет использования нотации: _Classname_attribname_functionname:
K>self().IColored::color_get(), self().IFruit::kind() — компилятор сразу покажет какие функции должен поддерживать "верхний" обьект, а по именам легко определить название интерфейсов.
Может быть это мне показалось с непривычки, но когда один template наползает на другой template и юзает его через третий template, мне становится дурно. А ошибки в этом ловить...

V>За возможность хранить или не хранить информацию о цвете в объекте "Фрукт" мы заплатили такую высокую цену, что победа оказалась пиррова.

K>О какой цене идет речь?
А если, допустим, под объектом Colored будет скрываться супермощная система методов, занимающая в исходниках мегабайт и поддерживающая всю функциональность работы с цветом, заложенную в фотошоп?
Мы, такие лопоухие, ничего не подозревая, напишем:

struct MyApple ...

struct MyMango ...

struct MyOrange ...

struct MyHome ...

// ... и т.д.


Ой, а почему на CD программа не помещается?

K>То что предлагаете вы будет работать только в простых случаях не представляющих интереса. Я никогда не поверю в то, что следующий код будет работать

K>
K>class LinuxWindow;
K>class Win32Window;
K>class DBView;

K>var dbvLnx as (LinuxWindow,DBView)
K>var dbvWin as (Win32Window,DBView)
K>

А почему нет? Если логику грамотно прописать, то должно.




Вот как то же самое может выглядеть при множественном наследовании:
class CFruit { // Фрукт
 var Kind as string;
 function name() as string {
   if Result = NULL { // Отдаёмся на откуп "наследникам"
     Result = Kind;
   }
 }
}

class CColored { // Нечто цветное
 var Color as string;
}

function (CFruit, CColored)::name() as string { // Доопределяем функцию CFruit::name()
  Result = Color + " " + Kind;
}

procedure TestColoredFruits(Other as CFruit) {  // Тестовая процедурка
 Var Fruit as CFruit,
     Colored as CColored,
     ColoredFruit as (CColored, CFruit);
 Fruit.Kind = "Mango";
 ColoredFruit.Kind = "Apple";
 ColoredFruit.Color = "Green";

 App.MsgBox(Fruit.name()); // "Mango"
 App.MsgBox(ColoredFruit.name()); // "Green Apple"
 App.MsgBox(Other.name()); // Зависит от того, что прислали.
     // Может выдать, например, "Plum" или "Yellow Banana"

 // А теперь нам хочется закричать страшным голосом, если Other зелёный
 ifcast Other as CColored { // такой специальный оператор
  if lower(Other.Color) = "green" { // здесь компилятор уже знает, что у Other есть Color
   App.MsgBox("Фууууу! Какая гадость! " + Other.name() + "!");
  }
 }
}


Всё просто и элегантно.

Кстати, в моём примерчике высвечивается такая проблема: если объявлен ещё один класс CQuality, то функция name() будет работать абы как:

class CQuality {
 var Sort as String;
}

function (CFruit, CQuality)::name() as string { // Тоже доопределяем функцию CFruit::name()
  Result = Sort + " " + Kind;
}


Что покажет такой код

var AllTogather as (CColored, CFruit, CQuality);
AllTogather.Kind = "Grape";
AllTogather.Color = "Red";
AllTogather.Quality = "Rotten";
App.MsgBox(AllTogather.name());


"Red Grape" или "Rotten Grape" ?

Не бейте меня ногами. Знаю, что проблема есть. Но это проблема, на мой взгляд, скорее методического плана. Думаю, решение для неё есть.
Re[4]: Статья про развитие идей ООП. Жду комментариев.
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 13.05.03 16:39
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Сейчас наоборот наблюдается деградация языков программирования к более простым вариантам

А>(видимо программист пошел совсем недалекий).

В точку. Вернее, концентрация "далёких" уменьшилась. А ещё — вследствие притягивания псевдопромышленной модели организации труда в софтостроение.

А>Наглядный пример Java и VB — полные ничтожества в языковом плане, никаких понят... тьфу возможностей,

А>однако ведь лидеры промышленной разработки.

Ключевое слово — "простота", а ещё — "специализация". А ещё — магическая фраза "MS-технология", "Современная технология" и т.п.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[8]: Ой
От: WolfHound  
Дата: 13.05.03 16:41
Оценка:
Здравствуйте, Kluev, Вы писали:

K>То что предлагаете вы будет работать только в простых случаях не представляющих интереса. Я никогда не поверю в то, что следующий код будет работать

K>
K>class LinuxWindow;
K>class Win32Window;
K>class DBView;

K>var dbvLnx as (LinuxWindow,DBView)
K>var dbvWin as (Win32Window,DBView)
K>

Я тоже.
... << RSDN@Home 1.0 beta 6a >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[9]: Ой
От: WolfHound  
Дата: 13.05.03 16:41
Оценка:
Здравствуйте, Kluev, Вы писали:

K>К примеру несколько программистов независимо друг от друга разарабатывают очень сложный класс. Каждый их них пишет свою часть, учитывая что его коллеги занимаются реализацией остальных частей которые будут доступны через соответствующие интерфейсы. Пока класс не написан каждый программер пишет для себя урезанную-тестовую реализацию остальных интерфейсов (обычно это не занимает много времени)

А вот таких эксперементов лучше избегать. Практика показывает что практически любой класс (кроме мелких) можно разбить на несколько мелких.
... << RSDN@Home 1.0 beta 6a >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[9]: Ой
От: WolfHound  
Дата: 13.05.03 17:01
Оценка:
Здравствуйте, Voblin, Вы писали:

V>Может быть это мне показалось с непривычки, но когда один template наползает на другой template и юзает его через третий template, мне становится дурно. А ошибки в этом ловить...

С непривычки. А ошибки тут ловить довольно просто, а если учесть что прибив ошибку в одном месте то она испавится везде...

V>А если, допустим, под объектом Colored будет скрываться супермощная система методов, занимающая в исходниках мегабайт и поддерживающая всю функциональность работы с цветом, заложенную в фотошоп?

V>Мы, такие лопоухие, ничего не подозревая, напишем:
А если мы не лопухи и немного переделаем то
template <class T>
struct Self{
    T& self() { return *static_cast<T*>(this); }
};

template <class T>
struct Mango:Self<T>, IFruit {
    cchar_t* _IFruit_kind() { return "mango"; }
};
struct ColoredImpl:IColored//Толстая реализация
{
    std::string    _m_color;

    cchar_t* _IColored_color_get() { return _m_color.c_str(); }
    void _IColored_color_set( cchar_t *color ) { _m_color = color; }
};
template <class T>
struct Colored :Self<T>, ColoredImpl{};


V>Не бейте меня ногами. Знаю, что проблема есть.

Во-во и мы о томже...
V>Но это проблема, на мой взгляд, скорее методического плана. Думаю, решение для неё есть.
Нет это концептуальная проблема.
... << RSDN@Home 1.0 beta 6a >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[9]: Ой
От: Voblin Россия http://maslyaew.narod.ru/
Дата: 13.05.03 17:11
Оценка:
Здравствуйте, Kluev, Вы писали:

K>// Легкая шаблонная обертка

K>template <class T>
K>struct TMyObject : Part<MyObject,T> {
K>// этот код гарантирует поддержку классом Т интерфейсов IxFoo, IxZoo
K> IxFoo& _MyObject_IxFoo() { return self(); }
K> IxZoo& _MyObject_IxFoo() { return self(); }
K>};

K>// Теперь можно собирать по кусочкам:

K>struct Test1 :
K> TMyObject<Test>,
K> TMyIxFooImpl<Test1>,
K> TMyIxZooImpl<Test2>
K>{
K> // ..............
K>};

K>struct Test2 :

K> TMyObject<Test2>,
K> TMy_Another_IxFoo_And_IxZoo_Impl_in_single_class<Test2>
K>{
K> // ..............
K>};
K>[/ccode]

Безусловно, это очень интересно, полезно и может быть всячески рекомендовано всем, кто пишет на С++.

Несколько соображений:
1. Не все задачи имеет смысл решать на С++. И с этим можно только смириться.
2. Главная проблема всё равно остаётся нерешённой. Для того, чтобы покрыть всё разнообразие объектов, встречающихся в задаче, мы обязаны все их классы объявить в программе явно. В некоторых случаях это хорошо, но иногда сильно напрягает.
3. Может ли случиться так, что код, реализующий интерфейс IxFoo должен будет вести себя по-разному в зависимости от того, сидит ли с ним под одной крышей IxZoo? Предположим, это случилось. Как быть? Разруливать в теле класса Test1? А потом копированием/вставкой тянуть в Test2?
4. Что у нас с полиморфизьмом? Как сделать так, чтобы функция name() простого фрукта вернула "Apple", а цветного фрукта — "Green Apple"?

Думаю, mixins и то, что описано в статье в равной степени имеют право быть.
Re[7]: Шаблоны - не выход. Вернее, не всегда выход.
От: Akzhan Россия http://www.akzhan.midi.ru/devcorner/
Дата: 13.05.03 18:22
Оценка:
Здравствуйте, Voblin, Вы писали:

V>Тоже хороший подход. Сразу бросается в глаза вот что:

V>1. Делается на базе шаблонов. То есть мы заставляем компилятор генерировать некий "промежуточный" исходник, в котором все наши используемые сочетания обявлены явно и жёстко. Мало того, что генерируется большой объём кода (это не страшно, кто сейчас считает мегабайты?), но и за кадром может остаться множество
V>полезных сочетаний.

Шаблоны как таковые (при правильном подходе) являются средстством резко уменьшить объём кода. Посмотрите на библиотеки MFC и WTL. При решении одной и той же задачи объём кода разнится на порядки. Причём WTL/ATL использует именно mixin-подход.

V>2. Мутация бывает очень полезна. Поясняю. Например, пользователь заводит карточку сотрудника. Пол он ещё не ввёл, и поэтому объект не принадлежит ни классу CMale, ни классу CFemale. Выбирает пол сотрудника — "Male". С этого момента неплохо было бы сменить тип редактируемого объекта на (CPerson, CMale).


В терминах реляционных баз данных мы просто вносим уточнение на уровне отдельного атрибута. При закачке в оперативную память (swizzling) генерируется объект необходимого типа (всё равно "Персона"). Удобно для случая stateless objects.

Если же рассматривать, почему: Вы подобрали плохой пример — здесь удобнее не наследование, а включение.
Так, "Персона" имеет необязательное свойство "Пол". Это удобнее, и не надо вводить спорную концепцию.
С уважением,
Акжан, http://www.akzhan.midi.ru/devcorner/ — мой уголок разработчика
Re[9]: Ой
От: Kluev  
Дата: 13.05.03 18:58
Оценка:
Здравствуйте, Voblin, Вы писали:

K>О какой цене идет речь?

V>А если, допустим, под объектом Colored будет скрываться супермощная система методов, занимающая в исходниках мегабайт и поддерживающая всю функциональность работы с цветом, заложенную в фотошоп?
V>Мы, такие лопоухие, ничего не подозревая, напишем:
V>
V>struct MyApple ...
V>struct MyMango ...
V>struct MyOrange ...
V>struct MyHome ...
V>// ... и т.д.
V>

V>Ой, а почему на CD программа не помещается?

Малореальная ситуация. Перед тем как юзать обычно сырцы\доку смотрят, а иначе как?. К тому-же это не проблема времени выполнения


K>То что предлагаете вы будет работать только в простых случаях не представляющих интереса. Я никогда не поверю в то, что следующий код будет работать

K>
K>class LinuxWindow;
K>class Win32Window;
K>class DBView;

K>var dbvLnx as (LinuxWindow,DBView)
K>var dbvWin as (Win32Window,DBView)
K>

V>А почему нет? Если логику грамотно прописать, то должно.
V>


Вот ситуация: DBView создает несколько дочерних форм. Как он сможет их создать будучи полностью отделенным от LinuxWindow или Win32Window? Очевидно, что практически невозможно обеспечить единство интерфейсов для LinuxWindow и Win32Window. В этом случае нам нужна платформенно-независимая библиотека. Но смотрите:
class LinuxWindow;
class Win32Window;
class PlatformIndependentWindow;
class DBView;

var dbvLnx as (LinuxWindow,DBView) // не подойдет
var dbvLnx as (Win32Window,DBView) // не подойдет
var dbvLnx as (PlatformIndependentWindow,DBView) // сойдет

В итоге имеем толко один вариант, а раз он один то се-таки удобнее делать так
class DBView : public PlatformIndependentWindow {....};

V>Вот как то же самое может выглядеть при множественном наследовании:

V>
V>class CFruit { // Фрукт
V> var Kind as string;
V> function name() as string {
V>   if Result = NULL { // Отдаёмся на откуп "наследникам"
V>     Result = Kind;
V>   }
V> }
V>}

V>class CColored { // Нечто цветное
V> var Color as string;
V>}

V>function (CFruit, CColored)::name() as string { // Доопределяем функцию CFruit::name()
V>  Result = Color + " " + Kind;
V>}
V>


Выглядит красиво но не без проблем. Фактически — это альтернативный способ записи множественного наследования, Следующий код поясняет это:

function (CFruit, CColored)::name() as string { // Доопределяем функцию CFruit::name()
  Result = this->CColored::Color + " " + this->CFruit::Kind;
}


Видно что функция function (CFruit, CColored)::name() жестко привязана к конкретным реализациям классов CFruit, CColored — наследования то у вас нет
В этом случае прийдется постоянно писать что-то типа (ведь нет никакой связи между классами)
string (CApple,CFruit,CColored)::name()
string (COrange,CFruit,CColored)::name()
Боюсь программеры этого не одобрят и не поймут


V>Всё просто и элегантно.


V>Кстати, в моём примерчике высвечивается такая проблема: если объявлен ещё один класс CQuality, то функция name() будет работать абы как:


V>
V>class CQuality {
V> var Sort as String;
V>}

V>function (CFruit, CQuality)::name() as string { // Тоже доопределяем функцию CFruit::name()
V>  Result = Sort + " " + Kind;
V>}
V>


V>Что покажет такой код


V>
V>var AllTogather as (CColored, CFruit, CQuality);
V>AllTogather.Kind = "Grape";
V>AllTogather.Color = "Red";
V>AllTogather.Quality = "Rotten";
V>App.MsgBox(AllTogather.name());
V>


V>"Red Grape" или "Rotten Grape" ?


V>Не бейте меня ногами. Знаю, что проблема есть. Но это проблема, на мой взгляд, скорее методического плана. Думаю, решение для неё есть.


Эта проблемма легко решается наследованием как я уже показывал:
struct MyApple :
    Apple<MyApple>,
    Colored<MyApple>,
    ColoredFruit<MyApple>,
    Part<IObject,MyApple>
{
    string _IObject_fullName_get() {
        return color_get() + " " + kind() + " fruit";
    }
};

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

V>Несколько соображений:

V>1. Не все задачи имеет смысл решать на С++. И с этим можно только смириться.
Никто и не спорит. Если бы вы что-нибудь SQL подобное описывали вам бы никто и не возразил, а у вас типичная задача для С++ (уровня библиотеки шаблонов и интерфейсов)
V>2. Главная проблема всё равно остаётся нерешённой. Для того, чтобы покрыть всё разнообразие объектов, встречающихся в задаче, мы обязаны все их классы объявить в программе явно. В некоторых случаях это хорошо, но иногда сильно напрягает.
Шаблоны спасают.

Я как-то работал с языком Express-1 (язык описания данных) он поддерживает наследование в вашем стиле, т.е. обьекты в нем обьявляются так: #EdgeId=(Object("Dummy"),GeometricObject(),EdgeObject(#PointID,#PointID,#CurveId)) — в скобках вызовы конструкторов составного обьекта. Таким макаром можно наплодить дикое количество типов. Вопрос, что потом со всем этим делать?

V>3. Может ли случиться так, что код, реализующий интерфейс IxFoo должен будет вести себя по-разному в зависимости от того, сидит ли с ним под одной крышей IxZoo? Предположим, это случилось. Как быть? Разруливать в теле класса Test1? А потом копированием/вставкой тянуть в Test2?

Пример приведите, тогда и помозгуем, а так абстрактно слишком
V>4. Что у нас с полиморфизьмом? Как сделать так, чтобы функция name() простого фрукта вернула "Apple", а цветного фрукта — "Green Apple"?
Реализацией метода name в финальном классе-реализации. это аналогично добавлению метода (CFruit,CColored)::name()
Re[2]: Статья про развитие идей ООП. Жду комментариев.
От: Voblin Россия http://maslyaew.narod.ru/
Дата: 14.05.03 08:36
Оценка:
Здравствуйте, Akzhan, Вы писали:

A>Здравствуйте, Voblin, Вы писали:


A>http://www.rsdn.ru/Forum/Message.aspx?mid=266637&amp;only=1
Автор: PM
Дата: 14.05.03


Спасибо. Почитаю.
Re[2]: Статья про развитие идей ООП. Жду комментариев.
От: Voblin Россия http://maslyaew.narod.ru/
Дата: 14.05.03 11:26
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Что-то я так и не понял, чем же это отличается от "классического ООП в духе Страуструпа".

S>Ну, вот есть у нас классы. (Все классически). Ну вот может объект принадлежать к нескольким классам — тоже классика. (Вообще говоря, любой ациклический граф соответствует валидной схеме наследования классов).
Видимо Вы имеете в виду множественное наследование. У меня речь о другом.

S>Требование

присутствия возможности задания перечня классов непосредственно для каждого объекта

давно удовлетворено в классике. Никто не мешает писать так:

S>
S>  class _useonceforIbo_ : piblic IGadget, IBark{} *Ibo = new _useonceforIbo_();
S>

S>хотя так делать и не стоит. А не стоит потому, что теперь мы получили объект уникального класса. Легкая модификация:
S>
S>  class _useonceforIbo_ : piblic IGadget, IBark{} *Ibo = new _useonceforIbo_();
S>  class _useonceforIbo2_ : piblic IGadget, IBark{} *IboSon = new _useonceforIbo2_();
S>

S>и упс! У нас два объекта различных классов. Хотя набор интерфейсов в точности совпадает.
У меня классы Ibo и IboSon будут идентичны.

S>Так что на диаграмме надо бы стереть слова "Non-classic".

S>Ага, дальше мы собрались отказаться от наследования и вместо "реального" класса XY: public X, Y {} ввести виртуальный класс XY. Пардон, а чем он так радикально отличается от своего "реального" тезки?
Хорошо. По порядку. Реальный класс должен быть объявлен как положено, и экземпляры мы порождаем уже от него.
Виртуальный же тем и виртуален, что он нигде не объявлен. Мы порождаем объект от двух классов и считаем, что теперь он принадлежит трём классам — двум реальным и одному виртуальному. Для виртуального мы тоже можем определять свойства и методы. В этом случае он станет более реальным, но всё равно у него останется налёт виртуальности: порождая экземпляр классов X,Y,Z получим экземпляр, одновременно принадлежащий классам X,Y,Z,XY,XZ,YZ,XYZ из которых первые три — реальные, последний — под вопросом, а остальные — виртуальные.

S>

S>Вооружившись комбинаторикой, можно вспомнить, что количество сочетаний N классов, выбранных среди K существующих (без учета порядка), равно С(K, N) = K!/(N!*(K-N)!))


Дурака свалял. Конечно, надо считать
S(N=1..K)(K!/(N!*(K-N)!)))
Не знаю, как это сказать по-комбинаторски.

S>Обычно создают родительский класс clPersistent, имеющий методы Read() и Save(), и классы clClient и clOrder порождают (возможно, косвенно) от Persistent.

. . .
S>Запись реквизитов контрагента в базу данных будет производиться в процедуре Save() класса clPersistentClient: public clPersistent, clClient{}, а реквизитов заказа — в процедуре, реализованной для clPersistentOrder: public clPersistent, clOrder{}.
S>Ну да, анси паскаль отдыхает. Впрочем, мы и раньше это знали.
В примере с clPersistent, clClient и clOrder мне нужно было показать, как мы можем добиться полиморфизма без использования наследования. По-моему, мне это удалось.
А то, что ту же логику можно реализовать на С++, я и сам знаю. На Pascalе тоже кстати можно это сделать. Только чуть по-другому.

S>Я не очень понял пассаж про вызов метода класса XZ для объекта класса XY. Вот если бы наш объект был класса XYZ, тогда бы эта кандидатура была бы оправдана.

М.б. я просто неясно выразился, но имелось в виду именно это.

S>Ок, давайте рассмотрим такую ситуацию:

S>1. У нас есть классы X, Y, и Z. Пусть у нас есть метод X::M().
S>2. Теперь мы создаем класс XY и переопределяем для него метод XY::M(). В данный момент принудительный вызов обоих версий метода кажется совершенно излишним — если бы классический программист хотел этого добиться, то он бы просто вставил этот вызов в тело XY::M(), при этом полностью управляя последовательностью вызовов.
S>3. Теперь мы порождаем класс XYZ и снова переопределяем M(). Предыдущее рассуждение все еще остается справедливым — хорошо смеется тот, кто стреляет последним.
S>4. А вот теперь кто-то приходит и добавляет в систему класс XZ. С точки зрения классического программиста, это не приносит ничего нового, ибо класс XYZ c ним никак не связан. Наша неклассическая система считает себя умнее программиста, и вызывает X::M(), XY::M(), XZ::M(), XYZ::M() в неопределенном порядке, предоставляя каждой версии доступ на чтение к наиболее свежему кандидату на возвращаемое значение. И об этом неклассический программист просто проинформирован. Нда, я пока не готов стать неклассическим программистом — я бы все же предпочел иметь немного больше контроля над развитием событий.
Согласен, что надо давать больше контроля. Например так, как это сделано в CLOS — вызов всех подходящих методов производится упорядоченно и программисту даётся возможность повлиять на этот порядок с помощью оператора call_next_method. Сейчас понятно, что здесь есть над чем подумать.

S>Все дальнейшие рассуждения в статье без особых оговорок применимы к С++, вплоть до реляционных БД.

Здесь нужно по порядку:
S>Проблемы объединения ООП и РСУБД никак не связаны с трудностями отображения объектов на таблицы.
Не согласен. Это одна из основных проблем и одна из основных причин появления ООБД.
РСУБД основаны на реляционной алгебре, которая в свою очередь основана на математической теории множеств, а ООП — вообще на чём основано. Когда это пытаешься склеивать, возникают противоречия.

S>И уж конечно, фиксация единственного способа отображения не является решением подобной проблемы, даже если бы она и была.

Готов спорить до хрипоты. В грамотно построенной логически целостной системе должен использоваться только один способ отображения. Всё остальное — кустарщина и дилетантизм. Кроме того, очень много систем автоматически строят структуру БД и структуру классов на базе метаданных. Вот так:
            -- Структура БД
Метаданные <      
            -- Классы

И здесь действительно всякие вольности и шаманство в плане отображения классов на таблицы в принципе невозможно.
Пример — ужасно модная и перспективная MSBS Axapta.

S>Трудности начинаются в тот момент, когда нужно выбрать те из объектов класса X, у которых метод M() возвращает 0. Если вспомнить о том, что у нас есть еще классы XY, XZ, и XYZ, то можно сразу выбросить на помойку идею применить индекс к этому запросу — увы, метод M виртуален. И даже для детерминированных методов (от которых мы только что отказались, решив вызывать все подряд) поиск оптимального плана выполнения такого запроса значительно сложнее, чем для типичного RDBMS запроса.

Очень экзотический случай. Уверен, что ни одна их существующих сейчас РСУБД такое не поддерживает. Может быть, в Yukon что-то такое будет?
Конечно, и сейчас можно в MS SQL 2000 использовать user-defined функции, но это всегда работает очень медленно именно из-за того, что не удаётся оптимизировать план выполнения запроса. Здесь я имею в виду те функции, которые не "Inline Table-valued Functions".

S>А финальную фразу этого раздела я вообще не понял — как это у нас парадигма привязки произвольного набора классов к каждому объекту умудрилась хорошо просочетаться с теорией баз данных, учитывая выбранный способ отображения? Т.е. у нас теперь один объект — одна табличка? Нда, вряд ли бы корифеи реляционной алгебры это одобрили.

Поправлю: один класс — одна табличка. В статье я специально оговорился про подчинённые таблички.

S>Заключение

S>Помимо очевидных внутренних нестыковок, я сумел найти единственное радикальное отличие предлагаемой технологии от "классического ООП". Это методика разрешения неопределенностей вызова виртуальных методов при множественном наследовании. Возможно, я ее просто не понял, но на первый взгляд она выглядит значительно хуже любой альтернативы, которую я только могу придумать.
1. Отказ от наследования — это не отличие?
2. Проблема неопределённости последовательности вызовов решаема. Например так, как я написал выше. Или даже как-нибудь более элегантно.
Re[8]: Шаблоны - не выход. Вернее, не всегда выход.
От: Voblin Россия http://maslyaew.narod.ru/
Дата: 14.05.03 11:41
Оценка:
Здравствуйте, Akzhan, Вы писали:

A>Шаблоны как таковые (при правильном подходе) являются средстством резко уменьшить объём кода. Посмотрите на библиотеки MFC и WTL. При решении одной и той же задачи объём кода разнится на порядки. Причём WTL/ATL использует именно mixin-подход.


Шаблоны — это всего лишь умные макросы. С логической точки зрения это безразлично — использовать template или копирование/вставку+поиск/замену. С макросоми, конечно, продуктивнее. Да и ошибки исправлять проще.

V>2. Мутация бывает очень полезна. Поясняю. Например, пользователь заводит карточку сотрудника. Пол он ещё не ввёл, и поэтому объект не принадлежит ни классу CMale, ни классу CFemale. Выбирает пол сотрудника — "Male". С этого момента неплохо было бы сменить тип редактируемого объекта на (CPerson, CMale).


A>В терминах реляционных баз данных мы просто вносим уточнение на уровне отдельного атрибута. При закачке в оперативную память (swizzling) генерируется объект необходимого типа (всё равно "Персона"). Удобно для случая stateless objects.


A>Если же рассматривать, почему: Вы подобрали плохой пример — здесь удобнее не наследование, а включение.

A>Так, "Персона" имеет необязательное свойство "Пол". Это удобнее, и не надо вводить спорную концепцию.

С полом, конечно, пример не совсем удачный. Хотя всяко может быть. Особенно, если CFemale реализует женскую логику

Более удачный пример — Контрагент — (физ/юр) лицо. Это действительно разные классы, каждый из которых обладает своим набором атрибутов (даже длина поля ИНН разная).
Re[3]: OFF: про собаку Аибо :-)
От: Хитрик Денис Россия RSDN
Дата: 14.05.03 15:01
Оценка:
Друзья!
Хочу сказать, что Аибо — имя собственное, его дали электронной собачке, сделанной в лабораториях фирмы Сони.

По английски пишется как AIBO — artificial intelligent robot, afaik.

Сайт, где можно посмотреть это чудо: http://www.aibo.com/.
Правила нашего с вами форума.
Как правильно задавать вопросы. © 2001 by Eric S. Raymond; перевод: © 2002 Валерий Кравчук.
Re[9]: Шаблоны - не выход. Вернее, не всегда выход.
От: Akzhan Россия http://www.akzhan.midi.ru/devcorner/
Дата: 15.05.03 03:48
Оценка:
Здравствуйте, Voblin, Вы писали:

V>Шаблоны — это всего лишь умные макросы. С логической точки зрения это безразлично — использовать template или копирование/вставку+поиск/замену. С макросоми, конечно, продуктивнее. Да и ошибки исправлять проще.


Язык высокорого уровня — это тоже лишь набор макросов

A>Если же рассматривать, почему: Вы подобрали плохой пример — здесь удобнее не наследование, а включение.

A>Так, "Персона" имеет необязательное свойство "Пол". Это удобнее, и не надо вводить спорную концепцию.
V>С полом, конечно, пример не совсем удачный. Хотя всяко может быть. Особенно, если CFemale реализует женскую логику

V>Более удачный пример — Контрагент — (физ/юр) лицо. Это действительно разные классы, каждый из которых обладает своим набором атрибутов (даже длина поля ИНН разная).


Где Вы видели мутирующих контрагентов?
Тут скорее подходит принцип "актуализации".

Я сейчас пишу статью на эту тему. Можете посмотреть драфт: http://www.akzhan.midi.ru/devcorner/articles/YourIS-IronBeans.html
С уважением,
Акжан, http://www.akzhan.midi.ru/devcorner/ — мой уголок разработчика
Re[10]: Шаблоны - не выход. Вернее, не всегда выход.
От: Voblin Россия http://maslyaew.narod.ru/
Дата: 15.05.03 09:32
Оценка:
Здравствуйте, Akzhan, Вы писали:

V>Шаблоны — это всего лишь умные макросы. С логической точки зрения это безразлично — использовать template или копирование/вставку+поиск/замену. С макросоми, конечно, продуктивнее. Да и ошибки исправлять проще.


A>Язык высокорого уровня — это тоже лишь набор макросов


Конечно. Но не в такой же степени!!!

A>Если же рассматривать, почему: Вы подобрали плохой пример — здесь удобнее не наследование, а включение.

A>Так, "Персона" имеет необязательное свойство "Пол". Это удобнее, и не надо вводить спорную концепцию.
V>С полом, конечно, пример не совсем удачный. Хотя всяко может быть. Особенно, если CFemale реализует женскую логику

V>Более удачный пример — Контрагент — (физ/юр) лицо. Это действительно разные классы, каждый из которых обладает своим набором атрибутов (даже длина поля ИНН разная).


A>Где Вы видели мутирующих контрагентов?

A>Тут скорее подходит принцип "актуализации".

Запросто! Даже предложу два логических уровня.

1. Уровень бизнес-логики. Был контрагент покупателем, стал контрагент поставщиком. Был контрагент физ. лицом, а потом взял, и оформился в юр. лицо. Если с точки зрения бух. учёта это уже совсем другой контрагент, то в управленческом учёте это должен быть тот же самый. Нам же интересны реалиные взаиморасчёты, накопительные скидки и пр.

2. Уровень софтинки. Когда юзер давит кнопку "создать контрагента", перед ним возникает окошечко, в котором он заполнит его карточку. По умолчанию, допустим, контрагент создаётся как юр. лицо (так захотели пользователи). Соответственно, на формочке (и в том объекте, который за ней стоит) есть поля Name, FullName, VATRegNo (ИНН), RegNo (номер гос. регистрации), Юр. адрес и т.д.. Юзер перещёлкивает крыжик с юр. на физ. лицо, и эти поля (может быть, за исключением ИНН) исчезают, и появляются FirstName, LastName и т.д. Логично?

Можно, конечно, сделать как в 1С — в объекте Контрагент есть все поля, характеризующие и юр. и физ. лицо. Мне это не нравится. Я старый маразматичный поклонник нормализованных баз.

Помнится, как-то в таблице, хранящей справочник товаров системы Navision Attain я насчитал 130 полей. Каково, а?

A>Я сейчас пишу статью на эту тему. Можете посмотреть драфт: http://www.akzhan.midi.ru/devcorner/articles/YourIS-IronBeans.html


Такие тексты очень сложно воспринимать в отрыве от контекста.
Что это за проект? На какой он стадии? Кем проводится? Какие ресурсы задействованы? Что предполагается: проприетарный или свободный софт? И ещё много вопросов.

И ещё хочу предостеречь о двух вещах:

1. Архитектура "Толстый клиент на ЯВУ — SQL БД, спроектированная вручную" — одна из самых распространённых ошибок. Независимо от от того, есть ли между ними прослойка (или даже две). Это прям какой-то интеллектуальный вирус! Если бы я был юдофобом, то заподозрил бы жидомасонский заговор. Типичный жизненный цикл таких систем:
— "Какие классные, мощные, продвинутые инструменты! Сколько литературы! Как всё стройно, логично и правильно!" Есть заказчик (как правило, "наша фирма"), готовый финансировать разработку.
— Обследуем предметную область, пишем что-то вроде ТЗ. Попутно придумываем несколько "супер-пупер" технологических решений, которые позволят больше никогда не задумываться о иерархиях/историях значений/скорости получения итогов/проектировании формочек (нужное подчеркнуть и/или добавить своё)
— Проектируем БД в ERWin, пишем доп. компоненты к любимому средству разработки. Попутно постигаем ERP, SCM, CRM, ABC-анализ. Ой, прошёл год.
— Пишем клиента. В системе уже сотни классов, десятки форм, много печатных форм. Коллектив разработчиков — большой и дружный. Прошёл ещё год.
— Системой уже можно гордиться.
— Показали главбуху. главбух несёт какую-то чушь. Показали манагерам. Манагеры придираются по ерунде. Доделываем.
— Доделываем — показываем — доделываем — показываем — доделываем — показываем. Прошёл ещё год.
— Внедряем! Мучительно, на нервах, но система работает!
— А не продать ли нам её кому-нибудь ещё? Денег заработаем гору! Ищем клиента, находим, беседуем. Блин! Да нужно много чего под него переделать. Причём в модулях, про которые уже никто ничего не помнит. Либо отказываемся от проекта, либо берёмся за него и проваливаем.
— Изменилось законодательство. Ё моё! Всё надо переделать!
— Директор — козёл. Вместо нашей системы решил ставить 1С. 1С — отстой!
— У нас внедряют 1С. Сваливаем.

2. Бизнес-софт обязан соответствовать законодательству. Вы ничего не сможете продать оптом, но напечатав счёт-фактуру (в которой указывается ГТД, правильно рассчитанный НДС, НП, акциз...), не сможете ничего оплатить по банку, но напечатав платёжку, разграфлённую с точностью до милиметра. А законодательство меняется с ураганной скоростью. Притом, как правило, в сторону усложнения и увеличения числа противоречий. Почитайте налоговый кодекс и последние ПБУ. Мало не покажется. Только свяжитесь с бухгалтерией, и никаких сил на ERP, SCM, CRM и ABC-анализ уже не останется.

Такова жизнь.
Не обижайтесь.
Re[11]: Шаблоны - не выход. Вернее, не всегда выход.
От: Akzhan Россия http://www.akzhan.midi.ru/devcorner/
Дата: 15.05.03 14:08
Оценка:
Здравствуйте, Voblin, Вы писали:

A>Где Вы видели мутирующих контрагентов?

A>Тут скорее подходит принцип "актуализации".
V>Запросто! Даже предложу два логических уровня.
V>1. Уровень бизнес-логики. Был контрагент покупателем, стал контрагент поставщиком. Был контрагент физ. лицом, а потом взял, и оформился в юр. лицо. Если с точки зрения бух. учёта это уже совсем другой контрагент, то в управленческом учёте это должен быть тот же самый. Нам же интересны реалиные взаиморасчёты, накопительные скидки и пр.

Тут же напрашивается решение с разделением понятий "Контрагент" и "Учётные данные контрагента". У нас клиенты могут иметь множество юридических лиц, например. А группы скидок могут присваиваться на любом уровне (от клиента до конкретного счёта).

V>Помнится, как-то в таблице, хранящей справочник товаров системы Navision Attain я насчитал 130 полей. Каково, а?

Не будем ругать то, что работает

A>Я сейчас пишу статью на эту тему. Можете посмотреть драфт: http://www.akzhan.midi.ru/devcorner/articles/YourIS-IronBeans.html

V>Такие тексты очень сложно воспринимать в отрыве от контекста.
V>Что это за проект? На какой он стадии? Кем проводится? Какие ресурсы задействованы? Что предполагается: проприетарный или свободный софт? И ещё много вопросов.

Есть две системы, уже работающие по этих принципам. А сейчас выкладываю мысли в свободный доступ — наряду с демо-реализацией. В порядке обмена опытом.

V>И ещё хочу предостеречь о двух вещах:

V>1. Архитектура "Толстый клиент на ЯВУ — SQL БД, спроектированная вручную" — одна из самых распространённых ошибок. Независимо от от того, есть ли между ними прослойка (или даже две). Это прям какой-то интеллектуальный вирус! Если бы я был юдофобом, то заподозрил бы жидомасонский заговор. Типичный жизненный цикл таких систем:


Знакомая история.
Тут главное вовремя остановиться с реализацией великих идей.

Кстати, в Питере есть несколько очень даже неплохих проприетарных решений, выросших до уровня коммерческих.
С уважением,
Акжан, http://www.akzhan.midi.ru/devcorner/ — мой уголок разработчика
Re: Статья про развитие идей ООП. Жду комментариев.
От: Akzhan Россия http://www.akzhan.midi.ru/devcorner/
Дата: 15.05.03 14:12
Оценка:
Здравствуйте, Voblin, Вы писали:

V>Может быть, кому-нибудь будет интересно.

V>http://voblin.nm.ru/objects_classes.dhtml
V>Сразу вопрос: стоит ли это опубликовать в RSDN?

Кстати, если дополните Вашу статью описанием mixin-подхода, то цены Вам не будет. Обязуюсь в таком случае выложить такой вариант у себя и даже раскрутить (включая offline-публикации).
С уважением,
Акжан, http://www.akzhan.midi.ru/devcorner/ — мой уголок разработчика
Re[2]: Статья про развитие идей ООП. Жду комментариев.
От: Voblin Россия http://maslyaew.narod.ru/
Дата: 15.05.03 15:09
Оценка:
Здравствуйте, Akzhan, Вы писали:

A>Здравствуйте, Voblin, Вы писали:


V>Может быть, кому-нибудь будет интересно.

V>http://voblin.nm.ru/objects_classes.dhtml
V>Сразу вопрос: стоит ли это опубликовать в RSDN?

A>Кстати, если дополните Вашу статью описанием mixin-подхода, то цены Вам не будет. Обязуюсь в таком случае выложить такой вариант у себя и даже раскрутить (включая offline-публикации).


ОК. Сделаю. Только возьму тайм-аут на недельку, а то начальство с потрохами сожрёт.
Re[12]: Шаблоны - не выход. Вернее, не всегда выход.
От: Voblin Россия http://maslyaew.narod.ru/
Дата: 15.05.03 15:32
Оценка:
Здравствуйте, Akzhan, Вы писали:

V>Помнится, как-то в таблице, хранящей справочник товаров системы Navision Attain я насчитал 130 полей. Каково, а?

A>Не будем ругать то, что работает
Иногда рука сама тянется к канделябру.

A>Я сейчас пишу статью на эту тему. Можете посмотреть драфт: http://www.akzhan.midi.ru/devcorner/articles/YourIS-IronBeans.html

V>Такие тексты очень сложно воспринимать в отрыве от контекста.
V>Что это за проект? На какой он стадии? Кем проводится? Какие ресурсы задействованы? Что предполагается: проприетарный или свободный софт? И ещё много вопросов.

A>Есть две системы, уже работающие по этих принципам. А сейчас выкладываю мысли в свободный доступ — наряду с демо-реализацией. В порядке обмена опытом.

Это уже интересно. Особенно в свете возможной кончины 1С. Очень остро возникнет проблема — чем заткнуть дыру?

V>И ещё хочу предостеречь о двух вещах:

V>1. Архитектура "Толстый клиент на ЯВУ — SQL БД, спроектированная вручную" — одна из самых распространённых ошибок. Независимо от от того, есть ли между ними прослойка (или даже две). Это прям какой-то интеллектуальный вирус! Если бы я был юдофобом, то заподозрил бы жидомасонский заговор. Типичный жизненный цикл таких систем:

A>

A>Знакомая история.
A>Тут главное вовремя остановиться с реализацией великих идей.

A>Кстати, в Питере есть несколько очень даже неплохих проприетарных решений, выросших до уровня коммерческих.


Всяко бывает. Не спорю.

На мой взгляд, в этом деле конструкторы типа 1С, Attain, Axapta и иже с ними перспективнее. Работает, конечно, не так быстро, зато подгонять под клиента и развивать проще.
Re[3]: Статья про развитие идей ООП. Жду комментариев.
От: Sinclair Россия https://github.com/evilguest/
Дата: 16.05.03 06:59
Оценка:
Здравствуйте, Voblin, Вы писали:

V>Видимо Вы имеете в виду множественное наследование. У меня речь о другом.

Да, именно его я имею в виду. Я не понимаю разницы между классическим множественным наследованием и тем, что предлагается.
V>У меня классы Ibo и IboSon будут идентичны.
S>>Так что на диаграмме надо бы стереть слова "Non-classic".
S>>Ага, дальше мы собрались отказаться от наследования и вместо "реального" класса XY: public X, Y {} ввести виртуальный класс XY. Пардон, а чем он так радикально отличается от своего "реального" тезки?
V>Хорошо. По порядку. Реальный класс должен быть объявлен как положено, и экземпляры мы порождаем уже от него.
V>Виртуальный же тем и виртуален, что он нигде не объявлен. Мы порождаем объект от двух классов и считаем, что теперь он принадлежит трём классам — двум реальным и одному виртуальному. Для виртуального мы тоже можем определять свойства и методы. В этом случае он станет более реальным, но всё равно у него останется налёт виртуальности: порождая экземпляр классов X,Y,Z получим экземпляр, одновременно принадлежащий классам X,Y,Z,XY,XZ,YZ,XYZ из которых первые три — реальные, последний — под вопросом, а остальные — виртуальные.
А, ну вот что-то вырисовывается. Ценность этого пока сомнительна, но по крайней мере это уже не классика. В плюсах можно вручную сделать класс XYZ потомком XY, XZ, и YZ, но, естественно, автоматически это не гарантируется.

V>В примере с clPersistent, clClient и clOrder мне нужно было показать, как мы можем добиться полиморфизма без использования наследования. По-моему, мне это удалось.

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

V>Согласен, что надо давать больше контроля. Например так, как это сделано в CLOS — вызов всех подходящих методов производится упорядоченно и программисту даётся возможность повлиять на этот порядок с помощью оператора call_next_method. Сейчас понятно, что здесь есть над чем подумать.


V>Не согласен. Это одна из основных проблем и одна из основных причин появления ООБД.

V>РСУБД основаны на реляционной алгебре, которая в свою очередь основана на математической теории множеств, а ООП — вообще на чём основано. Когда это пытаешься склеивать, возникают противоречия.
Да нет там никаких противоречий. Ну где вы их увидели? Проблема — исключительно в производительности. Для реляционных СУБД просто разработаны хорошие методы оптимизации. Которые основаны на знаниях об эквивалентности планов, и методах предсказания затрат. Сегодняшнее ООП является преимущественно процедурным. Кроме того, концепции инкапсуляции и полиморфизма стимулируют нас рассматривать каждый объект как черный ящик. Это означает, что мы не можем с легкостью фокусника заменить нудный вызов метода М для всех миллионов объектов похожего класса обращением в список объектов, у которых этот вызов даст требуемый результат.
А просто отобразить поля объекта в поля таблиц базы данных — как два пальца об асфальт.

V>Готов спорить до хрипоты. В грамотно построенной логически целостной системе должен использоваться только один способ отображения. Всё остальное — кустарщина и дилетантизм. Кроме того, очень много систем автоматически строят структуру БД и структуру классов на базе метаданных. Замечательно. А про оптимизацию производительности мы просто забудем? Есть N семантически эквивалентных способов отобразить заданную иерархию классов в РСУБД. Каждый из них дает различное быстродействие при выполнении различных запросов. Но умоляю, давайте не будем здесь обсуждать эту тему! Лучше отдельный флейм начать.


V>Очень экзотический случай. Уверен, что ни одна их существующих сейчас РСУБД такое не поддерживает. Может быть, в Yukon что-то такое будет?

V>Конечно, и сейчас можно в MS SQL 2000 использовать user-defined функции, но это всегда работает очень медленно именно из-за того, что не удаётся оптимизировать план выполнения запроса. Здесь я имею в виду те функции, которые не "Inline Table-valued Functions".
Ну еще бы РСУБД поддерживали объектные запросы! Это не экзотический случай, это типичная задачка, выраженная в терминах ООП. Просто обычно как раз такие задачи решают средствами РСУБД, а там наследованием и полиморфизмом даже не припахивает. Потому сразу делают всё класса XYZ, вместо метода M() у нас — поле М, и все работает и все довольны. Вот это — проблема! А отображение классов в табличку... Может, я чего-то не понимаю? Это рутина.

V>Поправлю: один класс — одна табличка. В статье я специально оговорился про подчинённые таблички.

Э, нет. Вы в самом начале отказались от того, чтобы объекты имели класс. Они у вас принадлежат произвольному множеству классов, причем это индивидуально контролируется на уровне каждого объекта. Помните? Вот у нас есть три реальных класса X, Y, Z. Еще четыре штуки виртуальных. И объекты, принадлежащие всем восьми комбинациям (включая пустую) зараз. Ну и по каким табличкам мы все это раскладываем? А, ну да. Вот теперь мы получили проблему.

V>1. Отказ от наследования — это не отличие?

У вас нет никакого отказа от наследования. Оно торчит из статьи, как кроличьи уши из шляпы. Или вы называете принудительное добавление классов-предков к классу объекта отказом от наследования? Да тут больше наследования, чем в классике! Раньше наш XYZ спокойно наследовался от XY, и горя себе не знал. A тут ему говорят, что его дядя XZ и тетя YZ теперь тоже его родители, и жить будем все вместе. И объясняют это отказом от наследования.

V>2. Проблема неопределённости последовательности вызовов решаема. Например так, как я написал выше. Или даже как-нибудь более элегантно.

В вашем объяснении выше не сказано, в каком порядке будут вызываться методы. А рассуждения в статье насчет параллельного выполнения — вообще ужасны. В каком состоянии находится ваш объект в процессе выполнения метода? Как вы собираетесь гарантировать его целостность в этом случае?
... << RSDN@Home 1.0 beta 6a >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: Статья про развитие идей ООП. Жду комментариев.
От: Voblin Россия http://maslyaew.narod.ru/
Дата: 16.05.03 09:17
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, Voblin, Вы писали:


V>>Видимо Вы имеете в виду множественное наследование. У меня речь о другом.

S>Да, именно его я имею в виду. Я не понимаю разницы между классическим множественным наследованием и тем, что предлагается.
Конечно, каждое сочетание классов "наследует" свойства и методы всех своих подмножеств. Т.е. XY наследует всё и от Х, и от Y. Только вор в системе нет такого класса — XY. Есть объекты, принадлежащие и X, и Y (и, возможно, куче всего другого дополнительно), но класса такого нет. Итак, кто у кого что наследует? Класс XY у классов X и Y? Нет такого класса — XY! Есть объекты A(X), B(Y), C(XY), D(XYZ), которые получают свойства, методы и реализации методов классов X, Y и XY. Но это же не наследование, когда от класса к экземпляру! Наследование — это когда от класса к классу! Семантически в результате может получиться похоже, но... может и не получиться.

V>>В примере с clPersistent, clClient и clOrder мне нужно было показать, как мы можем добиться полиморфизма без использования наследования. По-моему, мне это удалось.

S>Вы просто назвали наследование по-другому. Вы собираетесь писать код, который имеет ровно ту же семантику, что и приведенный мной код на плюсах.
Повторяю, что в примере с clPersistent, clClient и clOrder я действительно показал семантику, эквивалентную обычному наследованию. Если бы я взялся усложнять пример, то мог бы получить совсем другую семантику. Например, так:
Добавляем в систему класс clVendor. Предположим, в системе возможны клиенты, также являющиеся поставщиками, т.е. сочетание (clClient, clVendor, ...) является допустимым. Теперь для некоего объекта AOrder нам приспичело узнать состояние взаиморасчётов (суммарные, кредиторка и дебиторка) с тем товарисчем, который указан в поле "ClientID". Делаем это так:

 var AClient as (clPersistent, clClient), Balance as Double;
 AClient.LoadObject(AOrder.ClientID); // Этот метод класа clPersistent процедура загружает объект целиком.
         // Т.е. сначала выясняет по идентификатору его классовую сущность, мутирует его до нужного состояния
         // и вызывает свой собственный жутко полиморфный Read().
 Balance = AClient.ClientBalance;
 ifcast AClient as clVendor { // А не поставщик ли он ещё?
   Balance -= AClient.VendorBalance;  // Ага, поставщик. Вычтем свой долг перед ним.
 }
 if Balance + AOrder.TotAmount > 1000000 {
   App.MsgBox("Только по предоплате!!!");
 }


Здесь интересно то, что метод clPersistent::Read() загрузит из БД всё что необходимо сам, отработав код (clPersistent, clClient)::Read() и, если нужно, (clPersistent, clVendor)::Read()
И не надо дополнительно городить класс clPersistentClientAndVendor, который объединит в себе всю весёлую компанию и в методе clPersistentClientAndVendor::Read() сам вызовет clPersistentClient::Read() и clPersistentVendor::Read().

S>А просто отобразить поля объекта в поля таблиц базы данных — как два пальца об асфальт.

Люди головы ломают, научные труды пишут, ООБД выдумывают, а Вы — "об асфальт". Не хорошо. Поищите в сети MappingObjects.pdf. Там эта проблема рассмотрена подробно. Описано три подхода. Честно скажу, ни один из них мне не кажется идеальным.

V>>Поправлю: один класс — одна табличка. В статье я специально оговорился про подчинённые таблички.

S>Э, нет. Вы в самом начале отказались от того, чтобы объекты имели класс. Они у вас принадлежат произвольному множеству классов, причем это индивидуально контролируется на уровне каждого объекта. Помните? Вот у нас есть три реальных класса X, Y, Z. Еще четыре штуки виртуальных. И объекты, принадлежащие всем восьми комбинациям (включая пустую) зараз. Ну и по каким табличкам мы все это раскладываем? А, ну да. Вот теперь мы получили проблему.
В фразе "один класс — одна табличка" не имелись в виду чисто виртуальные классы. Виртуальный класс, конечно, может захотеть дописать что-то в отдельную табличку, но только в том случае, если это в нём прямо прописать. Тогда по-любому пришлось бы городить отдельную табличку, даже если программа пишется на Бейсике.

V>>1. Отказ от наследования — это не отличие?

S>У вас нет никакого отказа от наследования. Оно торчит из статьи, как кроличьи уши из шляпы. Или вы называете принудительное добавление классов-предков к классу объекта отказом от наследования? Да тут больше наследования, чем в классике! Раньше наш XYZ спокойно наследовался от XY, и горя себе не знал. A тут ему говорят, что его дядя XZ и тетя YZ теперь тоже его родители, и жить будем все вместе. И объясняют это отказом от наследования.
См. выше.

V>>2. Проблема неопределённости последовательности вызовов решаема. Например так, как я написал выше. Или даже как-нибудь более элегантно.

S>В вашем объяснении выше не сказано, в каком порядке будут вызываться методы. А рассуждения в статье насчет параллельного выполнения — вообще ужасны. В каком состоянии находится ваш объект в процессе выполнения метода? Как вы собираетесь гарантировать его целостность в этом случае?
Уговорили, напишу. Двумя словами отделаться не получится.
Re[5]: Статья про развитие идей ООП. Жду комментариев.
От: Sinclair Россия https://github.com/evilguest/
Дата: 16.05.03 12:59
Оценка:
Здравствуйте, Voblin, Вы писали:

V>Конечно, каждое сочетание классов "наследует" свойства и методы всех своих подмножеств. Т.е. XY наследует всё и от Х, и от Y. Только вор в системе нет такого класса — XY. Есть объекты, принадлежащие и X, и Y (и, возможно, куче всего другого дополнительно), но класса такого нет. Итак, кто у кого что наследует? Класс XY у классов X и Y? Нет такого класса — XY! Есть объекты A(X), B(Y), C(XY), D(XYZ), которые получают свойства, методы и реализации методов классов X, Y и XY. Но это же не наследование, когда от класса к экземпляру! Наследование — это когда от класса к классу! Семантически в результате может получиться похоже, но... может и не получиться.

Вот-вот, давайте-ка про семантику поговорим. Я не вижу смысла отделять "от класса к классу" от "от класса к экземпляру". В вашей системе всегда можно ввести безымянный класс, который и будет наследовать все что нужно от всего что нужно. Ну вот например для того самого объекта классов X, Y, и Z одновременно — ведь все объекты, которые указали при своем конструировании эти три класса, ведут себя одинаково! Они наследуют ровно один и тот же набор методов. Вы сами сказали при обсухдении айбо, что класс двух объекта, задекларировавших одинаковые списки классов, совпадает. Ну вот он и есть тот самый безымянный класс, которого вы так избегаете! Он есть де-факто, хоть имя его В Раздоле Не Произносят.

Могу подсказать: для того, чтобы с сточки зрения семантики можно было говорить о прямом наследовании от класса к экземпляру, потребуется что-то типа возможности переопределять методы на уровне экземпляров. Хотя наследование (в каком-то смысле) все еще останется. Но по этому пути я идти не рекомендую — посмотрите на JavaScript. Прекрасный язык, но в нем нет типизации.

Если я ошибаюсь, то объясните поподробнее, в каком же именно случае семантика прямого указания всех классов будет отличаться от введения безымянного промежуточного класса?

V>Здесь интересно то, что метод clPersistent::Read() загрузит из БД всё что необходимо сам, отработав код (clPersistent, clClient)::Read() и, если нужно, (clPersistent, clVendor)::Read()

V>И не надо дополнительно городить класс clPersistentClientAndVendor, который объединит в себе всю весёлую компанию и в методе clPersistentClientAndVendor::Read() сам вызовет clPersistentClient::Read() и clPersistentVendor::Read().
Ага! Вот теперь мы начинаем постепенно уползать от классики, так как экземпляр начал мутировать в процессе жизнедеятельности. Да, в классике почти везде класс объекта неизменен в течение всего времени жизни, и сама возможность динамически его изменить — сильная штука. Но почему вы ни слова не пишете об этом в статье? Это очень интересная тематика, тут подстерегает очень большое количество проблем. С большим интересом прочитаю побольше о том, как вы себе представляете семантику такой мутации объекта, который начал жизнь поставщиком, а попутно стал производителем.

S>>А просто отобразить поля объекта в поля таблиц базы данных — как два пальца об асфальт.

V>Люди головы ломают, научные труды пишут, ООБД выдумывают, а Вы — "об асфальт". Не хорошо. Поищите в сети MappingObjects.pdf. Там эта проблема рассмотрена подробно. Описано три подхода. Честно скажу, ни один из них мне не кажется идеальным.
Читал я это. Ну и что? Да, все три неидеальны. Но поймите, что проблемы в этом нет. Все уже обсосано до упора. И ООБД с этими возможностями на рынке уже лет десять пасутся. Проблема в том, что реляционная алгебра работает с данными, а ООП — с поведением. Несмотря на ортогональность этих концепций, пока не получается получить приемлемую производительность при их совместном использовании.
Хорошо, опишите тогда подробнее, чем ваш подход будет так уж лучше предлагаемых Амблером.

V>В фразе "один класс — одна табличка" не имелись в виду чисто виртуальные классы. Виртуальный класс, конечно, может захотеть дописать что-то в отдельную табличку, но только в том случае, если это в нём прямо прописать. Тогда по-любому пришлось бы городить отдельную табличку, даже если программа пишется на Бейсике.

Я вам еще раз намекаю, что ваша система как раз очень плохо отображается в RDBMS. В отличие от, например, жестко типизированной системы с одиночным наследованием Object Pascal.

V>Уговорили, напишу. Двумя словами отделаться не получится.


Давайте, пишите. Я бы на вашем месте сосредоточился на отличиях предлагаемой вами системы от существующих моделей. Одинаковости превозносить смысла нет — они уже прекрасно аргументированы в трудах Великих.
... << RSDN@Home 1.0 beta 6a >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[6]: Статья про развитие идей ООП. Жду комментариев.
От: Voblin Россия http://maslyaew.narod.ru/
Дата: 16.05.03 13:46
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Могу подсказать: для того, чтобы с сточки зрения семантики можно было говорить о прямом наследовании от класса к экземпляру, потребуется что-то типа возможности переопределять методы на уровне экземпляров.

Лучше смерть.

S>Если я ошибаюсь, то объясните поподробнее, в каком же именно случае семантика прямого указания всех классов будет отличаться от введения безымянного промежуточного класса?

Такой пример:
class X {...};
class Y {...};
class Z {...};
class XY: X, Y {...};
class XZ: X, Z {...};
class YZ: X, Z {...};
class XYZ:  ?????? {...};

// Может быть, так?
class XYZ: X, Y, Z {...}; // вариант 1 - очевидная глупость

// Или так?
class XYZ: XY, XZ, YZ {...}; // вариант 2 - самое логичное

// Или вот так? 
class XYZ: XY, XZ {...}; // вариант 3 - склероз замучил


Семантически эквивалентным моей схеме будет вариант 2, т.к. только в этом случае все переопределённые методы в принципе доступны. И то, если программист не забудет повызывать родительские методы.

S>Ага! Вот теперь мы начинаем постепенно уползать от классики, так как экземпляр начал мутировать в процессе жизнедеятельности. <...>

Тема мутации объектов безусловно требует дальнейшего раскрытия, тем более, что в предложенную мной схему она настойчиво напрашивается. ОК, поставим ещё одну галочку.

S>Хорошо, опишите тогда подробнее, чем ваш подход будет так уж лучше предлагаемых Амблером.

Отдельная тема для пространных наукообразных рассуждений. Будет время — залезу в неё.

V>>В фразе "один класс — одна табличка" не имелись в виду чисто виртуальные классы. Виртуальный класс, конечно, может захотеть дописать что-то в отдельную табличку, но только в том случае, если это в нём прямо прописать. Тогда по-любому пришлось бы городить отдельную табличку, даже если программа пишется на Бейсике.

S>Я вам еще раз намекаю, что ваша система как раз очень плохо отображается в RDBMS. В отличие от, например, жестко типизированной системы с одиночным наследованием Object Pascal.

V>>Уговорили, напишу. Двумя словами отделаться не получится.


S>Давайте, пишите. Я бы на вашем месте сосредоточился на отличиях предлагаемой вами системы от существующих моделей. Одинаковости превозносить смысла нет — они уже прекрасно аргументированы в трудах Великих.


Итак, в статью нужно добавить следующее:
1. Сравнение с mixin-технологией (вполне логичное пожелание Akzhan)
2. Способы придания предсказуемости вызовам методов объектов.
3. Мутация объектов.
4. Те изменения, которые вносит предлагаемая технология в процесс проектирования систем. Здесь и кроятся основные отличия от трудов Великих.
Re[7]: Статья про развитие идей ООП. Жду комментариев.
От: Sinclair Россия https://github.com/evilguest/
Дата: 16.05.03 14:14
Оценка:
Здравствуйте, Voblin, Вы писали:

S>>Если я ошибаюсь, то объясните поподробнее, в каком же именно случае семантика прямого указания всех классов будет отличаться от введения безымянного промежуточного класса?

V>Такой пример:
V>
V>class X {...};
V>class Y {...};
V>class Z {...};
V>class XY: X, Y {...};
V>class XZ: X, Z {...};
V>class YZ: X, Z {...};
V>class XYZ:  ?????? {...};

V>// Может быть, так?
V>class XYZ: X, Y, Z {...}; // вариант 1 - очевидная глупость

V>// Или так?
V>class XYZ: XY, XZ, YZ {...}; // вариант 2 - самое логичное

V>// Или вот так? 
V>class XYZ: XY, XZ {...}; // вариант 3 - склероз замучил
V>


V>Семантически эквивалентным моей схеме будет вариант 2, т.к. только в этом случае все переопределённые методы в принципе доступны. И то, если программист не забудет повызывать родительские методы.


Но ведь это никак не противоречит наличию такого класса! Класc XYZ есть, как бы он ни был продекларирован! Я согласен, что наиболее полным аналогом наследования, принятого в вашей модели является автоматическое зачисление в предки класса всех "вычетов", т.е. классов, которые были так же унаследованы от всех подмножеств множества исходных предков, которые которых... Тьфу, пропасть!
Короче, как только мы пишем
[virtual language]
class XYZ: X, Y, Z {} 
[/virtual language]

Мы подразумеваем
class XYZ: virtual XY, virtual XZ, virtual YZ {...}; // вариант 2 - самое логичное


А когда мы пишем
[virtual language]
class XYZW: X, Y, Z, W {} 
[/virtual language]

Мы подразумеваем
class XYZW: virtual XYZ, virtual XYW, virtual XZW, virtual YZW  {...};

То есть для четырех классов будем брать все тройки, для трех — двойки. Очевидно, что при таком рекурсивном определении класс XYZW унаследует все поведение (т.е. методы) и от классов X, Y, Z, W, XY, XZ, XW, YZ, YW, ZW.
Вот это уже похоже на отличие схемы наследования (я бы не рискнул называть это отсутствием наследования) от классических языков. Надо только понять, наскольо такая надстройка над объектностью оправдана — также, как С++ в свое время взял часть рутинной работы С-программиста на себя, эта система типизации тоже берет часть работы на себя. Но при этом ценой является некоторое уменьшение гибкости.

V>Тема мутации объектов безусловно требует дальнейшего раскрытия, тем более, что в предложенную мной схему она настойчиво напрашивается. ОК, поставим ещё одну галочку.

V>Отдельная тема для пространных наукообразных рассуждений. Будет время — залезу в неё.

V>>>В фразе "один класс — одна табличка" не имелись в виду чисто виртуальные классы. Виртуальный класс, конечно, может захотеть дописать V>>>Уговорили, напишу. Двумя словами отделаться не получится.


V>Итак, в статью нужно добавить следующее:

V>1. Сравнение с mixin-технологией (вполне логичное пожелание Akzhan)
V>2. Способы придания предсказуемости вызовам методов объектов.
V>3. Мутация объектов.
V>4. Те изменения, которые вносит предлагаемая технология в процесс проектирования систем. Здесь и кроятся основные отличия от трудов Великих.
Нет предела совершенству! Буду с интересом ждать выхода следующей версии

И перейдем к вопросам производительности
... << RSDN@Home 1.0 beta 6a >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[8]: Статья про развитие идей ООП. Жду комментариев.
От: Voblin Россия http://maslyaew.narod.ru/
Дата: 16.05.03 14:53
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>И перейдем к вопросам производительности


Насчёт производительности — это не ко мне. Это к фирме Intel. Позвать Гордона Мура.

Конечно, производительность будет напрямую зависеть от того, насколько эффективным получится сделать механизм построения списка подходящих реализаций виртуальных методов. Здесь можно вовсю побаловаться конечными автоматами, кэшированием в VMTable,...

Не буду об этом думать сегодня. Подумаю об этом завтра.
(с) С.О`Хара

Что уж говорить, сейчас подавляющее большинство (если скажу 90%, сильно не ошибусь) систем автоматизации основано на средстве разработки, дающем порядка 2 млн. элементарных операций в секунду на процессоре 2Ггц. Т.е. эффективность порядка 0.1% И что? Да ничего! Все довольны!

Часто борятся две тенденции:

Интеллектуальность среды => эффективные алгоритмы => повышение быстродействия
Интеллектуальность среды => тормоза в движке => понижение быстродействия

Пока счёт равный. Привести примеры можно как в ту, так и в другую сторону.
Re[9]: Статья про развитие идей ООП. Жду комментариев.
От: Sinclair Россия https://github.com/evilguest/
Дата: 19.05.03 22:40
Оценка:
Здравствуйте, Voblin, Вы писали:

V>Насчёт производительности — это не ко мне. Это к фирме Intel. Позвать Гордона Мура.

Офф:
Есть такое слово — масштабируемость. Это означает, что линейные алгоритмы — это верхний предел допустимой неоптимальности. Ну, в худшем случае О(N*logN). Все, что медленнее — сосет. RDBMS рулят из-за линейного объема и логарифмического поиска. Точка. Дело не в том, что ODBMS делают что-то в 10^K раз медленнее, дело в том, что в мало-мальски интересных случаях они сразу заменяют O(logN) на O(N).
... << RSDN@Home 1.0 beta 6a >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[8]: Статья про развитие идей ООП. Жду комментариев.
От: Voblin Россия http://maslyaew.narod.ru/
Дата: 16.06.03 10:32
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Нет предела совершенству! Буду с интересом ждать выхода следующей версии


Ну вот и появилась следующая версия статьи.

Почитать её можно там же.
Re: ВЫШЛА НОВАЯ ВЕРСИЯ
От: Voblin Россия http://maslyaew.narod.ru/
Дата: 16.06.03 10:36
Оценка:
Прочитать можно там же.
Re: Статья про развитие идей ООП. Жду комментариев.
От: vgrigor  
Дата: 17.06.03 07:25
Оценка:
Я вот буду не соглашаться с автором,

по следующим аспектам:
я пишу как правило реальную программу,
и с базрой данных, иногда с интеренет, со слоями,

И я не увидел ни одной полезной строки для этого.

И вот я думаю где мне вот такая концепция все таки пригодится?
Чисто конкретно?

Есть веслеые фразы, отражающие множественное наследование,
как четко определенные категории,

— Барсик — кот, игрушка
— Васька — кот, дикое животное
— Бобик — собака, игрушка
— Жучка — собака, дикое животное
— Тузик — собака, сотрудник ВОХР

а автор на мой взляд не предлагает ничего, четко сформулированного,
с другой строны ООП весьма обсужденная вещь, чтобы предполагать что в ней
такие явные недостатки, (как шаблоны).

Давайте Обсудим и мы. Это полезно.

Погрешности:
" При реализации полиморфизма через виртуальные классы программа, написанная забывчивым разработчиком, не будет аварийно завершаться с сообщением об ошибке. Она просто не будет выполнять требуемое действие. Как к этому относиться – не знаю."
Все знают — что плохо. Это вопрос стиля и его соответствия свободе программирования.Выбор за программером.

"Не знаю как кто, но я бы об избавлении от шаблонов не жалел ни секунды."
Классическое "Современное пректирование" в некоторых основных частях основано именно на шаблонах,
как эффективной вещи.
В частности миксинахи высокоструктурных компонентах.
С другой стороны вы не предложили достойной альтернативы.


"Реализация таких методов весьма накладна. Определение перечня задействованных реализаций в любом случае намного дольше отработки процессорной инструкции CALL.
Они никогда не смогут быть in-line. "
— не интересует мелкая накладность- интересует правильная оргпнизация проекта, чтобы он не провалился.

Вы начали обсуждатьно не предложили конкретно как сделать большой проект с большой вероятностью не провальным.

"множественной классификации." — вещь хорошая — это то же множественнео наследование,
или миксины или в чем явное отличие,
и какие выгоды от всего этого?

"Обман компилятора" — нехорошая вещь —
компилятрор ваш друг в поиске ошибок,
которые угробили бы ваш проект в дестяки раз быстрее.

"Будем считать вопрос строгой типизации закрытым. "
Надо писать "предлагаю" — но вы не написали серьещно почему?
Нет критериев.
Плохая проработка.

В общем это больше описание известных методов в
предложении представитьв новом языке.
Или не показано явное отличие.



Узнать о них можно -поэтому печатать полезно.
Но не супер.
Винтовку добудешь в бою!
Re[2]: Статья про развитие идей ООП. Жду комментариев.
От: Voblin Россия http://maslyaew.narod.ru/
Дата: 17.06.03 12:42
Оценка:
Здравствуйте, vgrigor, Вы писали:

V>Я вот буду не соглашаться с автором,


V>по следующим аспектам:

V>я пишу как правило реальную программу,
V>и с базрой данных, иногда с интеренет, со слоями,
Тоже дело, тоже балуюсь, но шило в заднице мешает сидеть спокойно

V>И я не увидел ни одной полезной строки для этого.

Я пока тоже. Ждём развития событий.

[мыши погрызли]

V> а автор на мой взляд не предлагает ничего, четко сформулированного,

V>с другой строны ООП весьма обсужденная вещь, чтобы предполагать что в ней
V>такие явные недостатки, (как шаблоны).
Некоторые никогда не устанут обсуждать погоду, некоторые — правительство, а некоторые — ООП.

V>Погрешности:

V>" При реализации полиморфизма через виртуальные классы программа, написанная забывчивым разработчиком, не будет аварийно завершаться с сообщением об ошибке. Она просто не будет выполнять требуемое действие. Как к этому относиться – не знаю."
V>Все знают — что плохо. Это вопрос стиля и его соответствия свободе программирования.Выбор за программером.
Суть ошибки забывчивого программера в том, что он не дописал ту функциональность, которая должна быть в программе.
Среда разработки (или выполнения) на это может среагировать двумя способами:
1. При первом удобном случае размазать несчастного по стенке. Программисты этого не любят, и поэтому, как правило, пишут быстренько затычки для виртуальных методов, чем сводят поведение системы ко второму способу.
2. Просто не делать то, что не запрограммировано. Запрограммирует — будем делать, не запрограммирует — адью.
Не вижу ничего плохого в том, чтобы система всегда шла по второму пути, но, как всегда, готов выслушать аргументированные возражения.

V>"Не знаю как кто, но я бы об избавлении от шаблонов не жалел ни секунды."

V>Классическое "Современное пректирование" в некоторых основных частях основано именно на шаблонах,
V>как эффективной вещи.
V>В частности миксинахи высокоструктурных компонентах.
V>С другой стороны вы не предложили достойной альтернативы.
Пардон, а для чего альтернатива? Для того, чтобы продолжать заниматься теми страшными извращениями, которые обычно реализуются на шаблонах? Господа! Подавляющее количество языков программирования не имеет механизма шаблонов, и не потому, что разработчики компилятора — недоумки, а потому, что это в них не нужно.

V>"Реализация таких методов весьма накладна. Определение перечня задействованных реализаций в любом случае намного дольше отработки процессорной инструкции CALL.

V>Они никогда не смогут быть in-line. "
V>- не интересует мелкая накладность- интересует правильная оргпнизация проекта, чтобы он не провалился.
Мне показалось полезным обсудить такую фичу, хотя соглашусь, что обсуждаемый раздельчик выглядит слегка инородным.

V>Вы начали обсуждатьно не предложили конкретно как сделать большой проект с большой вероятностью не провальным.

Как сделать проект с большой вероятностью не провальным, я не скажу. И не просите. Речь шла о том, как сделать проект с большей вероятностью не провальным. Разница — буква.
Как же сделать проект с большей вероятностью не провальным? Я предложил сильно упростить этап классификации и дополнительно к этому смягчить последствия ошибок, допущенных на нём.

V>"множественной классификации." — вещь хорошая — это то же множественнео наследование,

V>или миксины или в чем явное отличие,
V>и какие выгоды от всего этого?
Отличие — в том, что предложено делать типы объектов неатомарными.
При ЛЮБОМ навороте в ЛЮБОМ существующем языке программирования тип объекта ВСЕГДА атомарен. Что бы мы ни взяли, множественное наследование, миксины, составные типы или даже Variant, мы всегда имеем дело с атомарным типом.
В раздельчике "Классификация/Что же предлагается" про это подробно написано (только слово "атомарность" не упоминается чтобы людей не дразнить наукообразием).

V>"Обман компилятора" — нехорошая вещь -

V>компилятрор ваш друг в поиске ошибок,
V>которые угробили бы ваш проект в дестяки раз быстрее.
Хорошо это или не хорошо, но соблазн у программера есть всегда.
Конечно хотелось бы сделать так, чтобы корректность мутаций чётко и надёжно контролировалась компилятором, но сделать это ой как не просто!

V>"Будем считать вопрос строгой типизации закрытым. "

V>Надо писать "предлагаю" — но вы не написали серьещно почему?
V>Нет критериев.
V>Плохая проработка.
Да ну? По-моему, вполне доходчиво это было доказано.
Если эта фраза была воспринята в том смысле, что все среды программирования, не имеющие строгой типизации must die, то извините. Конечно, утверждение справедливо только в контексте множественной классификации.

V>В общем это больше описание известных методов в

V>предложении представить в новом языке.
V>Или не показано явное отличие.
Во люди дают! Им весь процесс построения системы классов перевернули вверх тормашками, попутно показав, насколько это хорошо сочетается с РБД, легитимизировали мутацию и избавились от шаблонов, а оказалось всё мало.
Думаю, старый ассемблерщик, почитав про ООП, мог бы сказать что-то вроде такого: "Да это и так всё давно известно и используется! Посмотрите хотя бы мой [censored].asm!"
Re[3]: ВЫШЛА НОВАЯ ВЕРСИЯ
От: Voblin Россия http://maslyaew.narod.ru/
Дата: 17.06.03 12:52
Оценка:
Здравствуйте, _vovin, Вы писали:

_>В работе никак не отражены важнейшие результаты, полученные за последние двадцать пять лет.

Чукча не читатель

А за остальное — супер пупер огроменное спасибо Так им!
Re[3]: ВЫШЛА НОВАЯ ВЕРСИЯ
От: vgrigor  
Дата: 17.06.03 12:57
Оценка:
Хорошая ссылка,но

Не подскажете что такое "динамический ООП"?

Весьма интересно.И в статье той даже не написано.

чего означает это понятие?

"современное проектирование"(Как писал Александреску) в смысле — создание коллекций типов как обьектов,
и операций с ними — конструирования обьектов из них в рун-тиме и соотвтествующей работой?
Винтовку добудешь в бою!
Re[4]: ВЫШЛА НОВАЯ ВЕРСИЯ
От: _vovin http://www.pragmatic-architect.com
Дата: 17.06.03 13:30
Оценка:
Здравствуйте, vgrigor, Вы писали:

V>Хорошая ссылка,но


V>Не подскажете что такое "динамический ООП"?


V>Весьма интересно.И в статье той даже не написано.


V>чего означает это понятие?


А не-динамического ОО не бывает, его придумали враги.
То, что мы видим сейчас, уже было в Simula, которое еще ООП не считалось.

Вкратце, объектный подход это — объекты, состояние, посылка сообщения. И точка.

Объектная система является набор объектов, развивающихся посредством последовательного изменения своего состояния. Единственным способом взаимодействия между объектами является посылка сообщения.
Объектный язык, это язык, который взаимодействует с объектной системой посредством посылки сообщений.

V>"современное проектирование"(Как писал Александреску) в смысле — создание коллекций типов как обьектов,

V>и операций с ними — конструирования обьектов из них в рун-тиме и соотвтествующей работой?

Проектирование само собой, оно при любом подходе имеет общие правила.
А про объектный подход я писал достаточно часто, например
http://www.rsdn.ru/Forum/Message.aspx?mid=280629&amp;only=1
Автор: _vovin
Дата: 29.05.03

Можно также зайти на сайт, который у меня указан в уголке и почитать статьи из Топ-листа.

--

Владимир.
Re[4]: ВЫШЛА НОВАЯ ВЕРСИЯ
От: Voblin Россия http://maslyaew.narod.ru/
Дата: 17.06.03 13:34
Оценка:
Здравствуйте, vgrigor, Вы писали:

V>"современное проектирование"(Как писал Александреску) в смысле — создание коллекций типов как обьектов,

V>и операций с ними — конструирования обьектов из них в рун-тиме и соотвтествующей работой?
Можно где-нибудь взять Александреску в эл. виде? Уж больно лень тащиться в книжный магазин.
Re[5]: ВЫШЛА НОВАЯ ВЕРСИЯ
От: vgrigor  
Дата: 17.06.03 14:06
Оценка:
http://www.bookhouse.com.ua/catalog/goods/3720.phtml

Точное название там:
можно заказать по интеренет.

В сети я не нашел.
Винтовку добудешь в бою!
Re[7]: ВЫШЛА НОВАЯ ВЕРСИЯ
От: vgrigor  
Дата: 17.06.03 14:17
Оценка:
V>Эх, придётся наверно купить treeware версию. А значит и прочитать целиком. Чтением по диагонали уже чисто психологически не отделаться. Что обидно.

А как это делается?
Расскажите народу.


И можно ли записать на диск в процессе триала?
Винтовку добудешь в бою!
Re[3]: ВЫШЛА НОВАЯ ВЕРСИЯ
От: Voblin Россия http://maslyaew.narod.ru/
Дата: 17.06.03 14:35
Оценка:
Здравствуйте, Akzhan, Вы писали:

A>В своей статье Вы полагаете объект некоей кучей иных объектов

Предыдущее утверждение не верно, следующее — верно.
A>Хотя все Ваши цитаты из реального мира прямо говорят о дргом подходе:
A>Объекты в природе сами по себе целостны (как Вы говорите, элементарны).

A>А множество определений для одного и тог же объекта можно строго определить различными точками зрения на один и тот объект (в принципе отсюда в оригинале и пляшет концепция контрактов-интерфейсов).

Точки зрения — это немножко про другое. См. ниже.

A>Вдумайтесь: та же кошка не является кучей точек зрения, вместе собирающихся в нечто единое (подход слепцов и слона). Наоборот — кошка — это строго и заранее определённый (с точностью до реализации) объект, который наше восприятие способно воспринимать с различных точек зрения.

Конкретная кошка — это действительно строго и заранее (гены и вся история её жизни) определённый объект. Короче, экземпляр. Абстрактная кошка (класс) — это тоже заранее определённая вещь. У абстрактную кошку действительно может быть определено несколько точек зрения. Эти точки зрения вполне переносимы на конкретную Мурку, но...
Но Мурка может быть также классифицирована как-нибудь ещё. Например, как злюка.
Точка зрения слепца на кошку может, например, содержать интерфейс Погладить(). Реакция Мурки на вызов этого интерфейса может быть различной в зависимости от того, является она также ещё и злюкой либо нет.

Идея точек зрения —
Впитываю.
Re[8]: ВЫШЛА НОВАЯ ВЕРСИЯ
От: Voblin Россия http://maslyaew.narod.ru/
Дата: 17.06.03 14:39
Оценка:
Здравствуйте, vgrigor, Вы писали:


V>>Эх, придётся наверно купить treeware версию. А значит и прочитать целиком. Чтением по диагонали уже чисто психологически не отделаться. Что обидно.


V>А как это делается?

V>Расскажите народу.


V>И можно ли записать на диск в процессе триала?


Не trial, а treeware. От слова "дерево". Вычитал в руководстве по CVS, очень понравилось.
Re[9]: ВЫШЛА НОВАЯ ВЕРСИЯ
От: vgrigor  
Дата: 17.06.03 14:44
Оценка:
V>Не trial, а treeware. От слова "дерево". Вычитал в руководстве по CVS, очень понравилось.

Это все что можешь сообщить?
Винтовку добудешь в бою!
Re[3]: ВЫШЛА НОВАЯ ВЕРСИЯ
От: Voblin Россия http://maslyaew.narod.ru/
Дата: 18.06.03 09:34
Оценка:
Здравствуйте, Akzhan,

Кстати, описание миксинов в статье нормальное? Без ляпов?
Re[5]: Статья про развитие идей ООП. Жду комментариев.
От: Аноним  
Дата: 19.06.03 09:26
Оценка:
Здравствуйте, joker6413, Вы писали:

А>>Если же кого-то интересуют навороченные языковые возможности, то есть тот же CLOS, Smalltalk, SML, Haskell

А>>(последний вроде как уже есть под .NET — H#).

J>Какие концептуальные задачи вы будете решать этими инструментами?


J>Игорь


Да какие угодно. За smalltalk ничего не скажу, а функциональные языки намного понятнее и удобнее в использовании. За ними также стоит мощная математическая теория, которая упрощает анализ програм, написанных на них, распаралеливание и т.п. Естественно операционную систему на них писать или перемножать матрицы не стоит, но написать на SML, например, компилятор пара пустяков. Если вы не знакомы с этой концепцией, советую познакомиться, очень полезно знать, что существуют и другие подходы к понятию вычисления, кроме машины Тьюринга.
Re[6]: Статья про развитие идей ООП. Жду комментариев.
От: vgrigor  
Дата: 19.06.03 09:30
Оценка:
Перевожу на русскй:
мелкософт работает в своих лабораториях над функциональным языком F#.
Основанным на общем описании проблемы с помощью функций и организаций,
а компилятро сам все вычислит как лучше посчитать.

кстати ссыску надо бы приводить. или бред получается.
Винтовку добудешь в бою!
Re[7]: Статья про развитие идей ООП. Жду комментариев.
От: Аноним  
Дата: 19.06.03 09:44
Оценка:
Здравствуйте, vgrigor, Вы писали:

V>Перевожу на русскй:

V>мелкософт работает в своих лабораториях над функциональным языком F#.
V>Основанным на общем описании проблемы с помощью функций и организаций,
V>а компилятро сам все вычислит как лучше посчитать.

V>кстати ссыску надо бы приводить. или бред получается.


Пока Микрософт чего то химичит в лабораториях, другие все уже сделали. Ссылки — www.haskell.org и www.ocaml.org.
Лучше ocaml, поскольку Haskell создан скорее в академических целях, типа изучения различных теоретических наворотов
и установить его сложнее. А ocaml можно сразу скачать и работать, кроме того для него там выложена on-line книга.
Re[4]: ВЫШЛА НОВАЯ ВЕРСИЯ
От: Akzhan Россия http://www.akzhan.midi.ru/devcorner/
Дата: 19.06.03 09:50
Оценка:
Здравствуйте, Voblin, Вы писали:

V>Кстати, описание миксинов в статье нормальное? Без ляпов?


Если честно — настолько сжатое, что если про неё заранее не знаешь, то и смысла не поймёшь
С уважением,
Акжан, http://www.akzhan.midi.ru/devcorner/ — мой уголок разработчика
Re[8]: Статья про развитие идей ООП. Жду комментариев.
От: vgrigor  
Дата: 19.06.03 09:53
Оценка:
А>Пока Микрософт чего то химичит в лабораториях, другие все уже сделали. Ссылки — www.haskell.org и www.ocaml.org.
А>Лучше ocaml, поскольку Haskell создан скорее в академических целях, типа изучения различных теоретических наворотов
А>и установить его сложнее. А ocaml можно сразу скачать и работать, кроме того для него там выложена on-line книга.

Микрософт делает реально пригодные для использования продукты.
А некоторые развлекаются. Можно так сказать.

Я взглянул на окамл, и первый пример -использование рекурсий вместо циклов — явно
плохой предложение ввиду неудобства реального представления алгоритма,
линейных, простых. В общем -неудача на первой странице.
Винтовку добудешь в бою!
Re[9]: Статья про развитие идей ООП. Жду комментариев.
От: Аноним  
Дата: 19.06.03 10:02
Оценка:
Здравствуйте, vgrigor, Вы писали:

V>Микрософт делает реально пригодные для использования продукты.

V>А некоторые развлекаются. Можно так сказать.

V>Я взглянул на окамл, и первый пример -использование рекурсий вместо циклов — явно

V>плохой предложение ввиду неудобства реального представления алгоритма,
V>линейных, простых. В общем -неудача на первой странице.

Записывать алгоритм с помощью рекурсии или циклов дело вкуса, поскольку это одно и тоже.
Функциональные языки потому и называются функциональными, что оперируют функциями — небольшими
по размеру. Вместо циклов используется рекурсия.
Однако за рекурсией вы не расмотрели главного — автоматического выведения типов + строгая типизация,
pattern matching, частичных функций и т.д. Кстати, переменных в ФЯ тоже нет, можете записать это им
в минус.
Re[10]: Статья про развитие идей ООП. Жду комментариев.
От: vgrigor  
Дата: 19.06.03 10:07
Оценка:
Да, правое ухо чесать через-под левое колено,
это на ваш вкус.
Винтовку добудешь в бою!
Re[5]: ВЫШЛА НОВАЯ ВЕРСИЯ
От: Voblin Россия http://maslyaew.narod.ru/
Дата: 19.06.03 10:34
Оценка:
Здравствуйте, Akzhan, Вы писали:

A>Здравствуйте, Voblin, Вы писали:


V>>Кстати, описание миксинов в статье нормальное? Без ляпов?


A>Если честно — настолько сжатое, что если про неё заранее не знаешь, то и смысла не поймёшь


Я, конечно, понимаю, что если миксины описывать подробно, то получится толстая книжка, и показанное на картинке решение — это лишь один из частных случаев. Но, думаю, в контексте изложения такого очень краткого описания достаточно. Или нет? Или упустил что-то существенное?
Re[11]: Статья про развитие идей ООП. Жду комментариев.
От: Аноним  
Дата: 19.06.03 10:36
Оценка:
Здравствуйте, vgrigor, Вы писали:

V>Да, правое ухо чесать через-под левое колено,

V>это на ваш вкус.

Извините за грубость, но если вы чего то не понимаете, лучше промолчать, чем выставлять свое невежество напоказ.
То что рекурсия слабо используется в Visual Basic'e от фирмы Microsoft, не значит, что она плоха, это значит
лишь, что ее там использовать не целесообразно. А существуют (удивительное дело) языки, где не целесообразно
использовать циклы, а есть языки где переменных нет, и есть языки, где порядок операторов не важен. Но все это,
конечно, поделки развлекающихся бездельников, ведь умные дяди из Microsoft эти языки не используют, а им ведь
виднее.
Короче, я привел ссылки. Кого интересует программирование, как наука и исскуство, а не только как не особо напряжный
способ заработать на жизнь лабая формы в VS, могут найти там что-нибудь интересное.
Re[12]: Статья про развитие идей ООП. Жду комментариев.
От: vgrigor  
Дата: 19.06.03 10:40
Оценка:
Моя точка зрения основана на эффективном программировании,
быстром написании и оптимизации жизненного цикла программы.

А у вас вкус другой,
не буду вам мешать.

кстати вы аноним для таких высказываний,
и это некорректно.
Винтовку добудешь в бою!
Re: Статья про развитие идей ООП. Жду комментариев.
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 19.06.03 13:33
Оценка:
Здравствуйте, Voblin, Вы писали:

V>Может быть, кому-нибудь будет интересно.

V>http://voblin.nm.ru/objects_classes.dhtml
V>Сразу вопрос: стоит ли это опубликовать в RSDN?

Я извиняюсь за последующие ламерские вопросы но мне интересно разобраться с идеями автора.
1. На данном этапе понятие интерфейс является класс с абстрактными виртуальными методами которые давным давно реализуются в СОМ (возможность отказа от виртуальности проблема компилятора так как не нужно наследование делать их статическими)
2. Все последующие доводы опять же крутятся вокруг интерфейсов. Приведения объекта к определенному интерфейсу.
3. Почему то не увидел в С# директиву аналогичную в Delphi Implements.
Еще раз прошу меня извинить и напрвить на путь истинный.
и солнце б утром не вставало, когда бы не было меня
Re[2]: Статья про развитие идей ООП. Жду комментариев.
От: Voblin Россия http://maslyaew.narod.ru/
Дата: 19.06.03 14:32
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>Здравствуйте, Voblin, Вы писали:


V>>Может быть, кому-нибудь будет интересно.

V>>http://voblin.nm.ru/objects_classes.dhtml
V>>Сразу вопрос: стоит ли это опубликовать в RSDN?

S> Я извиняюсь за последующие ламерские вопросы но мне интересно разобраться с идеями автора.

S> 1. На данном этапе понятие интерфейс является класс с абстрактными виртуальными методами которые давным давно реализуются в СОМ (возможность отказа от виртуальности проблема компилятора так как не нужно наследование делать их статическими)
S> 2. Все последующие доводы опять же крутятся вокруг интерфейсов. Приведения объекта к определенному интерфейсу.
S> 3. Почему то не увидел в С# директиву аналогичную в Delphi Implements.
S> Еще раз прошу меня извинить и напрвить на путь истинный.

Не очень понял вопрос, ну и ладно, попробую ответить как понял.
1. Про абстрактные классы: абстрактный и виртуальный — не одно и то же.
2. Как объект соотносится с интерфейсом.
Сейчас делается так (сильно упрощённая схема):

 Интерфейс ------> Класс <------ Экземпляр
           *    1         1    *


Т.е. взяв объект, можем получить его класс и, следовательно, список интерфейсов.

Предлагается вот что:

 Интерфейс ------> Класс <------> Экземпляр
           *    1         *    *


Т.е. экземпляр может принадлежать нескольким классам и, соответственно, иметь присущие им наборы интерфейсов.
Re[11]: Статья про развитие идей ООП. Жду комментариев.
От: PeterZT  
Дата: 19.06.03 17:54
Оценка:
Здравствуйте, vgrigor, Вы писали:

V>Да, правое ухо чесать через-под левое колено,

V>это на ваш вкус.
Use the right tool.(c)
... << RSDN@Home 1.0 beta 7a >>
Re[3]: Статья про развитие идей ООП. Жду комментариев.
От: Lloyd Россия  
Дата: 20.06.03 08:28
Оценка:
Здравствуйте, Voblin, Вы писали:

V>
V> Интерфейс ------> Класс <------ Экземпляр
V>           *    1         1    *
V>


V>Т.е. взяв объект, можем получить его класс и, следовательно, список интерфейсов.


А почему на стрелочке Интерфейс — Класс стоит *-1, а не *-*?
Re[3]: Статья про развитие идей ООП. Жду комментариев.
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 20.06.03 09:52
Оценка:
Здравствуйте, Voblin, Вы писали:

V>Здравствуйте, Serginio1, Вы писали:


S>>Здравствуйте, Voblin, Вы писали:


V>>>Может быть, кому-нибудь будет интересно.

V>>>http://voblin.nm.ru/objects_classes.dhtml
V>>>Сразу вопрос: стоит ли это опубликовать в RSDN?

S>> Я извиняюсь за последующие ламерские вопросы но мне интересно разобраться с идеями автора.

S>> 1. На данном этапе понятие интерфейс является класс с абстрактными виртуальными методами которые давным давно реализуются в СОМ (возможность отказа от виртуальности проблема компилятора так как не нужно наследование делать их статическими)
S>> 2. Все последующие доводы опять же крутятся вокруг интерфейсов. Приведения объекта к определенному интерфейсу.
S>> 3. Почему то не увидел в С# директиву аналогичную в Delphi Implements.
S>> Еще раз прошу меня извинить и напрвить на путь истинный.

V>Не очень понял вопрос, ну и ладно, попробую ответить как понял.

V>1. Про абстрактные классы: абстрактный и виртуальный — не одно и то же.
V>2. Как объект соотносится с интерфейсом.
V>Сейчас делается так (сильно упрощённая схема):

V>
V> Интерфейс ------> Класс <------ Экземпляр
V>           *    1         1    *
V>


V>Т.е. взяв объект, можем получить его класс и, следовательно, список интерфейсов.


V>Предлагается вот что:


V>
V> Интерфейс ------> Класс <------> Экземпляр
V>           *    1         *    *
V>


V>Т.е. экземпляр может принадлежать нескольким классам и, соответственно, иметь присущие им наборы интерфейсов.


В классическом Delphi интерфейсы определены как классы с абстрактными виртуальными методами и доступ к ним идет через VMT где прописаны реальные адреса процедур.

То есть
Интерфейс это класс
Interface= class
procedure P1; Virtual; abstract; stdcall;
procedure P2; Virtual; abstract; stdcall;
end;

В моем понимании ссылку на интерфейс можно прописать таким способом аналогичным TMethod.

TInterfase= Record
data:Pointer;// Сылка на данные класса
Code:Pointer;// Ссылка на VMT
end;

Implements в Delphi имеет замечательную возможность использовать класс реализующий уже набор интерфейсов например

type
IMyInterface = interface
procedure P1;
procedure P2;
end;
TMyImplClass = class
procedure P1;
procedure P2;
end;
TMyClass = class(TInterfacedObject, IMyInterface)
FMyImplClass: TMyImplClass;
property MyImplClass: TMyImplClass read FMyImplClass implements IMyInterface;
procedure IMyInterface.P1 = MyP1;
procedure MyP1;

end;
procedure TMyImplClass.P1;
...
procedure TMyImplClass.P2;
...
procedure TMyClass.MyP1;
...
var
MyClass: TMyClass;
MyInterface: IMyInterface;
begin
MyClass := TMyClass.Create;
MyClass.FMyImplClass := TMyImplClass.Create;
MyInterface := MyClass;
MyInterface.P1; // calls TMyClass.MyP1;
MyInterface.P2; // calls TImplClass.P2;
end;

В Delphi как и в Net и Java отказались от множественного наследования (огромное количество общих методов из-за наследовния от Object)
и солнце б утром не вставало, когда бы не было меня
Re[4]: Статья про развитие идей ООП. Жду комментариев.
От: Voblin Россия http://maslyaew.narod.ru/
Дата: 20.06.03 10:07
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Здравствуйте, Voblin, Вы писали:


V>>
V>> Интерфейс ------> Класс <------ Экземпляр
V>>           *    1         1    *
V>>


V>>Т.е. взяв объект, можем получить его класс и, следовательно, список интерфейсов.


L>А почему на стрелочке Интерфейс — Класс стоит *-1, а не *-*?


Потому что "сильно упрощённая схема". Конечно, если подрисовать наследование и делегирование, то получится что-то вроде *-*, но сути это не сильно поменяет, т.к. основные различия, которые и хотелось проиллюстрировать находятся в правой части схемки.
Re[4]: Статья про развитие идей ООП. Жду комментариев.
От: Voblin Россия http://maslyaew.narod.ru/
Дата: 20.06.03 10:18
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>В классическом Delphi интерфейсы определены как классы с абстрактными виртуальными методами и доступ к ним идет через VMT где прописаны реальные адреса процедур.


В статье специально я оговорился о том, что понятие "интерфейс" у меня будет означать именно свойство или метод, тогда как в интерфейсном проектировании под этим понятием подразумевается то, что у меня обозначено как "набор интерфейсов".

То, что Вы описали, это есть агрегация с делегированием интерфейсов, которая у меня тоже рассмотрена.
Re[5]: Статья про развитие идей ООП. Жду комментариев.
От: vgrigor  
Дата: 20.06.03 10:21
Оценка:
Как отписаться от темы не подскажете?
Винтовку добудешь в бою!
Re[5]: Статья про развитие идей ООП. Жду комментариев.
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 20.06.03 12:24
Оценка:
Здравствуйте, Voblin, Вы писали:

V>Здравствуйте, Serginio1, Вы писали:


V>В статье специально я оговорился о том, что понятие "интерфейс" у меня будет означать именно свойство или метод, тогда как в интерфейсном проектировании под этим понятием подразумевается то, что у меня обозначено как "набор интерфейсов".



Честно говоря туповат я немного никак не могу понять разницу между клаасическим понятием интерфейса и твоим. Implements в Delphi дает возможность не агрегировать реализацию интерфейса в классе а использовать уже существующий итд. Как бы там нибыло в моем понятии интерфейс это структура ссылок на методы. Ну да ладно. С другой стороны в Net возможно динамическое создание объектов реализующих дополнительные возможности этого класса которые могут быть делегированы в класс например через ArrayList или однонаправленный список. Плюс развитая система рефлексии которая позволяет по типу свойств итд.
и солнце б утром не вставало, когда бы не было меня
Re[13]: Статья про развитие идей ООП. Жду комментариев.
От: Аноним  
Дата: 23.06.03 14:49
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Есть такой язык называется С++ там есть такое слово template. Его виртуозное использование это функциональное программирование чистой воды. Целью которого служит генерация кода. Что позволяет писать в несколько раз меньше кода. Зная об этом разработчики VC++7.1 сделали просто потряающий оптимизатор который генерирует код по эффективности почти равный ручной работе на asm'е. К стати, а как обстаят дела со скоростью выполнения на этих навороченых функциональных языках?


Не надо путать людей. Шаблоны в С++ не имеют прямого отношения к ФП. Может быть они слегка похожи, но если присмотреться то разница будет очевидной. Полиморфизм в ФЯ работает совсем не так, как шаблоны, никакой дополнительной генерации кода для каждого нового типа не нужно. Тип может иметь сколь угодно сложную структуру и при этом определяется автоматически. Если вы попробуете, что-то подобное реализовать с помощью шаблонов, то получите геморой с огромными описаниями типов с уродливыми <>.
Чтобы было понятнее я приведу функцию mmap, которая применяет функцию ко всем элементам списка
let mmap list func =
     match list with
        tail::head => (func tail)::(mmap head func)
     |  [] => []

Вот и все определение для функции, которая принимает на вход список из элементов любого типа и применяет к ним функцию, которая возвращает какой угодно тип. Для использования этой функции нужно просто вызвать ее с соответсвующими аргументами. Сравните теперь это с тем, что пришлось бы написать на С++, почуствуйте разницу. Не говоря уже о том, что шаблоны не позволяют использовать частичные функции, ленивые вычисления, pattern matching для быстрого разбора сложных по структуре типов и т.п. А если вспомнить как реализованы шаблоны в разных компиляторах...

ФЯ как раз не навороченные. Я в одиночку напишу за пару месяцев компилятор такого простого языка, где будут все основные полезные возможности, а вот компилятор С++ боюсь и за пару лет одному человеку не написать. А со скоростью дела обстоят нормально. Если для языка есть компилятор и он не чисто функциональный, то на некоторых задачах (связанных, например, с ИИ), я уверен, он сделает даже С. Я не хочу здесь распространяться на эту тему, почитайте статью Why functional programming matters. Она есть в инете и там все объяснено гораздо лучше, чем мог бы объяснить я. Зайдите на сайт ocaml'a и поищите в новостях, там было сообщение о том, что они в каком-то сравнении компиляторов заняли высокое место.
Re[14]: Статья про развитие идей ООП. Жду комментариев.
От: Sergey Россия  
Дата: 23.06.03 15:54
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, WolfHound, Вы писали:


WH>>Есть такой язык называется С++ там есть такое слово template. Его виртуозное использование это функциональное программирование чистой воды. Целью которого служит генерация кода. Что позволяет писать в несколько раз меньше кода. Зная об этом разработчики VC++7.1 сделали просто потряающий оптимизатор который генерирует код по эффективности почти равный ручной работе на asm'е. К стати, а как обстаят дела со скоростью выполнения на этих навороченых функциональных языках?


А>Не надо путать людей. Шаблоны в С++ не имеют прямого отношения к ФП.


Эт ты зря. Просто не знаешь, о чем идет речь.

А>Может быть они слегка похожи, но если присмотреться то разница будет очевидной. Полиморфизм в ФЯ работает совсем не так, как шаблоны, никакой дополнительной генерации кода для каждого нового типа не нужно.


Ты не понял, про что тебе говорят. Шаблоны в C++ сами по себе — ФЯ для управления кодогенерацией (хотя и довольно убогий). И говорить про дополнительную генерацию кода в этом контексте не имеет смысла, так как функциональная программа на С++'ных шаблонах исполняется в момент компиляции и сама генерирует код.

А>Тип может иметь сколь угодно сложную структуру и при этом определяется автоматически.


Мимо кассы

А>Если вы попробуете, что-то подобное реализовать с помощью шаблонов, то получите геморой с огромными описаниями типов с уродливыми <>.


Хе, в том ФЯ, что скрывается в шаблонах С++ значением переменной является тип В том Вот чего шаблонам в С++ действительно не хватает, так это переменного числа параметров. Ну и скобки треугольные кому-то кажуться уродливыми

А>Не говоря уже о том, что шаблоны не позволяют использовать частичные функции, ленивые вычисления, pattern matching для быстрого разбора сложных по структуре типов и т.п.


Вот как раз pattern matching там есть, вместе с ленивыми вычислениями. А что ты имешь в виду под частичными функциями, я просто не в курсе.

А>А если вспомнить как реализованы шаблоны в разных компиляторах...


В современных компиляторах — более-менее нормально, в старых — отвратно.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[15]: Статья про развитие идей ООП. Жду комментариев.
От: Аноним  
Дата: 23.06.03 17:26
Оценка:
Здравствуйте, Sergey, Вы писали:

S>Ты не понял, про что тебе говорят. Шаблоны в C++ сами по себе — ФЯ для управления кодогенерацией (хотя и довольно убогий). И говорить про дополнительную генерацию кода в этом контексте не имеет смысла, так как функциональная программа на С++'ных шаблонах исполняется в момент компиляции и сама генерирует код.


Да, не заметил, что речь идет о генерации кода, но тогда собственно о чем речь? Приведите ваши доказательства, что шаблоны ФЯ. На мой взгляд они имеют мало общего. Чтобы была хоть какая-то общая база приведу определение из comp.functional, если не ошибаюсь.

Functional programming is a style of programming that emphasizes the evaluation of expressions, rather than execution of commands. The expressions in these language are formed by using functions to combine basic values. A functional language is a language that supports and encourages programming in a functional style.

Может наука ушла вперед, но насколько я помню шаблон по своей сути функция, которой дают названия типов или значения констант и она возвращает текст класса, метода, функции и т.п. Мы не можем комбинировать такие функции, поскольку бессмысленно подставлять текст программы вместо переменной. И в этом заключается главная разница между шаблонами и ФЯ, в ФЯ можно подставить вместо переменной значение другой функции, если угодно можно подставить даже саму эту функцию, заменив ее вызовы на ее тело.

S>Хе, в том ФЯ, что скрывается в шаблонах С++ значением переменной является тип В том Вот чего шаблонам в С++ действительно не хватает, так это переменного числа параметров. Ну и скобки треугольные кому-то кажуться уродливыми


Уродливо будет выглядеть вся запись, если в ней несколько типов да еще вложенных. Я понимаю, что это издержки явного указания типов, но тем не менее.

S>Вот как раз pattern matching там есть, вместе с ленивыми вычислениями. А что ты имешь в виду под частичными функциями, я просто не в курсе.


Хотелось бы знать, что вы имеете ввиду под pm и ленивыми вычислениями относительно шаблонов. Частичными функциями (я просто забыл, как они по научному называются) я имеею ввиду возможность оставить функцию недовычисленной, т.е. типа add x y = x + y; part_add x = add x 10;
Re[16]: Статья про развитие идей ООП. Жду комментариев.
От: WolfHound  
Дата: 23.06.03 18:50
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Может наука ушла вперед, но насколько я помню шаблон по своей сути функция, которой дают названия типов или значения констант и она возвращает текст класса, метода, функции и т.п. Мы не можем комбинировать такие функции, поскольку бессмысленно подставлять текст программы вместо переменной. И в этом заключается главная разница между шаблонами и ФЯ, в ФЯ можно подставить вместо переменной значение другой функции, если угодно можно подставить даже саму эту функцию, заменив ее вызовы на ее тело.

http://www.rsdn.ru/forum/Message.aspx?mid=303515
Автор: WolfHound
Дата: 22.06.03

Практически весь код это функциональная программа на шаблонах. Согласен?

А>Хотелось бы знать, что вы имеете ввиду под pm и ленивыми вычислениями относительно шаблонов. Частичными функциями (я просто забыл, как они по научному называются) я имеею ввиду возможность оставить функцию недовычисленной, т.е. типа add x y = x + y; part_add x = add x 10;

void add(int a, int b)
{
    std::cout<<"a="<<a<<";b="<<b<<";a+b="<<a+b<<"\n";
}
int main()
{
    std::vector<int> vec;
    vec.push_back(1);
    vec.push_back(2);
    vec.push_back(3);
    vec.push_back(4);
    std::for_each(vec.begin(), vec.end(), boost::bind(&add, _1, 10));
}

Ы?
... << RSDN@Home 1.0 beta 6a >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[17]: Статья про развитие идей ООП. Жду комментариев.
От: Аноним  
Дата: 24.06.03 09:33
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>http://www.rsdn.ru/forum/Message.aspx?mid=303515
Автор: WolfHound
Дата: 22.06.03

WH>Практически весь код это функциональная программа на шаблонах. Согласен?

Согласен. Действительно наука ушла вперед. Только применимость подобных методов под вопросом. Представьте, что константы достаточно
большие, сколько тогда функций придется сгенерировать компилятору? Пусть он поймет, что функции одноразовые, но тогда встает вопрос о понятности такого кода. А если граница интервалов 10000, а самих интервалов всего 10. Из-за ограничений шаблонов вы будете вынуждены хранить массив из 10000 элементов, чтобы иметь возможность создавать классы runtime. А если бы классы создавались по номеру возвращаемому функцией (т.е. создаем класс X<f(n)>)?
Кроме того, я и без шаблонов могу прекрасно писать в функциональном стиле на С++, просто это не имеет никакого смысла, поскольку делать это гораздо сложнее, чем на специализированном языке. Вот для примера, как могла бы выглядеть аналогичная вашей программа на ФЯ. Только вместо класса — функция.
let OptimizedList = [(65,95); (-10,20); (22,35); (60,70);
        (600,700); (630,670); (21,21)];

let Print_func x () = print x;
let Empty_print_func ()  = ();


let sort_func (n1,m1) (n2,m2)  = if (n1 > n2) and (m1 > m2) then 1
                                                else 0;
let sorted_list = sort OptList sort_func;

let optimize_list OptList =
        match OptList with
                (n1,m1)::(n2,m2)::tail => if (m1+1 < n2) or (m2+1 < n1)
                                        then (if (n1 < n2) then n1 else n2, if (m1 > m2) then m1 else m2)::(optimize_list tail)
        |       (n,m)::null => [(n,m)]
        |       null => null;

let PrintTypeList OptList =
        match OptList with
                (n,m) => (print "Interval ", print n, print ",", print m)
        |       null => ();

let CreateFuncByIntervalList OptList Num =
        match OptList with
                (n,m)::tail => if ((Num <= m) and (Num >= n)) then Print_func Num
                                else CreateFuncByIntervalList tail Num
        |       null => Empty_print_func;

let Main () =
        let OptList = optimize_list sorted_list in
        let PrintTypeList OptList in
        let print_1 = CreateFuncByIntervalList OptList 0 in
        let print_2 =  CreateFuncByIntervalList OptList 650 in
        ....
         (print_1 (), print_2 (), ... );

А>>Хотелось бы знать, что вы имеете ввиду под pm и ленивыми вычислениями относительно шаблонов. Частичными функциями (я просто забыл, как они по научному называются) я имеею ввиду возможность оставить функцию недовычисленной, т.е. типа add x y = x + y; part_add x = add x 10;
    std::for_each(vec.begin(), vec.end(), boost::bind(&add, _1, 10));

WH>Ы?

Напишите, что такое bind и _1. Я не знаком с этой библиотекой.

Короче, я согласен. что шаблоны в С++ дают возможность оперировать типами и константами в функциональном стиле. Но это в такой же степени является функциональным программированием, в каком программирование на basic является императивным. Сложно и очень ограничены возможности. При этом я не отрицаю, что шаблоны увеличивают возможности С++.
Re[16]: Статья про развитие идей ООП. Жду комментариев.
От: Sergey Россия  
Дата: 25.06.03 07:36
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Sergey, Вы писали:


S>>Ты не понял, про что тебе говорят. Шаблоны в C++ сами по себе — ФЯ для управления кодогенерацией (хотя и довольно убогий). И говорить про дополнительную генерацию кода в этом контексте не имеет смысла, так как функциональная программа на С++'ных шаблонах исполняется в момент компиляции и сама генерирует код.


А>Да, не заметил, что речь идет о генерации кода, но тогда собственно о чем речь? Приведите ваши доказательства, что шаблоны ФЯ. На мой взгляд они имеют мало общего. Чтобы была хоть какая-то общая база приведу определение из comp.functional, если не ошибаюсь.


А>Functional programming is a style of programming that emphasizes the evaluation of expressions, rather than execution of commands.


Именно. При раскрытии шаблонной функции как раз идет проверка совпадений типов и при необходимости — дальнейшее раскрытие шаблонов в нужных "ветках" алгоритмы.

А>The expressions in these language are formed by using functions to combine basic values.


А у нас: values — только для целочисленных констант, но наравне с values добавляются типы.

А>A functional language is a language that supports and encourages programming in a functional style.


Ну это уже масло маслянное

А>Может наука ушла вперед, но насколько я помню шаблон по своей сути функция, которой дают названия типов или значения констант и она возвращает текст класса, метода, функции и т.п.


Угу. Только текст этот в общем случае опять шаблонный будет. Что позволяет писать программы для компилятора.

А>Мы не можем комбинировать такие функции, поскольку бессмысленно подставлять текст программы вместо переменной.


Можем. Если какой-то кусок текста программы представляет собой тип, то он вполне может быть передан в качестве переменной на вход другой функции-щаблона.

А>И в этом заключается главная разница между шаблонами и ФЯ, в ФЯ можно подставить вместо переменной значение другой функции, если угодно можно подставить даже саму эту функцию, заменив ее вызовы на ее тело.


Функция сама является типом и может быть передана в качестве аргумента в другую (шаблонную) функцию.

S>>Хе, в том ФЯ, что скрывается в шаблонах С++ значением переменной является тип В том Вот чего шаблонам в С++ действительно не хватает, так это переменного числа параметров. Ну и скобки треугольные кому-то кажуться уродливыми


А>Уродливо будет выглядеть вся запись, если в ней несколько типов да еще вложенных.


На вкус и на цвет... Мне примеры на ocaml'е с непривычки тоже уродливыми кажутся.

А>Я понимаю, что это издержки явного указания типов, но тем не менее.


Это издержки исчисления типов, а вовсе не их избыточного указания.

S>>Вот как раз pattern matching там есть, вместе с ленивыми вычислениями. А что ты имешь в виду под частичными функциями, я просто не в курсе.


А>Хотелось бы знать, что вы имеете ввиду под pm и ленивыми вычислениями относительно шаблонов.


Компилятор не раскрывает шаблоны там, где это не требуется — ограничивается (нестрогой) проверкой синтаксиса.

А>Частичными функциями (я просто забыл, как они по научному называются) я имеею ввиду возможность оставить функцию недовычисленной, т.е. типа add x y = x + y; part_add x = add x 10;


Это уже я не понял. Че оно делает-то и в чем тут "частичность"?
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[18]: Статья про развитие идей ООП. Жду комментариев.
От: Sergey Россия  
Дата: 25.06.03 15:31
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Да, спасибо, я уже понял все это на примере приведенном выше. Но у меня есть пара замечаний, которые я привел в том числе и к тому примеру.

А>Не рекомендовал бы изучать ФП на примере шаблонов. Уж больно там запутанный синтаксис, корявые средства построения программ, да и язык сам по себе уж больно примитивный.

Язык действительно примитивный (в части ФЯ), синтаксис, на мой взгляд, вполне приемлемый, а вот насчет корявых средств построения программ — это ты о чем вообще? Язык — он и есть средство построения программ, так?

А>Шаблоны по сути довесок к С++ и может сложиться мнение, что ФП в целом малопонятно и нежизнеспособно само по себе.


Вот несчет применимости чистых функциональных языков в качестве полноценных средств коммерческого программирования у меня, например, сильные сомнения...

А>Кроме того, возникает ощущение, что функциональность шаблонов это side effect, а не главная цель. Хотя я не знаю, какая была мотивация у разработчиков, может и ошибаюсь.


Мне тоже кажется, что ФЯ в шаблонах самозародился

S>>На вкус и на цвет... Мне примеры на ocaml'е с непривычки тоже уродливыми кажутся.

А>Здесь дело не во внешней красоте, а в том, что для шаблонов нужно огромное количество писанины, в которой еще потом и ошибки искать придется, а я помню насколько понятные бывают сообщения об ошибках, когда речь идет о шаблонах.

Ну это у тебя по VC 6 или более ранним, наверное, воспоминания. А насчет огромного количества писанины — никто ж не запрещает библиотеками пользоваться. Кроме того, длинные-предлинные типы, часто возникающие при работе с шаблонами, обычно нигде в тексте программы не фигурируют и нужны только компилятору

S>>Это уже я не понял. Че оно делает-то и в чем тут "частичность"?

А>По научному curring. Одно из главных отличий от императивных языков, мы можем писать f x1 x2 x3 вместо f(x1,x2,x3), а потом явно указать, например x3 и использовать уже функцию от 2-х аргументов. Крайне полезное свойство.

А чем отличается от такого:

void f(int a, float b, long c)
{
   ...
}

void f(int a, long c)
{
   f(a, 1.5, c);
}


Если дело только в том, чтобы не определять явно новую функцию от двух переменных, а иметь какой-то синтаксис для передачи функции от трех переменных туда, где требуется функция от двух, то можно писать так:

boost::bind(f, _1, 1.5, _2);  // возвращает функцию от двух переменных (a, b), вызывающую f(a, 1.5, b)


Можно даже аргументы при необходимости переставить:

boost::bind(f, _2, 1.5, _1);  // возвращает функцию от двух переменных (a, b), вызывающую f(b, 1.5, a)
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[19]: Статья про развитие идей ООП. Жду комментариев.
От: Аноним  
Дата: 25.06.03 18:23
Оценка:
Здравствуйте, Sergey, Вы писали:

S>Вот несчет применимости чистых функциональных языков в качестве полноценных средств коммерческого программирования у меня, например, сильные сомнения...

Чистых может быть. Но call-by-value языки я думаю задвинут С++ по быстродействию при символьных вычислениях. Во всяком случае в сегодняшнем мире джав и си шарпов смешно говорить о каком то существенном преимуществе императивных языков. Естественно, драйвер на них писать не стоит, но делать то, что делают на Джаве, скажем, вполне реально. А то что они широко не используются в разработке, так на то я думаю есть объективные причины, типа консервативности тех, кто мог бы изменить ситуацию. Если бы Микрософт вдруг решил сделать ставку на ML, все виндовые программисты завтра бы писали на ML.

S>А чем отличается от такого:


S>
S>void f(int a, float b, long c)
S>{
S>   ...
S>}

S>void f(int a, long c)
S>{
S>   f(a, 1.5, c);
S>}

S>


S>Если дело только в том, чтобы не определять явно новую функцию от двух переменных, а иметь какой-то синтаксис для передачи функции от трех переменных туда, где требуется функция от двух, то можно писать так:


S>
S>boost::bind(f, _1, 1.5, _2);  // возвращает функцию от двух переменных (a, b), вызывающую f(a, 1.5, b)
S>


S>Можно даже аргументы при необходимости переставить:


S>
S>boost::bind(f, _2, 1.5, _1);  // возвращает функцию от двух переменных (a, b), вызывающую f(b, 1.5, a)
S>


Возможно ничем. Но для любого количества переменных заготовленной конструкции, я так понимаю, нет. Кроме того, я уже говорил, что на С++ можно писать функционально в любом случае, даже без шаблонов. Для f я мог ручками определить g, которая делает то, что нужно. bind лишь сократил время, необходимое для этого. В данном случае уже идет С++, а не шаблонный язык, а оспаривать, что С++ очень плох для ФП, думаю, вы не будете.
Re: Ууу....
От: Poudy Россия  
Дата: 28.06.03 08:36
Оценка:
Здравствуйте, Voblin, Вы писали:

V>Может быть, кому-нибудь будет интересно.

V>http://voblin.nm.ru/objects_classes.dhtml
V>Сразу вопрос: стоит ли это опубликовать в RSDN?

Все смелости не хватало прочесть ветку.

А не бесполезны ли виртуальные классы?
Заметим, что в примере они используются в локальных методах. Т.е. как одноразовое средство. А в этом случае можно обойтись просто двумя классами, ведь мы знаем их конкретные типы. Если же использовать долгоживущие виртуальные классы, то скорее всего у разработчика появится жедание оформить их "официально", чтобы не писать параметром методу нечно вроде (IFruit, IGoods, IMoneraryUnit, IReusabe, IStorable...). Я это к чему — использование mixin есть четкая последовательная процедура. Дело не в C++, а в том, что примесь проектируется с таким учетом, что просто добавляет функциональности, а не пытается обмануть кого-то полиморфным поведением.

На самом-то деле все упирается в контекст использования человеком понятий. Это только кажется, что систему с PlasticApple можно так легко разрулить. Под одним и тем же Plastic человеком используются десятки разных классов.
Просто это все разные Plastic, разные "млекопитающее" и все остальное.

Все просто. Пластмасса — значит чаще всего плавает, мягкая, горит (даже тут оговорки). Если анализировать ассоциации, т.е. как раз то, что "можно с этим делать", то вот:

1. Клавиатура пластмассовая (вроде) — почему-то не приходит в голову, что она плавает.
2. Начинаешь смотреть вокруг и кажется, что ни одна из пластмассовых вещей не плавает,
хотя опыт показывает обратное — еще как плавает, если не налить в корпус воды (как в случае с пластиковой
бутылкой).
3. Про мягкую тоже поторопились.
4. Быть может, неотемлемое свойство пластмассы, которое можно как-то использовать, — это ее долговечность?
Нет. Полезная долговечность не заключается в том, но на мусорке она не будет гнить тысячу лет. Надо, чтоб
родукт не ломался, тут-то и облом.
5. Пожалуй так, пластмассовый — значит дешевое говно, которое быстро и внезапно ломается. Чинить — дохлый номер.
6. А как же пластиковые лодки и яхты?
7. Тогда скажем так — пластмассовый, это состоящий из длинных повторяющихся цепочек углеводородов с небольшим числом
примесей, которые придают "этому" желаемые свойства. Это уже из области бесполезных книжных определений. Или нет?
8. Обратимся к спецу по "пластмассовый" — о говорит: "Какой еще пластмассовый! Ты мне сделай, чтоб по марке
выводился справочник производителей и цены. А порошек мы на глаз кладем. От температуры зависит." Так от
температуры или на глаз? "Уйди на фиг."
9. Пластмассовый, значит дешевый, поддельный, яркий, красивый, но непременно ядовитый и несьедобный,
противоположность всему живому, что бы там ни говорили про органические соединения.

Это говорит о том, что классификация, обычно вводимая человеком — просто чущь собачья. Именно поэтому любой простой вопрос к опытному прикладному специалисту по чему_бы_там_ни_было выявляет у него на лбу складки тяжелого размышления : "Как бы ему, дурню, рассказать, чтобы коротенько, часа на два, и не запутать вконец". А Быстрые Ответы даются на корректно и четко поставленные узкие вопросы. Потому и код шаблонов такой. Поэтому единственный путь сокрашения издержек, размера кода, времени размышления и т.д. — выявление, документирование, унификация и стандартизация всех неявных предположений о процессе планирования, работе компилятора, работе с типами и т.д.

После тысяч провальных и почти не провальных проектов по всему миру такие предположения уточняются, объединяются, и согласно этому выпускается большая и сложная библиотека. Организованная весьма однообразно, на простом, не допускающем разночтений языке, с подробной документацией на каждый "пук", для идиотов. Это то, чем занимается Microsoft, за что его все любят, и то, за что ненавидят.

Язык, это не только код, но и средство модификации этого кода. Любой программист отдаст мизинец за среду, в которой 1.4 Mb исходников ворочаются, словно 1.4 Kb. И не суть важно что это — autocomletiotion или метаклассы с контекстами.

В общем, система с наборами интерфейсов позволяет сильно модифицировать "представление в голове" почти не трогая код. Но сам код при этом по-прежнему остается тяжело модифицируемым.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.