Re[20]: И опять С++ vs С#
От: vdimas Россия  
Дата: 24.11.04 14:02
Оценка: 14 (3) :)
Здравствуйте, VladD2, Вы писали:

VD>В качестве другого примера могу привести делегат. Попробуй поглядеть сколько нужно наколбасить кода на С++ чтобы его сэмулировать.

вообще-то есть слоты и функторы, ну а самый простой пример вот
Автор: vdimas
Дата: 21.11.04
:
(уверен, этот исходник меньше аналогичного из донета, и посмотри, что 4/5-х исходника сделаны по copy&paste, для тупого описания частичных специализаций, и эти частичные специализации не содержат никакого кода, кроме как делегирования метода целевому объекту)

VD>А потом добавь сюда то, что делегат является компонетной (рантаймной) сущьностью и дает прозначное использование в компонентах и ремоутинге.

VD>только вот вызовы методов через делегаты тормозят чего-то... а в приведенном мной примере примерно равны вызову виртуальной ф-ии.

Насчет ремоутинга не спорю, мета-инфрмация она и в африке метаинформация. Как компилируемый вариант я использую CORBA. И мой трафик гораздо меньше твоего (чистые бинарные представления сруктур передаются без метаинформации).

VD>В итоге получится, что в язык встроена огромная супер-универсальная библиотека. При этом достигаетя высокое удобство испольования, простота и выразительность.

Язык пользуется этой библиотекой и базируется на ней.

V>>если упомянутая задача неоднократная, то мне все-равно меньше чем тебе париться


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


[скип]

все понятно, для реализации твоих техник мне понадобятся 2 общеупотребимых хелпера:

template<typename T, typename From, T* Transform(From*)>
class TransformEnumerator : public IEnumerator<T> {
protected:
    IEnumerator<From>* from;
    T* current;
public:
    TransformEnumerator(IEnumerator<From>* from_) : from(from_) {}

    void Reset() { from->Reset(); }
    
    bool MoveNext() { 
        while(from->MoveNext() && (current=Transform(from->Current))==NULL);
        return current!=NULL
    }
    
    T* get_Current() { return current; }
};

class<typename T, typename From, IEnumerator<T>* Nest(From*)>
class NestedEnumerator: public IEnumerator<T> {
protected:
    IEnumerator<From>* from;
    IEnumerator<T>* nest;

public:
    NestedEnumerator(IEnumerator<From>* from_) : from(from_) {}

    void Reset() { 
        from->Reset(); 
        nest=NULL; 
    }

    bool MoveNext() { 
        while(nest == NULL || nest->MoveNext()==false) {
            if(from->MoveNext())
                nest = Nest(from->Current);
            else
                return false;
        }
        return true;
    }

    T* get_Current() { return nest->Current; }

    virtual T* ExtractNest(From* from_) = 0;
};


TransformEnumerator — преобразует один енумератор в другой
NestedEnumerator — осуществляет енумерацию вложенных элементов другого.

далее, твоя целевая задача состоит из нескольких (а я уверен — неоднократно используемых) аспектов:

struct MetaTasks {

    static Assembly* LoadAssembly(String* path) {
        try {
            return Assembly::LoadFrom(path);
        } catch (Exception ex) {
            _result.Errors.Add(new CompilerError(
                "", 0, 0, "",
                "Can't load external meta assembly: "
                + ex.Message));
        }
        return NULL;
    }

    static Type* CheckIMetaRule(Type* type) {
        if(type->GetInterface("IMetaRule"))
            return type;
        return NULL;
    }

    static IEnumerator<Type>* GetAssemblyTypes(Assembly* a) {
        return a->GetTypes()->GetEnumerator();
    }


    static IEnumerator<Type>* GetIMetaRuleTypes(IEnumerator<String> assembliesList) {
    return new TransformEnumerator<Type, Type, MetaTasks::CheckIMetaRule>(
        new NestedEnumerator<Type, Assembly, MetaTasks::GetAssemblyTypes>(
            new TransformEnumerator<Assembly, String, MetaTasks::LoadAssembly>(assembliesList)));
    }
}


Таким образом, я применяю обычную в ООП и структурном программировании декомпозицию задач.
теперь твоя программа может использовать эти аспекты в любом месте, например в указанном тобой:
foreach(Type *type,  MetaTasks::GetIMetaRuleTypes(assembliesList1)) {
    // тут делай что хошь

    foreach(Type *type,  MetaTasks::GetIMetaRuleTypes(assembliesList2)) {
        // и тут тоже

    }
}

(foreach на С++ тут
Автор: WolfHound
Дата: 07.11.03
, обрати внимание на порождаемый ассемблерный код — песня!, правда, это не относится к C#-подобным енумераторам, но можно легко переделать для работы и на них... однако в С++ свои правила , иначе бы мы не получали тот самый ассемблерный код, где надо 3 команды процессора для организации foreach )

Причем, вспомогательные классы NestEnumerator и TransformEnumerator — это однократно введенные классы, для реализации подобных алгоритмов.
(кстати, мне уже стало интересно, сколько мне всего надо хелперов, чтобы покрыть все техники, предоставляемые yield. Боюсь — уже немного осталось, а их использование весьма гибко и провоцирует выделять повторно-применяемые аспекты у задач, а не "строгать код по-месту").

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

Смотрим, что у нас получилось. Твое рекурсивное решение создаст рекурсивно столько енумераторов, сколько узлов в дереве.
Далее, т.к. в скомпилированном коде среда будет выполнять MoveNext() и вызов get_Current() твоих енумераторов, то, при глубине дерева в 10 элементов ты получишь на каждый вызов этих методов енумератора верхнего уровня вызов по цепочке таких же 10-ти виртуальных ф-й вложенных енумераторов. Учитывая, что среднестатистическое дерево имеет структуру, близкую к треугольной (с рутом в вершине), большинство узлов дерева лежат на "глубоких" уровнях.

Не знаю, как там принято у C#-программистов, но в С++ за подобные решения можно уже начинать увольнять.
Кстати, подобная техника обхода дерева как раз реализуема теми же усилиями в С++ с использованием указанного NestedEnumerator. Но это очень плохое решение.

V>>Ну с какого перепугу, по-твоему, усложнять язык дополниельными (не императивными!!!) конструкциями?


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


В свете вышесказанного — не убедил.

Да, C# начинает скрывать многие подробности реализации, но начинающие программисты могут не знать, что именно стоит за этим, и, идя по наилегчайшему пути, порождать программы, в которых сидит тот самый маляр, который в первый день покрасил 100 метров, а на 10-й день — 1 метр.

К тому же, ты продемонстрировал низкий уровень повторного использования кода.
Re[28]: И опять С++ vs С#
От: WolfHound  
Дата: 08.12.04 07:51
Оценка: 2 (2) +2
Здравствуйте, VladD2, Вы писали:

VD>И все же похоже ты действительно не очень понимашь о чем идет речь. Речь идет не об энумераторах, а об итераторах — новой концепци реализации тех самх энумераторов. см. http://gzip.rsdn.ru/article/csharp/newincsharp.xml#EJA
Автор(ы): Владислав Чистяков (VladD2)
Дата: 24.06.2004
В статье рассказывается о новшествах, которые должны появиться в новой версии языка C#

раздел "Итераторы".

Ты меня точно с кемто путаешь. Про этот синтаксический сахар я прекрасно знаю. Но он не добавляет никакой функциональности.

Кстати а как там с

Из обнаруженных мной проблем можно выделить то, что мне не удалось создать итератор, производящий рекурсивный вызов. Это довольно серьезное ограничение, поскольку итераторы как нельзя лучше подошли бы для деревьев и других рекурсивных структур, для которых создавать перечислители особо сложно и неудобно. Будем надеяться, что к release-версии эту проблему устранят.


VD>Дык, как видишь ты с успехом обошелся без деструктора.

Ну и в С++ я прекрасно обхожусь без делегатов.
VD>При грамотном подходе потребоность в них появляется очень редко.
Что есть грамотное проектирование вопрос очень сложный и очень сильно зависит от решаемых задач.
VD>Я уже забыл когда мне они были нужны.
using'ом давно пользовался? А это и есть кастыль для хоть какойто эмуляции автоматических деструкторов. Чтобы не приходилось мудить с try/finnaly как это делается в жабе и дельфе...
VD>Нужно только придерживаться идеи занятия ресурсов на минимально возможный период времени.
Да все так и делают. Но вот только когда это поддержывается языком это делать удобней. using конечно тоже не худшее решение но деструкторы лучше.

VD>А твою проблему можно решить намного проще и элегантрее. Например, так:

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

VD>Надо сказать, что припахабно.

А по моему вполне нормально.
VD>Кмпиляцию тормозя,
Миф
VD>с полиморфизмом проблемы,
В смысле
VD>между процессами не передаш,
Ну это проблемы несколько иного порядка и решать их надо на несколько другом уровне.
VD>интерграция с разными компонентными технологиями вроде COM фиговая и т.п.
Ну не знаю. У меня проблем небыло.

VD>Это сказка для не посвященных. Я как бы сам плавал с 25-минутной компиляцией проекта со всем инкриментами и прекомпайлами.

Я какбы сам компилировал.

VD>Проблемы с вызовом деструкторов у суперклассов не имеющих виртуального деструктор тебе знакомы?

Я тебя умоляю... Ты уже устраивал флейм на эту тему. Результаты на лицо... тебя никто не поддержал ибо это не проблема.
VD>А размер int-а?
А что размер инта? У тебя хоть раз с ним были проблемы?
VD>Все это выбор скорости в ущерб стройности дизайна языка и простоте его использования. Примеров таких море.
А валью типы в шарпе? Нафига еще одна сущность?

это выбор скорости в ущерб стройности дизайна языка и простоте его использования


VD>Это реально если этим заниматься.

Твои предложения на счет деструкторов точно не реально.
VD>Вот C++/CLI содают же. И "гигабайты" вроде не страдают.
Тебе самому не смешно? Это чудо можно использовать только для интеграции мендежет и анменеджед кода.
К томуже проблемы то они и не решают.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[24]: И опять С++ vs С#
От: vdimas Россия  
Дата: 28.11.04 22:33
Оценка: +3 -1
Здравствуйте, VladD2, Вы писали:

VD>Еще одна непрада. Твой код не только больше, он еще и не полон. Ты каждый раз забываешь продемонстрировать код самого шаблона. И каждый раз пытаешся опустить тот факт, что тебе нужно резко усложнять алгоритм.


Так и есть. По диагонали все-таки читаешь. Учитывая твои предыдущие замечания на этот раз я приводил ПОЛНЫЙ код. Там 2 блока — блок с шаблонными классами-хелперами и блок, где я их применяю. И он полностью эквивалентен твоему примеру.

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


No comments... Похоже ты всерьез считаешь компилятор умнее меня
Да загляни в тот код, мне где-то даже обидно, что ты перед тем постом упрекнул в неполной реализации, а теперь даже не заглянул... Некрасиво получилось.

Все т.н. ленивые перечисления — это элементарщина, в том коде решено 2-мя строками целевого алгоритма (метод MoveNext). Вся остальная т.н. "тонна кода" — суть строки объявления класса и реализуемых методов интерфейса.


V>> хотя у тебя "сверх-фичи", а у меня всего лишь С++, на котором я легко реализую любые сверх-фичи



VD>Это более чем доказывает твою предвзятость, не зелание вникать в суть, оценивать по достоинству нововедения и как следствие адекватно воспринимать уровень языка.


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


VD>Я не вижу что мне отвечать по деревьям.

Так ты даже не прочитал ответ на свои же аргументы в предыдущщих постах?

VD>Создай свою реализацию. Оцени гору кода которую создал, а потом сравни это с простыми и компактными итераторами.

Уже создал — NestedEnumerator. Теперь мой код обхода дерева может быть строка-в-строку похож на твой. Но это, как раз таки, не суть важно. Ты не ответил на принципиальный вопрос о применимости рекурсивных итераторов.

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

-------------
несколько абзацев со строками типа "цепляешься за старое" я позволил себе проигнорировать как беспредметные ответвления.
Re[31]: И опять С++ vs С#
От: vdimas Россия  
Дата: 28.11.04 23:14
Оценка: 18 (1) +1 -1
Здравствуйте, Павел Кузнецов, Вы писали:

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


ПК>Например, всякая математика. Для простоты возьмем алгоритм решения систем линейных уравнений. В C++ его можно написать в обобщенном виде, так что он будет работать с любыми матрицами любых чисел. От матриц достаточно операции [i][j], от чисел — обычных для арифметики операций. В том числе программист может подставить типы, представляющие числа большей точности. Очевидно, если числа будут наследоваться от интерфейсов, то работа с ними будет для вычислений слишком медленной.


Хитер Паша, хитер...

Да не могут они ничего такого. Только через интерфейсы или (того хуже) через делегаты. Просто объявить сигнатуру метода и пользовать не получится.
Re[26]: И опять С++ vs С#
От: WolfHound  
Дата: 07.12.04 08:52
Оценка: 16 (2) +1
Здравствуйте, VladD2, Вы писали:

VD>Гора кода поскипана. Могу скзать, только что паттернами решаются любые задачи в том числе ООП на С. Вот только любые паттерны менее удобны и просты чем продуманные и хорошо встроенные идиомы языка.

Вот только эта "гора" которая не такая уж и гора... Скажем чтобы по человечески прикрутить MVC к WinForms мне тоже пришлось писать утилитарный контейнер...

VD>Ты уверен что полностью понимашь, что такое итераторы C# 2.0?

Ты меня с Губановым не путаешь?
Итераторами C# можно пробежатся от начала и до конца контейнера (не обязательно контейнера) при этом только читая значения из него. Единственное чем он отличяется от инпут итератора это тем что можно вернутся в начало последовательности.
Тот итератор что показал я позволяет пройтись и вперед и назад, и читать и писать, позволяет запомнить и востановить произвольную позицию в процессе итерирования... А если теперь вспомнить про дазйн STL(знаю он тебе не нравится...)то возможности этих итераторов становятся просто огромными...

VD>Программирую на С++ я вынужден каждый раз писать приметивные базовые вещи.

А где не так? Вот я сейчас пишу на C# и я вынужден писать чисто утилитарныу классы. Зачем? Почему это все не встроено в язык?
VD>Зачем?
Вот именно зачем?
VD>Зачем мне извращаться и ломать голову как реализовать тот или иной патерн?
Вот именно? Почему Микрософтовци не сдлелали поддержку MVC? Почему мне пришлось это избретать самому?
VD>Мне проще когда все это делает порой строк кода используемого мной языка.
Ой как я с тобой согласен... но не все встроено в язык...
VD>Бесспорно, что на С++ с некоторой натяжкой в виде паттернов можно сэмулировать практически любую возможность C#.
Тоже относится и к C#. Вот например так я вешаю курсор песочные часы на форму.
            using(WaitCursor waitCursor = owner.WaitCursor())
            {
            //тут гора тормозного кода который может кинуть исключение итп
            }

Ладно что хоть с try/finnaly возится не приходится... А все почему? А по тому что в C# нет автоматических деструкторов. И их приходится эмулировать.
VD>Так делегаты в общем-то можно заменить объемистыми классами Буста или Локи,
И надо сказать очень не плохо эмулируются... через границу процесса его конечно вызвать нельзя но в приделах одного процесса оень даже не плохо работают.
VD>а итераторы еще какой-нибудь горкой кода
Еще раз в C# есть только инпут итераторы. В С++ выбор куда больше.
VD>в сочетании с малопонятным синтаксисом их применения.
Это очень спорный вопрос.
VD>Но зачем все это?
Что именно?
VD>Я правильно понимаю, чтобы убить еще чес при компиляции
Ну этот вопрос давно научились решать. Прекомпилид хидеры, инкреди билд(когда за компиляцию принимаются 20 компов...)
К тому же тормоза компиляции в С++ происходят несколько по другим причинам... Кстати компиляция C#2 происходит примерно с тойже скоростью что и компиляция С++ с прекомпилед хидерами...
VD>или чтобы запутаться в десятках реализаций?
Какие десятки реализаций? Мне одного STL хватает. Чго нет в STL есть в boost, а если чегото раз в год я не нахожу в boost то написать сотню строк не проблема.
А для левых либ по любому приходится писать враперы... Знаешь что такое Apache Portable Runtime и лучше тебе этого не знать...

VD>Да нет — это вопрос дизайна языка.

А это и есть очень филосовский вопрос.
VD>К дизайну С++ подходили довольно наплевательски.
Вобщем согласен.
VD>Он приносился в жертву эффективности и совместимости.
Ну жертв эффективности я чегото не заметил , а вот совместимость это да... Это они погорячились.
VD>В итоге получился довольно уродливый монстр который не хотят (а возможно боятся) менять сами его создатели.
Это не реально. Изменить этого монстра это значит поломать гигабайты кода... Именно по этому его меняют так окуратно и медленно.

Хотя конечно есть лазейка в прочем это тема для отдельного разговора. Но и на эту лазейку надо много ресурсов. У меня столько нет.
И тут надо действовать очень окуратно. Вон ребята D сделали... так над ними все хихикают... А все почему? А по тому что они подобно Вирту сражались с ветряными мельницами. Они даже вывод шаблонных параметров шаблона функции из типов аргументов зарубили... Мотивируя это некой абстрактной чистотой языка... Сделав это они убили очень много очень полезных возможностей. Это даже в C#2 есть...
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[24]: И опять С++ vs С#
От: WolfHound  
Дата: 04.12.04 18:59
Оценка: 3 (1) +2
Здравствуйте, VladD2, Вы писали:

VD>Для меня правильно все что удобно, и что способно упростить мою жизнь.

+1
VD>Итераторы появились в нескольких языках и хорошо себя зарекомедовали.
+1
VD>В С++ он досутупен как паттерн программирования и вызывает некоторый напряг при реализации.
1)STL-Like итераторы в С++ это совсем не те итераторы что в C#
2)Если приминить мозги то реализация STL-Like итератора дело не такое уж и напряжное
Например реализация итератора для двусвязного списка
    struct iterator
        :iterator_facade_t
            < iterator
            , value_type
            , std::bidirectional_iterator_tag
            >
    {
        friend struct const_iterator;
        iterator()
            :cur(0)
        {}
        iterator(pointer ptr)
            :cur(ptr)
        {}
    private:
        friend struct intrusive_list_t;
        iterator(intrusive_list_node_t* ptr)
            :cur(ptr)
        {}
    private:
        friend struct iterator_core_access;

        void increment() 
        { 
            cur=node_next(cur);
        }
        void decrement() 
        { 
            cur=node_prev(cur);
        }

        reference dereference()const
        { 
            return *static_cast<pointer>(cur);
        }

        bool equal(iterator const& that)const
        {
            return cur==that.cur;
        }
    private:
        intrusive_list_node_t* cur;
    };

С этим итератором можно делать гораздо больше чем с итераторами из C#.
Шаблон iterator_facade_t пишется раз и навсегда.(могу показать он очень простой но там кода много... почти все операторы перегружаются)

VD>Что лучше "чистота" языка или удобство и простота каждый решат для себя сам.

Что есть чистота языка вопрос очень филосовский...
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[26]: И опять С++ vs С#
От: vdimas Россия  
Дата: 30.11.04 12:31
Оценка: 1 (1) +2
Здравствуйте, VladD2, Вы писали:

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

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


Ты говорил, вроде, что я привел код не полностью. Он приведен полностью и функционально эквивалентен твоему.


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


На практике у С++ программистов по-другому реализована концепция итераторов. Хотя она вписывается в паттерн.


VD>Ты нагородил кучу грязи в которой еще разобраться нужно. А разбираться болшинство не буед.


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

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


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


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

V>>Уже создал — NestedEnumerator. Теперь мой код обхода дерева может быть строка-в-строку похож на твой.


VD>Это не правда.


Правда. Приведи свой код, а я приведу свой с использованием NestedEnumerator. И посмотришь.

V>> Но это, как раз таки, не суть важно. Ты не ответил на принципиальный вопрос о применимости рекурсивных итераторов.


VD>А что ты хочешь о них услышать?


А здесь
Автор: vdimas
Дата: 24.11.04
указал на мааленький такой подводный камешек. Последняя часть поста.

VD>Чушь поришь тут ты утверждая, что горы малопонятного кода лучше простых и ясных конструкций.

Повтори это после прочтения указанной сыылки

VD>Спорить с людьми утвреждающиеми, что и так все можно мне надоело уже в начале 90-ых, когда они утверждали, что все что можно на С++, можно и на С. Доказать таковым ничего нельзя. Их выличит только время. Крикуны от С и ассемблера уже докричались (хотя до сих пор иногда слышатся отдельные голоса). С++-ники пока что еще кричат. Ну, что-же... пусть кричат.


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

Наши итераторы — суть маленькое лирическое отступление, не более. Мне вообще эта тема не интересна, ибо итераторы в C# — весьма тяжеловесная сущность. А нынешняя возможность легко создавать рекурсивные итераторы меня вообще веселит. Мне даже трудно представить, до какой степени неэффективный код можно будет налепить, обойдясь несколькими строчками рекурсивных итераторов.

(И что характерно, у меня железка 3.2GHz, но я не чуствую, что она такая уж сверх-быстрая. Скажи мне о таких цифрах и этих ощущениях лет 10 назад — не поверил бы. Ты там говоришь, что через 10 такие как я вымрут... А я просто уверен, что через 10 лет на железке порядка 30-50GHz я тоже не буду чуствовать мощщи и скорости. То, как сейчас ведут себя GUI-дотнет приложения на моей железке не выдерживает никакой критики )
Re[24]: И опять С++ vs С#
От: Павел Кузнецов  
Дата: 25.11.04 15:00
Оценка: +2 -1
AndrewVK,

> V> Да ладно, все коллекции в дотнете — сплошной copy&paste.


> Для этого в 2.0 как раз и добавили дженерики, кои эту проблему решают превосходно.


Допустим, надо сделать generic контейнер с произвольным доступом, позволяющий эффективно вставлять элементы как в начало, так и в конец. Сделать такой контейнер — в общем-то не большая проблема: для этого нужно хранить элементы блоками. Но вот можно ли сделать в C# + .Net без copy-paste, с сохранением статической типизации, и не реализуя эти операции заново для разных контейнеров, чтобы данный контейнер можно было сортировать, искать в нем элементы последовательным поиском, бинарным поиском, искать в нем подпоследовательность, как с начала, так и с конца и т.п.?
Posted via RSDN NNTP Server 1.9 gamma
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[22]: И опять С++ vs С#
От: vdimas Россия  
Дата: 28.11.04 01:34
Оценка: +2 -1
Здравствуйте, VladD2, Вы писали:

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


VD>Основного утверждения о меньшей выразительности С++ ты опровергнуть так и не смог. Все эти горы кода приводимые в ответ только подтверждают это.


Странная у тебя оценка. похоже ты опять читаешь оппонента по диагонали.
В своих постах ты указал на т.н. "новые" трюки с yield. Я каждый из них однократно выражаю в 10-ти строках примитивного шаблонного кода. Там где реально использую — мой код не больше твоего, хотя у тебя "сверх-фичи", а у меня всего лишь С++, на котором я легко реализую любые сверх-фичи и не отстаю в эффективности их применения от "специально заточенных" конструкций. Это более чем показательно и доказательно. Второго такого инструмента пока не придумали.

Кстати, там пост состоит из 3-х частей. Ты не ответил по деревьям, а стоило бы.
Re[19]: И опять С++ vs С#
От: VladD2 Российская Империя www.nemerle.org
Дата: 28.11.04 19:30
Оценка: 23 (2)
Здравствуйте, Зверёк Харьковский, Вы писали:

ЗХ>Влад, а что этот код делает? Я не иронизирую, мне просто интересно. Что такое yield?


Вот тут http://gzip.rsdn.ru?/article/csharp/newincsharp.xml#XSLTPART149120120
Автор(ы): Владислав Чистяков (VladD2)
Дата: 24.06.2004
В статье рассказывается о новшествах, которые должны появиться в новой версии языка C#

все описано (см. раздел "Итераторы").

Основная суть:

Итераторы – это «синтаксический сахар», позволяющий значительно упростить реализацию перечислителей. Суть его заключается в том, что вместо создания класса и нудного превращения циклических алгоритмов просмотра коллекции в последовательный ее просмотр вам достаточно объявить одно свойство или метод, возвращающие интерфейсы IEnumerator, IEnumerable, IEnumerator<T> или IEnumerable<T>. Но это не совсем обычный метод. Дело в том, что он вызывается каждый раз, когда читающий коллекцию код вызывает метод IEnumerator.MoveNext. Если управление покидает этот метод ненасильственным путем, т.е. без принудительного yield return, то процесс перечисления заканчивается, и метод больше вызываться не будет. Если же вернуть управление с помощью оператора yield return, то возвращенное в нем значение станет текущим значением перечисления. Когда перечислителю потребуется следующий элемент (у него вызовут метод MoveNext), управление снова вернется в метод, причем с позиции, следующей непосредственно за той, что привела к выходу из метода в прошлый раз. Так продолжается до тех пор, пока управление не покинет метод без вызова yield return. Это может случиться, если вызвать yield break или просто дать управлению выйти из метода самостоятельно.

... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[25]: И опять С++ vs С#
От: vdimas Россия  
Дата: 02.12.04 11:18
Оценка: 17 (1) +1
Здравствуйте, Зверёк Харьковский, Вы писали:

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


ЗХ>>>угу. а чем это отличается от моей формулировки?

V>>тем, что алгоритм итерации будет развернут принципиально по-другому, чем в случае выноса в отдельный класс.
ЗХ>Не понял

Итератор должен хранить свое текущее состояние. Если алгоритм итерации нетривиален, то это может означать лишние трудозатраты на проектирование итератора. В случае с yield компилятор сам "разберется", что должно относиться к текущему состоянию итератора и построит из твоего алгоритма класс, инкапсулирующий в себе все эти моменты.
Re[21]: И опять С++ vs С#
От: VladD2 Российская Империя www.nemerle.org
Дата: 28.11.04 22:28
Оценка: 7 (1) -1
Здравствуйте, Зверёк Харьковский, Вы писали:

ЗХ>Поправь меня, если я ошибаюсь: все это предназначено для того, чтобы локализовать код итерации по классы в самом классе, а не выносить в отдельный класс итератора, isn't it?


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

Сила "yield return" в том, что он позволяет превратить алгоритм в список. При этом не вынуждая копировать все результаты, а стало быть позволяя делать линивые алгоритмы.

Хороший пример — алогоритмы обхода бинарного дерева. Дерево можно обойти множеством способов. Обход прекрасно выражается в иде рекурсивных процедур. Однако намного удобнее оперировать не рекурсией, а абстракцией "список". Самым легким решением было бы копирование всех объодимых элементов в некий список, но елси учесть, что зачастую объод делается частичный, и то что дерево может иметь большой объем, намного выгоднее было бы сделать некий динамический списк элементы которого формируются по мере запроса. Вот для таких задач "yield return" отличное решение. Мы пишем нужный рекурсивный алгоритм, тесно связанный с реализацией дерева, а на выходе получаем независимый, динамически формируемый списк.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[30]: И опять С++ vs С#
От: Павел Кузнецов  
Дата: 26.11.04 03:12
Оценка: 2 (1) :)
VladD2,

> ПК>То есть, можно и не наследуя контейнеры от общих интерфейсов?


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


Дык, он и раньше тем же самым был

> Объясняю. Это не С++! В дотнете ввели понятие дженерик-интерфейса и дженерик-делегата. Все что нужно абстрагировать выражается в их терминах. <...>


В таких пределах я это все знаю.

> ПК> Интересно, как, если без указания интерфейса, реализуемого параметром generic класса, у него доступны только методы object?


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


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

Например, всякая математика. Для простоты возьмем алгоритм решения систем линейных уравнений. В C++ его можно написать в обобщенном виде, так что он будет работать с любыми матрицами любых чисел. От матриц достаточно операции [i][j], от чисел — обычных для арифметики операций. В том числе программист может подставить типы, представляющие числа большей точности. Очевидно, если числа будут наследоваться от интерфейсов, то работа с ними будет для вычислений слишком медленной.

Кроме того, если не ошибаюсь, в C# "эффективными" типами являются структуры, которые наследовать нельзя.

Можно ли в C# сделать подобные обобщенные алгоритмы, которые можно будет использовать повторно, не требующие наследования от интерфейсов?

Или же там будет происходить какая-то "магия" все оптимизирующая до скорости встроенных типов даже при работе через интерфейсы? Что-то сложно верится...

> Если бы ты прочел не "соответствующие статьи", а конкретно эту, то и вопроса не возникло бы. Ну, да выше я привел настолько простое описание насколько сомг. Если и это не понятно, то я даже и не знаю, что и как объяснять. Тут уже стереотипы ломать нужно.


Это-то все понятно. Непонятно как решить, используя возможности generics, приведенные задачи при условии, что через интерфейс работать нельзя...
Posted via RSDN NNTP Server 1.9 delta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[23]: И опять С++ vs С#
От: Павел Кузнецов  
Дата: 29.11.04 21:30
Оценка: 1 (1) -1
vdimas,

> VD>Основного утверждения о меньшей выразительности С++ ты опровергнуть так и не смог. Все эти горы кода приводимые в ответ только подтверждают это.


> В своих постах ты указал на т.н. "новые" трюки с yield. Я каждый из них однократно выражаю в 10-ти строках примитивного шаблонного кода. <...>


Кста, вот еще на примерчик "выразительности" наткнулся: http://rsdn.ru/forum/Message.aspx?mid=919926#919926
Автор:
Дата: 27.11.04
Вполне естественно, что язык предоставляет далеко не все возможности, нужные программистам в готовом виде. Вопрос только в том, позволяет ли он легко добавить желаемое.

В C++ именно такая возможность есть:
void f(T&);

ничего на NULL проверять не надо — компилятор сам разберется.

Но даже если представить, что в самом языке этого не было бы, то реализовать такую рюшечку через шаблоны не составило бы никакого труда:
void f(ref<T>);

Ну-ка то же самое, да на C# (чур, препроцессоры не предлагать)
Posted via RSDN NNTP Server 1.9 delta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[23]: И опять С++ vs С#
От: VladD2 Российская Империя www.nemerle.org
Дата: 28.11.04 15:50
Оценка: -2
Здравствуйте, vdimas, Вы писали:

V>Странная у тебя оценка. похоже ты опять читаешь оппонента по диагонали.


Просто тебе очень хочется так думать.

V>В своих постах ты указал на т.н. "новые" трюки с yield.


Неправда. Я указал на новый оператор, дающий повышение уровня языка. Это не трюк. И реализуемые им вещи тоже не трюки.

V> Я каждый из них однократно выражаю в 10-ти строках примитивного шаблонного кода.


Вот именно что в 10 строкай, и именно что приметивный, и именно что каждый раз (причем каждый раз новый). Это совсем не тоже самое что в случае итераторов Шарпа.

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


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

V> хотя у тебя "сверх-фичи", а у меня всего лишь С++, на котором я легко реализую любые сверх-фичи


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

V> и не отстаю в эффективности их применения от "специально заточенных" конструкций.


Отстовать будешь ты. Именно твоя эффективность (продуктивность) станет ниже.

V> Это более чем показательно и доказательно. Второго такого инструмента пока не придумали.


Это более чем доказывает твою предвзятость, не зелание вникать в суть, оценивать по достоинству нововедения и как следствие адекватно воспринимать уровень языка.

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

В общем, счастливо оставаться в каменном веке.

V>Кстати, там пост состоит из 3-х частей. Ты не ответил по деревьям, а стоило бы.


Я не вижу что мне отвечать по деревьям. Создай свою реализацию. Оцени гору кода которую создал, а потом сравни это с простыми и компактными итераторами.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[24]: И опять С++ vs С#
От: vdimas Россия  
Дата: 07.12.04 11:42
Оценка: +2
Здравствуйте, VladD2, Вы писали:

V>>Обход дерева — самый неудачный пример применения итераторов.


VD>Отличный пример! Просто надо вгнать из головы всех тараканов связанных с оптимизацией.


не могу

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


VD>Это все горы ручной работы с переворотом мозгов достойным отдельной тренировки. Я веду речь о концептуальной, идейной чистоте. Концептуально итераторы очень простая и понятная идиома, позволяющая очень легко писать нетривиальные алгоритмы даже программистам не проевшим себе плеш на почве алгоритмостроения.


Хм... опять кухарки будут переучиваться на PHP, тьфу, на C#?

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


Как показывает практика, эти т.н. "более сложные задачи" являются более простыми с технологической т.з. Более того, разделение труда дошло до того, что эти более сложные задачи теперь решают не программисты, а системные аналитики или архитекторы. Из многих динамических и статических UML-диаграмм современные ср-ва разработки генерируют отличный код. (Borland Together, Sybase Power Designer). Начни активно использовать эти среды, и причина нашего спора отпадет (либо перейдет в другую область).

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


Программист именно и занимается реализацией/программированием систем. И его задача — делать свою работу качественно, выдавать эффективный код.

VD>Думаю, не нужно обяснять почему решение на итераторах окажется проще в реализации?

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

Мы вообще спорим с тобой о разных видениях на проблему порождения кода программистом. Ты явно ориентируешься на "быстрое" решение задач по месту. Я склонен бесконечно делить и обощать , вынеся некий алгоритм в отдельную многократно (!!!) используемую сущность, я не вижу проблемы в том, чтобы у оформленной таким образом программной единицы оказалось десяток лишних строк. (Ибо этот десяток срок может дать гораздо даже меньший бинарный код и уж точно гораждо более в щедящем реждиме попользует ресурсы проца)
Re[28]: И опять С++ vs С#
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 07.12.04 14:52
Оценка: +1 :)
Здравствуйте, VladD2, Вы писали:

V>> Во всей этой ветке речь не шла о том, что дотнет не имеет будущего.

VD>Да нет. Она тут идет подспудно постоянно.
Хм. Подспудно, говоришь... учтём.

VD>Ты вот постоянно пыташся доказать, что вопросы производительности являются приговором, и что они куда важнее чистоты дизайна.

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

V>> Это же очевидно, что имеет и еще как. Речь шла о том, что ты сильно заблуждаешься, считая что дотнет легко вытеснит С++ из всех областей (ты приводил то качество стандарта как аргумент, то тот факт что в системных областях С лучше С++, то вот конструкции всякие).

VD>Э... как говорится, стоять Зорька!
VD>Где это я такое утверждал? Где я говорил, что легко, да и вытеснит.
Э... "подспудно" тобой именно это и утверждается на протяжении, чтобы не соврать... лет, эдак, примерно двух.

Про конкретно "все области" мне найти не удалось. Вот, накопал в локальной базе:

Re[8]: С++ и .NET
Автор: VladD2
Дата: 11.10.04

V>И еще — из компьютерных игр шарпу не вытеснить С++.
Гы. Очень даже вытеснить.(выделено мной — ГВ.) Не сразу конечно. Но через несколько лет народ прийдет к пониманию, что писать игры на Шарпе быстрее и удобнее. Примеры уже есть. Я вроде бы уже говорил. Тут Оранж давал ссылку на 3D RTS. Очень неплохо работает. А по архитектуре на порядок делает разные там именитые WarCraft-ы.


VD>Что касается скорого вытеснения, то я думаю, что раньше чем в следующем десятилетии об этом серьезно говорить не прийдется. Но процесс уже идет. Потихоньку, помаленьку... но идет. Комьюнити дотнетных программистов на RSDN-е уже практически равно комьюнити С++-ников. И со временем дотнтеное комьюнити привысит С++-ное.

Не имею в том ни малейших сомнений.

VD>Мне кажется это очевидным, хотя и с этим очень многие поспорят с пеной у рта.

Если я не ошибаюсь, то до недавнего времени в мире 50% программистов программировали на VB, тогда как C++-ников что-то там чуть ли не на порядок меньше. Только вот численность community трудно притянуть к оценке "способностей" средства. Аргумент коллективом, извините... Или как там, про миллион леммингов-то...

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

Ты лучше уж задумайся о том, проявлением чего является желание любой ценой доказать, что C++ is dead или что он должен быть срочно переделан по подобию C#.

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

VD>А мне очень жаль людей не понимающих, что технические аспекты ничто супратив архитектурных. Ну, да надоело повторяться.
Проблемы проявляются в комплексе, а не в отдельных аспектах. Знаешь, как бывает: все Левши, а блоха не прыгает...
... << RSDN@Home 1.1.3 stable >>
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[27]: И опять С++ vs С#
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 25.11.04 16:22
Оценка: 1 (1)
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>А как? У меня, по моей ограниченной осведомленности в C#/.Net, возникает ощущение, что все эти новые контейнеры для реализации этой возможности придется наследовать от какого-то одного и того же интерфейса.


Ну где то так. Причем скорее всего от дженерик интерфейса. Да, в дотнете правильно говорить реализовать интерфейс, а не наследовать.

ПК> Это так? Если да, то как предполагается организовать взаимодействие разных библиотек: ведь они могут добавлять функциональность независимо друг от друга, таким образом, вводя новые, разные интерфейсы...

ПК> Как тогда использовать функциональность, представляемую одной библиотекой, для контейнеров из другой библиотеки?

Возможность указывать в констрейнте инстанцированные параметром интерфейсы дает довольно много возможностей. Плюс стандартные паттерны. Подробно расписывать лень и нет времени.
... << RSDN@Home 1.1.4 beta 3 rev. 235>>
AVK Blog
И опять С++ vs С#
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.11.04 20:18
Оценка: -1
Здравствуйте, vdimas, Вы писали:

V>>>Влад, ты же разбираешься в этом вопросе, а жонглируешь...


VD>>Чем? Чистое сравнение количества конструкций языка. Без каких личбо выводов.


Так все же чем?

VD>>Осталось определить смысл вкладываемый в это понятие и как перевести "это" в количественную составляющую...


V>смысл такой — количество допустимых выражений на единицу языка.


Это очень расплывчатое определение. Да и бессмысленное.

Скорее оно тянет на выразительность языка. Т.е. на то насколько компактно и понятно можно описать некий алгоритм.

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

Так что подобное сравнение тяжело сделать точным и исчислимым. Скорее можно вести речь об субъективном сравнении.

V>есть подход от обратного.

V>берем допустимые цепочки и смотрим, скольким нетерминалам (конечным или промежуточным) удовлетворяет эта цепочка. Чем большим (чем больше неоднозначность), тем мощнее грамматика.

Какая нафиг не однозначность? Зависимость от контекста к неоднозначности не приводит.

В общем, это все бессмысленные рассуждения. Все намного проще. В Шарпе есть очень высокоуровневые конструкции и если не брать в рассчет библиотечный код (любой, даже входящий в стандарт), то выразительность Шарпа будет намного выше С++. Собственно для того язык и проектировался. Из самых ярких примеров... вот, например, реализация итератора на Шарпе:
public IEnumerator<НекоторыйТип> GetEnumerator()
{
    for (int i = 0; i < некотораяКоллекци.Count; i++)
            yield return некотораяКоллекци[i];
}

Для реализации того же самого на С++ прийдется создать внешний класс и кучу кода. Тут же 4 строки кода.

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

А мерить условные вариации просто бессмысленно. Как и использовать каие-то недетерминированные понятия вроде "мощьности".
... << RSDN@Home 1.1.4 beta 3 rev. 207>>

04.12.04 16:29: Ветка выделена из темы Качество стандарт
Автор: Павел Кузнецов
Дата: 13.11.04
— AndrewVK
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[16]: И опять С++ vs С#
От: vdimas Россия  
Дата: 21.11.04 23:59
Оценка: +1
Здравствуйте, VladD2, Вы писали:

VD>В общем, это все бессмысленные рассуждения. Все намного проще. В Шарпе есть очень высокоуровневые конструкции и если не брать в рассчет библиотечный код (любой, даже входящий в стандарт), то выразительность Шарпа будет намного выше С++. Собственно для того язык и проектировался. Из самых ярких примеров... вот, например, реализация итератора на Шарпе:

VD>
VD>public IEnumerator<НекоторыйТип> GetEnumerator()
VD>{
VD>    for (int i = 0; i < некотораяКоллекци.Count; i++)
VD>            yield return некотораяКоллекци[i];
VD>}
VD>


Ты привел неудачный пример. Коллекции, схожии по конструкции с шарповскими вообще записываются однократно на шаблонах, а потом только используются через typedef, например.
В С++ я могу наследоваться от параметра шаблона (или даже зависимого типа):

template<typename my_collection_type>
class CollectionImpl : public collection_base_type {
// ...
IEnumerator<typename collection_base_type::element_type>* GetEnumerator() {
    return new EnumeratorImpl<my_collection_type>(this);
}

template<typename collection_type>
class EnumeratorImpl : public IEnumerator<typename colection_type::element_type> {
public:
      EnumeratorImpl(colection_type* col) : col_(col) { Reset(); }
      void Reset { it_ = col_->begin(); }
      bool MoveNext() { if(it_ != col_->end() && ++it_ != col_->end())  return true; return false; }
      typename colection_type::element_type& Current() { return *it_; }

private:
      typename collection_type::iterator it_;
      collection_type* col_;
}


причем приведенный код глобально однократен, может входить во "фреймворк".

т.е. тебе 4 строчки, мне — ни одной.

приведенный тобой пример — из разряда костылей, у тебя же нет возможностей шаблонов С++.
Re[22]: И опять С++ vs С#
От: vdimas Россия  
Дата: 25.11.04 00:12
Оценка: :)
Здравствуйте, AndrewVK, Вы писали:

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


V>>(уверен, этот исходник меньше аналогичного из донета, и посмотри, что 4/5-х исходника сделаны по copy&paste,


AVK>Звучит как приговор.

Да ладно, все коллекции в дотнете — сплошной copy&paste.

это расплата за частичную специализацию.

смотри, мне надо ввести разные сигнатуры ф-ий:
void func();
void func(Type1);
void func(Type1, Type2);
void func(Type1, Type2, Type3); и т.д.

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


V>>Насчет ремоутинга не спорю, мета-инфрмация она и в африке метаинформация. Как компилируемый вариант я использую CORBA. И мой трафик гораздо меньше твоего (чистые бинарные представления сруктур передаются без метаинформации).


AVK>А с чего ты взял что ремоутинг передает метаинформацию?


смотрел выход форматтеров бинарных в их 3-х режимах.
Re[21]: И опять С++ vs С#
От: VladD2 Российская Империя www.nemerle.org
Дата: 25.11.04 21:56
Оценка: -1
Здравствуйте, vdimas, Вы писали:

Основного утверждения о меньшей выразительности С++ ты опровергнуть так и не смог. Все эти горы кода приводимые в ответ только подтверждают это.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[27]: И опять С++ vs С#
От: VladD2 Российская Империя www.nemerle.org
Дата: 25.11.04 21:56
Оценка: -1
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>А как?


Ручками.

ПК>У меня, по моей ограниченной осведомленности в C#/.Net, возникает ощущение, что все эти новые контейнеры для реализации этой возможности придется наследовать от какого-то одного и того же интерфейса.


Ну, ты сам написал почему. Я бы вот осбудил почему выражая подобные сомения ты до сих пор не изучил обсуждаемый вопрос?

ПК> Это так? Если да, то как предполагается организовать взаимодействие разных библиотек: ведь они могут добавлять функциональность независимо друг от друга, таким образом, вводя новые, разные интерфейсы... Как тогда использовать функциональность, представляемую одной библиотекой, для контейнеров из другой библиотеки?


Прочти вот это: Нововведения в C# 2.0
Автор(ы): Владислав Чистяков (VladD2)
Дата: 24.06.2004
В статье рассказывается о новшествах, которые должны появиться в новой версии языка C#

. Думаю, тебе этого будет более чем достаточно. Если конечно ты не начнешь дальше настраивать себя против всего нового.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[29]: И опять С++ vs С#
От: VladD2 Российская Империя www.nemerle.org
Дата: 25.11.04 21:56
Оценка: +1
Здравствуйте, Курилка, Вы писали:

AVK>>Ну где то так. Причем скорее всего от дженерик интерфейса. Да, в дотнете правильно говорить реализовать интерфейс, а не наследовать.


К>Скромно замечу — вроде бы это далеко не только в .нете интерфейсы реализуются, а не наследуются...


Это фразиологическая софистика. Можно говорить "реализовать", можно говорить "унаследовать интерфейс". Просто одних раздражает одно, других другое. Смысл вроде понятен всем.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[30]: И опять С++ vs С#
От: VladD2 Российская Империя www.nemerle.org
Дата: 25.11.04 21:56
Оценка: +1
Здравствуйте, AndrewVK, Вы писали:

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


Как минимум есть наследование интерфейсов (один можно унаследовать от другого). Реализация обычно говорят, чтобы отличать наследование интерфейсов другими интерфейсами от реализации их в классах. В разговоре же часто говорят наследует интерфейс, и от контекста все становится совершенно понятно.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[32]: И опять С++ vs С#
От: VladD2 Российская Империя www.nemerle.org
Дата: 26.11.04 00:55
Оценка: :)
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Имхо, вы оба правы. Андрей — в том смысле,


А я не говорю, что он не прав. Просто он слишком строго относится к тем кто выражается "неверно", а я как-то не вижу особой разницы.

ПК> что в данном разговоре, касающемся только C#, пожалуй, правильно говорить "реализует", раз уж в спецификации такая терминология.


Дык не все же свою жизнь со спецификации Шарпа начинают?

ПК> И я согласен с тобой, что от того, что кто-нибудь скажет "наследует", особенно если бы это было в разговоре, где речь не только о C#, все все прекрасно поймут


Ну, хоть в чем-то мы с тобой сошлись.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[21]: И опять С++ vs С#
От: vdimas Россия  
Дата: 28.11.04 22:47
Оценка: +1
Здравствуйте, Зверёк Харьковский, Вы писали:

ЗХ>Поправь меня, если я ошибаюсь: все это предназначено для того, чтобы локализовать код итерации по классы в самом классе, а не выносить в отдельный класс итератора, isn't it?


нет, это для того, чтобы пошаговый алгоритм превратить в обычный цикл.

Компилятор создает экземпляр класса-енумератора, добавляет в него как поля твои "локальные" переменные.
Добавляет поле current. Конструкция yield return someValue записывает значение в current и возвращает true как результат MoveNext() итератора. В первый вызов MoveNext() алгоритм идет с начала метода до yield return. В следующие разы — продолжает алгоритм от этого места (их может быть несколько). Выход за предела алгоритма означает возврат false как результат вызова MoveNext() итератора.
Re[32]: И опять С++ vs С#
От: vdimas Россия  
Дата: 28.11.04 23:14
Оценка: +1
Здравствуйте, VladD2, Вы писали:

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


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

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

VD>Посмотри в будующее хотя бы на пару лет. МС уже во всю клепает Авалон, Индигу и ВыньФС. Все они обладают менеджед АПИ и мы ничего не выиграем применением С++. Эти АПИ будут принципияльно предпочтительнее чем старые анменеджед АПИ. Причем не потому что они скомпилированы на более быстром компилыторе, а потому что они более качественно спроектированы, удобны и аппаратно ускорены. Ну, не сможешь ты на С++ и сегодняшнего ВыньАПИ породить код который сравнится по скорости с кодом написанном на ВБ но использующим аппаратную акселерацию Авалона. Принципиально не сможешь! Выигрыш от лучшей оптимизации составит проценты, а от аппаратной акселерации пордки. На, а надежность и простота поставят окончательную точку.


Все это здорово, за исключением одного но...
Что мешает разработать С++ для аппаратного байт-кода?

(С++/CLR — это не то. Он отделяет managed код от обычного. А тут именно с прицелом на тот самый байт код VM.)

--------
Кстати, ввиду характера системы команд VM на мой взгляд на ней должен был бы Forth рулить. Я видел на codeproject одну реализацию, но она откровенно неэффективна. (просто существует и даже как-то работает)
Re[24]: И опять С++ vs С#
От: Шахтер Интернет  
Дата: 30.11.04 01:18
Оценка: :)
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>vdimas,


>> VD>Основного утверждения о меньшей выразительности С++ ты опровергнуть так и не смог. Все эти горы кода приводимые в ответ только подтверждают это.


>> В своих постах ты указал на т.н. "новые" трюки с yield. Я каждый из них однократно выражаю в 10-ти строках примитивного шаблонного кода. <...>


ПК>Кста, вот еще на примерчик "выразительности" наткнулся: http://rsdn.ru/forum/Message.aspx?mid=919926#919926
Автор:
Дата: 27.11.04
Вполне естественно, что язык предоставляет далеко не все возможности, нужные программистам в готовом виде. Вопрос только в том, позволяет ли он легко добавить желаемое.


ПК>В C++ именно такая возможность есть:

ПК>
ПК>void f(T&);
ПК>

ПК>ничего на NULL проверять не надо — компилятор сам разберется.

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

ПК>
ПК>void f(ref<T>);
ПК>

ПК>Ну-ка то же самое, да на C# (чур, препроцессоры не предлагать)

Щаз скажу страшное -- а зачем в C# проверять на нуль? Это делается автоматом средой с генерацией исключения. Причем с трассировкой стека.
Масло маслянное.
... << RSDN@Home 1.1.0 stable >>
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[25]: И опять С++ vs С#
От: Павел Кузнецов  
Дата: 30.11.04 04:45
Оценка: +1
Шахтер,

> ПК>
> ПК>void f(ref<T>);
> ПК>

> ПК>Ну-ка то же самое, да на C# (чур, препроцессоры не предлагать)

> Щаз скажу страшное -- а зачем в C# проверять на нуль? Это делается автоматом средой с генерацией исключения. Причем с трассировкой стека.

> Масло маслянное.

Дык, 1) в отличие от приведенного примера на C++, во время исполнения, никаких подсказок во время компиляции; 2) исключение возникнет во время разыменования, а не там, где этот null возник (Влад даже статью про важность локализации таких вещей написал, "As is...").
Posted via RSDN NNTP Server 1.9 delta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[34]: И опять С++ vs С#
От: vdimas Россия  
Дата: 30.11.04 10:56
Оценка: +1
Здравствуйте, VladD2, Вы писали:

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


V>>Эти постулаты мы и сами знаем.


VD>Видимо фигово, раз постоянно про них забываете.


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


VD>Про порядки — это досужие домыслы. Практика показывает, что максимум в 3 раза.

только что получил разницу в 4 раза
template<typename T>
struct IValue {
    virtual T getValue() =0;
    virtual void setValue(T value) =0;
};

struct IntValueInline {
    int val;
    IntValueInline(int i=0) : val(i) {}

    int getValue() { return val; }
    void setValue(int value) { val = value; }
};


могу весь тест выложить


VD>И то в наихудших условиях.

Тебе как раз наихудшее условие и привели — это когда затраты на выполнения тела метода сопоставимо с затратами на вызов виртуальной ф-ии. Математические вычисления — та самая область.

VD>Ну, а по жизни разница оказывается на проценты.

По жизни никто и не спорит, или ты думаешь на С++ все только inline используют?

VD>А то и наоборот (получается выигрыш).

пример можно?

VD>К тому же весь проигрышь — это всего лишь резальтат недостаточной оптимизации.

Нет, если метод ожидает именно интерфейс в твоем случае, и ты реально подаешь туда различные имплементаторы этого интерфейса, то никакого инлайна в этом конкретном методе не может происходить по принципиальным причинам. Он ОБЯЗАН вызывать виртуальные ф-ии имплементаторов. И он их честно вызывает.

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


VD>Это не так. VC7.x делает подобные оптимизации на ура.

именно указанные не делает. Если метод ожидает объект (не интерфейс), то он часто инлайнит даже виртуальные ф-ии, согласен. Но, если же указан интерфейс и я в коде подаю разные имплементаторы — не инлайнит.

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


Достаточно всего двух разных имплементаторов интерфейса, чтобы тебя не спас никакой просмотр хоть на 100 шагов вперед.

VD>Так что это вопрос времени и денег положенных на оптимизацию.

Нет, это вопрос самой сущности виртуальных ф-ий.

V>>Все это здорово, за исключением одного но...

V>>Что мешает разработать С++ для аппаратного байт-кода?

VD>Что такое "аппаратный байткод"?

Ты там говорил про аппаратную акселерацию нетовских приложений. Я тебя понял именно так. (т.е. аппаратная реализация проца, выполняющего байт-код)

V>>--------

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

VD>MSIL разработан под компиляцию в машинный код. Они никогда не интерпретируется и то, что он основан на стэковой машине (видимо именно об этом ты пытаешся вести речь ) ровным счетом ничего не значит. После компиляции получается обычный машинный код ничем от С++-ного не отличающийся.


Forth никак не обязывает интерпретирующую реализацию. Там есть понятие — компиляция слова. Это означает генерацию двоичной последовательности команд, исполняющей тело слова. А что за последовательность команд — зависит от реализации. Байт-код MSIL идеально подходит для реализации Forth с непосредственной компиляцией слов в этот байт-код.
Re[23]: И опять С++ vs С#
От: vdimas Россия  
Дата: 30.11.04 12:52
Оценка: +1
Здравствуйте, Зверёк Харьковский, Вы писали:

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


V>>Здравствуйте, Зверёк Харьковский, Вы писали:


ЗХ>>>Поправь меня, если я ошибаюсь: все это предназначено для того, чтобы локализовать код итерации по классы в самом классе, а не выносить в отдельный класс итератора, isn't it?


V>>нет, это для того, чтобы пошаговый алгоритм превратить в обычный цикл.


V>>Компилятор создает экземпляр класса-енумератора, добавляет в него как поля твои "локальные" переменные.

V>>Добавляет поле current. Конструкция yield return someValue записывает значение в current и возвращает true как результат MoveNext() итератора. В первый вызов MoveNext() алгоритм идет с начала метода до yield return. В следующие разы — продолжает алгоритм от этого места (их может быть несколько). Выход за предела алгоритма означает возврат false как результат вызова MoveNext() итератора.

ЗХ>угу. а чем это отличается от моей формулировки?


тем, что алгоритм итерации будет развернут принципиально по-другому, чем в случае выноса в отдельный класс.
Т.е. операция рефакторинга — "вынос метода в отдельный класс" тут не аналогия.
Re[35]: И опять С++ vs С#
От: VladD2 Российская Империя www.nemerle.org
Дата: 06.12.04 23:09
Оценка: +1
Здравствуйте, vdimas, Вы писали:


VD>>Про порядки — это досужие домыслы. Практика показывает, что максимум в 3 раза.

V>только что получил разницу в 4 раза
V>
V>template<typename T>
V>struct IValue {
V>    virtual T getValue() =0;
V>    virtual void setValue(T value) =0;
V>};

V>struct IntValueInline {
V>    int val;
V>    IntValueInline(int i=0) : val(i) {}

V>    int getValue() { return val; }
V>    void setValue(int value) { val = value; }
V>};
V>

V>могу весь тест выложить

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

VD>>И то в наихудших условиях.

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

А это довольно большая редкость.

А вот то, что элюзорный выигрыш в скорости сталкивает программистов к плохому ОО-дизайну — это уже стало постоянной практикой. Открой те же паттерны проектирования и почитай, что там пишется. Слова полиморфизм (причем в смысле динамический) и им подобные там на каждом шагу.

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

VD>>Ну, а по жизни разница оказывается на проценты.

V>По жизни никто и не спорит, или ты думаешь на С++ все только inline используют?

По-моему, спорят и постоянно. А про С++ я не думаю. Я на нем 10 лет программировал и прикрасно понимаю кто что использует.

VD>>А то и наоборот (получается выигрыш).

V>пример можно?

Ну, например компилятор C# Моно работает быстрее МС-ного. Хотя МС-ный писан вручную на С++, а Моновский с использованием Yacc-а и на C#.

Но дело тут именно в лучшем проектировании. Так за счет лучшего проектирования самого языка можно достичь куда большего ускорения компиляции. Тот же компилятор С++ обычно значительно медленнее компиялтора C#. Все это потому, что C# специально проектировался так чтобы скорость компиляции не зависила от объема используемого библиотечного кода (путем введения модульного подхода при компиляции).

Вот еще ссылочка где есть тесты производительности портированного с С++ на C# 3D-движка:
Re[40]: Опять С++ vs С#
Автор: VladD2
Дата: 28.11.04

Re[40]: Опять С++ vs С#
Автор: VladD2
Дата: 28.11.04


C# позволяет более чисто и просто проектировать ОО-приложения и библиотеки. Это в свою очередь позволяет больше времени посвятить улучшения дизайна и оптимизации.

Единственная проблема C# на сегодня — это более слабый оптимизатор встроенный в джит или преджит. Но насколько я знаю к 2007-му году эта проблема будет решена путем создания мощьного оптимизированного преджита (а возможно и джита). Кстати, оптимизаторы VC и дотнета будут объеденены. В общем, см. http://research.microsoft.com/phoenix/

VD>>К тому же весь проигрышь — это всего лишь резальтат недостаточной оптимизации.

V>Нет, если метод ожидает именно интерфейс в твоем случае, и ты реально подаешь туда различные имплементаторы этого интерфейса, то никакого инлайна в этом конкретном методе не может происходить по принципиальным причинам. Он ОБЯЗАН вызывать виртуальные ф-ии имплементаторов. И он их честно вызывает.

Ты плохо осветдомлен. В VC (вот точно не помню из VS2005 или уже в VS2002-2003) уже включена опция спекулятивного инлайнинга с устранением виртуальных вызовов. Думаю, что в Фениксе эта тема тоже будет далеко не последней. К тому же на эту тему есть куча научных иследований.
В общем, погугли по словосоченатниям Inlining of Virtual Methods и speculative virtual call Inlining.

Так что появление подобной оптимизации в менеджед-средах исключительно дело времени. Рано или поздно МС или Сан вложат подобающее бабло в проблему оптимизации управляемого кода и данный вопрос изчезнет сам собой.

За-то с точки жрения чистоты дизайна дженерик интерфейсы и дженерик-делегаты несомненно на высоте. Дизайнеру примедяюще эти парадигмы будет намного проще создать стройный и легко расширяемый дизайн. При этом там где это возможно оптимизирующие компиляторы (а может и статические оптимизаторы кода на базе продуктов вроде #R) устранят виртуальность и нивилируют временные затраты. При этом от программиста и дизайнера не потребуется никаких умственных или физических затрат. Ну, а там где без виртуального вызова не обойтись... что же, значит это насущьные действительно требования дизайна и скорее всего без них невозможно будет обойтись и в С++... по крайней мере без потерь в качестве дизайна приложения/библиотеки.

V>именно указанные не делает. Если метод ожидает объект (не интерфейс), то он часто инлайнит даже виртуальные ф-ии, согласен. Но, если же указан интерфейс и я в коде подаю разные имплементаторы — не инлайнит.


Уверяю тебя ты заблуждаешся. Почитай МСДН... Погугли... Сслок я вроде привел достаточно.

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


Опять таки. Работ по спекулятивному инлайнингу в Интернете хоть пруд пруди. Там хорошо описаны методы предсказания того когда можно, а когда нет производить устранение виртуальности вызова. Почитай...

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

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

В пользу преувеличенности значения этого вопроса говрят те же примеры 3D-игр созданных на C# 1.х. C# 1.х обладал куда большим количеством мест способных снизить производительность приложений. Но тем не менее имеющейся производительности более чем достаточно для 3D-игр.

VD>>Так что это вопрос времени и денег положенных на оптимизацию.

V>Нет, это вопрос самой сущности виртуальных ф-ий.

Похоже — это вопрос информации. Спорить не хочу и не буду. Дума, что аргументов более чем достаточно. Если они тебя не убедили, то все равно дальнейший разговор бессмысленнен. Подождем 2007/2008-го года. К этому времени все должно встать на свои метса самостоятельно.

Лично я практически уверен, что разница в скорости менеджед-кода и С++-кода станет столь ничтожной, что говорить о чьём бы то нибыло приемуществе будет смешно. А вот с точки зрения ОО-дизайна интерфейсы и делегаты выгоднее уже сейчас (а где их применять совершенно по барабану).

VD>>Что такое "аппаратный байткод"?

V>Ты там говорил про аппаратную акселерацию нетовских приложений. Я тебя понял именно так. (т.е. аппаратная реализация проца, выполняющего байт-код)

Где, там? Ссылку можно? В общем, ты меня явно не правильно понял.

VD>>MSIL разработан под компиляцию в машинный код. Они никогда не интерпретируется и то, что он основан на стэковой машине (видимо именно об этом ты пытаешся вести речь ) ровным счетом ничего не значит. После компиляции получается обычный машинный код ничем от С++-ного не отличающийся.


V>Forth никак не обязывает интерпретирующую реализацию. Там есть понятие — компиляция слова. Это означает генерацию двоичной последовательности команд, исполняющей тело слова. А что за последовательность команд — зависит от реализации. Байт-код MSIL идеально подходит для реализации Forth с непосредственной компиляцией слов в этот байт-код.


Для генерации МСИЛ-а есть высокоуровневый АПИ, так что совершенно пофигу с для какого ЯП делать эту самую генерацию. В общем, я так и не понял причем тут Форт...
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[28]: И опять С++ vs С#
От: Павел Кузнецов  
Дата: 07.12.04 01:17
Оценка: +1
VladD2,

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


Похоже, ты упорно не понимаешь, что не все видят именно архитектурные аспекты одинаково, и не все согласны с твоими оценками именно архитектурных отличий C# от C++ как безусловных преимуществ.
Posted via RSDN NNTP Server 1.9 delta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[27]: И опять С++ vs С#
От: VladD2 Российская Империя www.nemerle.org
Дата: 07.12.04 23:05
Оценка: +1
Здравствуйте, WolfHound, Вы писали:

VD>>Ты уверен что полностью понимашь, что такое итераторы C# 2.0?

WH>Ты меня с Губановым не путаешь?
WH>Итераторами C# можно пробежатся от начала и до конца контейнера (не обязательно контейнера) при этом только читая значения из него. Единственное чем он отличяется от инпут итератора это тем что можно вернутся в начало последовательности.

И все же похоже ты действительно не очень понимашь о чем идет речь. Речь идет не об энумераторах, а об итераторах — новой концепци реализации тех самх энумераторов. см. http://gzip.rsdn.ru/article/csharp/newincsharp.xml#EJA
Автор(ы): Владислав Чистяков (VladD2)
Дата: 24.06.2004
В статье рассказывается о новшествах, которые должны появиться в новой версии языка C#

раздел "Итераторы".

WH>Тоже относится и к C#. Вот например так я вешаю курсор песочные часы на форму.

WH>
WH>            using(WaitCursor waitCursor = owner.WaitCursor())
WH>            {
WH>            //тут гора тормозного кода который может кинуть исключение итп
WH>            }
WH>

WH>Ладно что хоть с try/finnaly возится не приходится... А все почему? А по тому что в C# нет автоматических деструкторов. И их приходится эмулировать.

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

А твою проблему можно решить намного проще и элегантрее. Например, так:
partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    void UseWaitCursor()
    {
        if (Form.ActiveForm != null)
        {
            Form currForm = Form.ActiveForm;
            currForm.Cursor = Cursors.WaitCursor;
            Application.Idle += delegate(object sender, System.EventArgs e)
            {
                currForm.Cursor = Cursors.Default;
            };
        }
    }

    private void button1_Click(object sender, EventArgs e)
    {
        // Test!
        UseWaitCursor();
        for (int i = 0; i < int.MaxValue; i++)
        {
        }
    }
}


VD>>Так делегаты в общем-то можно заменить объемистыми классами Буста или Локи,

WH>И надо сказать очень не плохо эмулируются...

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

WH>Ну этот вопрос давно научились решать. Прекомпилид хидеры, инкреди билд(когда за компиляцию принимаются 20 компов...)


Это сказка для не посвященных. Я как бы сам плавал с 25-минутной компиляцией проекта со всем инкриментами и прекомпайлами.

WH>Ну жертв эффективности я чегото не заметил , а вот совместимость это да... Это они погорячились.


Проблемы с вызовом деструкторов у суперклассов не имеющих виртуального деструктор тебе знакомы? А размер int-а? Все это выбор скорости в ущерб стройности дизайна языка и простоте его использования. Примеров таких море.

VD>>В итоге получился довольно уродливый монстр который не хотят (а возможно боятся) менять сами его создатели.

WH>Это не реально. Изменить этого монстра это значит поломать гигабайты кода... Именно по этому его меняют так окуратно и медленно.

Это реально если этим заниматься. Вот C++/CLI содают же. И "гигабайты" вроде не страдают.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[17]: И опять С++ vs С#
От: VladD2 Российская Империя www.nemerle.org
Дата: 22.11.04 05:37
Оценка:
Здравствуйте, vdimas, Вы писали:

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

V>В С++ я могу наследоваться от параметра шаблона (или даже зависимого типа):
...
ОК. Изобрази на нем подобный код:
class Test
{
    public IEnumerator<int> GetEven()
    {
        for (int i = 2;; i += 2)
            yield return i;
    }
    
    public IEnumerator<int> GetOdd()
    {
        for (int i = 1;; i += 2)
            yield return i;
    }
}


А потом, ты видимо пропустил вот эти слова:

и если не брать в рассчет библиотечный код (любой, даже входящий в стандарт),

Так что опять таки мои слова верны по отношению к языку. Ну, а в библиотеках можно сделать все что зочешь. Хоть с "костылями", хоть без "костылей".
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[18]: И опять С++ vs С#
От: vdimas Россия  
Дата: 22.11.04 11:41
Оценка:
Здравствуйте, VladD2, Вы писали:

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


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

V>>В С++ я могу наследоваться от параметра шаблона (или даже зависимого типа):
VD>...
VD>
VD>ОК. Изобрази на нем подобный код:
VD>class Test
VD>{
VD>    public IEnumerator<int> GetEven()
VD>    {
VD>        for (int i = 2;; i += 2)
VD>            yield return i;
VD>    }
    
VD>    public IEnumerator<int> GetOdd()
VD>    {
VD>        for (int i = 1;; i += 2)
VD>            yield return i;
VD>    }
VD>}
VD>


схематично:
template<typename T, T begin, T step, class BaseT = System::Object>
class ValueEnumerator : public BaseT, public IEnumerator<T> {
// тут понятно что, Reset, MoveNext, Current
}

class Test
{
    public:
    IEnumerator<int>* GetEven()
    {
        return new ValueEnumerator<int, 2, 2>;
    }
    
    IEnumerator<int>* GetOdd()
    {
        return new ValueEnumerator<int, 1, 2>;
    }
}


(обрати внимание на BaseT, я могу подмешать имплементацию интерфейса к любому классу)

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

VD>А потом, ты видимо пропустил вот эти слова:

VD>

и если не брать в рассчет библиотечный код (любой, даже входящий в стандарт),


блин, шаблонный код на С++ я бы не назвал библиотечным в том смысле, в каком он подразумевается в C#. Шаблоны — это не только конкретные обощенные реализации классов, это еще обощенные алгоритмы, методики и трюки. Они служат как инструмент для порождения своих реализаций/имплементаций. В то время, как в C# это нихрена не инструмент, а именно только обощенные реализации классов. Разумеется, заколебешься в библиотеку запихать вообще все реализации прикладных классов, даже и обощенные. Но зато весьма нетрудно запихать в библиотеку разнообразный инструментарий для офигенного облегчения их реализации. Прочуствуй разницу.

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


Да ты не видишь очевидных вещей. Давай пойдем от обратного. Что измениться в C# 2.0 если убрать оттуда описанную конструкцию yield? Да ничего такого, собственно, за исключением того, что тебе придется каждый раз ручками переопределять 4 ф-ии, ибо в C# нереально обобщить имплементацию интерфейса. 4 ф-ии каждый раз это много? Вроде нет. Но когда речь касается настолько частоупотребимого случая, то поневоле задумаешься о "костыле".

Ну с какого перепугу, по-твоему, усложнять язык дополниельными (не императивными!!!) конструкциями? Да потому что выхода другого нет, это наименьшее зло.

-------
Тут кстати, Джава 1.5 вышла, надо бы посмотреть — возможна ли ТАМ обощенная реализация интерфейсов. Если вдруго возможна, то... в общем Microsoft ее так уж запросто не скинет.
Re[19]: И опять С++ vs С#
От: VladD2 Российская Империя www.nemerle.org
Дата: 23.11.04 18:31
Оценка:
Здравствуйте, vdimas, Вы писали:

VD>>
VD>>ОК. Изобрази на нем подобный код:
VD>>class Test
VD>>{
VD>>    public IEnumerator<int> GetEven()
VD>>    {
VD>>        for (int i = 2;; i += 2)
VD>>            yield return i;
VD>>    }
    
VD>>    public IEnumerator<int> GetOdd()
VD>>    {
VD>>        for (int i = 1;; i += 2)
VD>>            yield return i;
VD>>    }
VD>>}
VD>>


V>схематично:

V>
V>template<typename T, T begin, T step, class BaseT = System::Object>
V>class ValueEnumerator : public BaseT, public IEnumerator<T> {
V>// тут понятно что, Reset, MoveNext, Current
V>}

V>class Test
V>{
V>    public:
V>    IEnumerator<int>* GetEven()
V>    {
V>        return new ValueEnumerator<int, 2, 2>;
V>    }
    
V>    IEnumerator<int>* GetOdd()
V>    {
V>        return new ValueEnumerator<int, 1, 2>;
V>    }
V>}
V>


V>(обрати внимание на BaseT, я могу подмешать имплементацию интерфейса к любому классу)


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

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

V>если упомянутая задача неоднократная, то мне все-равно меньше чем тебе париться


Все равно больше те хотел сказать. Представь себе, что задачи схожи только тем, что их все можно представить итератором, а все алгоритмы у них разные и запутанные. Вот пример из реальной жизни. Создавая код для R#-а я заметил, что у меня получается дублирование (захотелось копи-пэстнутся ). Проанализировав ситуацию я понял, что мне нужно создать два разных прохода по одному и тому же алгоритму. Сначала я выделил алгоритм прохода в отдельную функцию, а действие определил делегатом. Но потом почесал репу переписал код с использованием итераторов. Получилось следующее:
        // Код итератора
        IEnumerable<Type> GetMetaRuleTypes(List<string> metaAssemblys)
        {
            foreach (string path in metaAssemblys)
            {
                Assembly assembly;
                try
                {
                    assembly = Assembly.LoadFrom(path);
                }
                catch (Exception ex)
                {
                    _result.Errors.Add(new CompilerError(
                        "", 0, 0, "",
                        "Can't load external meta assembly: "
                        + ex.Message));
                    continue;
                }

                Type[] types = assembly.GetTypes();

                // Отбираем типы реализующие интрефейс IMetaRule и создаем 
                // их экземлпяры, которые помещаем в массив.
                foreach (Type type in types)
                    if (type.GetInterface("IMetaRule") != null)
                        yield return type;
            }
        }
        
    ...
    // Первое использование
    private void MakeRuleCallCodeForMetaAssembly(
    AstNodeCollection compUnits,
    RMemberMethodImpl callRuleTypeMetaRule,
    RTypeMemberCollection members,
    RSwitchSection switchInCallRule,
    RSwitchSection caseInCallRules,
    RSwitchSectionCollection switchBodyInCallRules,
    List<string> metaAssemblys)
{
    foreach (Type type in GetMetaRuleTypes(metaAssemblys))
    {
        RMemberMethodImpl methodClone = MakeRuleInitCode(

...
    // где-то дальше... второе использование...
                // Загружаем классы из мета-сборок.
            foreach (Type type in GetMetaRuleTypes(metaAsmPaths))
            {
                _metaRules.Add(Utilits.GetFullTypeName(type),
                    (IMetaRule)Activator.CreateInstance(type));
            }


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

Так что подобная ишка очень полезна и никакими шаблонами полноценно не заменяется. Ее суть не в уменьшеии кода, а в том, что оно практически безболезнно позволяет превратить сложный запутанный алгоритм в итеративный. yield return — это средство очень просто развернуть в итерацию довольно сложные, запутанные и тесно связанные алгоритмы.

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

yield return же напротив настолько прост, что его использование на практике более чем реально.

VD>>А потом, ты видимо пропустил вот эти слова:

VD>>

и если не брать в рассчет библиотечный код (любой, даже входящий в стандарт),


V>блин, шаблонный код на С++ я бы не назвал библиотечным в том смысле, в каком он подразумевается в C#.


А какй смысл подрузумевается в C#? Я как-то не менял для себя смысла этих слов при переходе на C#.

V> Шаблоны — это не только конкретные обощенные реализации классов, это еще обощенные алгоритмы, методики и трюки.


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

Ну, и как я уже говорил выше, остается только одна область где шаблоны "руля" — это метапрограммироване. Причем так как эти цели достигаются путем использования побочных эффектов компиляторов пользоваться ими не удобно, они не полнофункциональны и могут приводить к проблемам (вроде разростания кода или не работы на других компиляторах). Отсуствие подобных средств в Шарпе действительно удручает. Вот тут то и вступает в игру R#
Автор(ы): Чистяков Влад (VladD2)
Дата: 28.01.2004
. Погоди немного и С++ будет отдыхать по этому параметру.

V> Они служат как инструмент для порождения своих реализаций/имплементаций.


Как костыль они служат.

V> В то время, как в C# это нихрена не инструмент, а именно только обощенные реализации классов.


Именно это и было исходным предназначением шаблонов. И именно это было нужно в C#.

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


Ты забыл что эти библиотеки написаны на C#. И что казалось бы их можно написать на С++. Но на С++ их никто так и не написал. Так что хватит говорить, что весь кайф дотнета в библиотеках. Весь кайф дотнета в нем самом. Все его части дают комулятивный эффект. Без одного невозможно дугое. Библиотеки такого размера просто нельзя написать на С++. Они просто развалятся под количеством багов, немодульностью и т.п. Что до Бустов, то — это во многом библиотека заплатка.

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


V>Да ты не видишь очевидных вещей.


Я то какраз все вижу. А вот ты бошся увидить очевидное.

V> Давай пойдем от обратного.


Т.е. на прямую не получилось?

V> Что измениться в C# 2.0 если убрать оттуда описанную конструкцию yield? Да ничего такого, собственно,


Он станет менее удобным. И вообще, убрав почти любую фичу из Шарпа язык очень многое теряет. А вот из С++ можно удалять лопатой и мало кто заметит. Я нипример, никогда в жизни не пользовался вложенными классами. Да и частичной специализацией шаблонов воспользовался один раз в жизни.

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


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

yield — это возможность необычайно легко абстрагировать любой алгоритм до банального списока. Ты просто смотришь не стой калакольни.

V>4 ф-ии каждый раз это много?


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

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


По больше бы таких костылей как yield!

V>Ну с какого перепугу, по-твоему, усложнять язык дополниельными (не императивными!!!) конструкциями?


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

V> Да потому что выхода другого нет, это наименьшее зло.


Это тебе так хочется считать. А все с точностью на оборот.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[21]: И опять С++ vs С#
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 24.11.04 14:12
Оценка:
Здравствуйте, vdimas, Вы писали:

V>(уверен, этот исходник меньше аналогичного из донета, и посмотри, что 4/5-х исходника сделаны по copy&paste,


Звучит как приговор.

V>Насчет ремоутинга не спорю, мета-инфрмация она и в африке метаинформация. Как компилируемый вариант я использую CORBA. И мой трафик гораздо меньше твоего (чистые бинарные представления сруктур передаются без метаинформации).


А с чего ты взял что ремоутинг передает метаинформацию?
... << RSDN@Home 1.1.4 beta 3 rev. 235>>
AVK Blog
Re[23]: И опять С++ vs С#
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 25.11.04 10:05
Оценка:
Здравствуйте, vdimas, Вы писали:

AVK>>Звучит как приговор.

V>Да ладно, все коллекции в дотнете — сплошной copy&paste.

Для этого в 2.0 как раз и добавили дженерики, кои эту проблему решают превосходно.

AVK>>А с чего ты взял что ремоутинг передает метаинформацию?


V>смотрел выход форматтеров бинарных в их 3-х режимах.


И что ты там кроме идентификаторов типов увидел?
... << RSDN@Home 1.1.4 beta 3 rev. 235>>
AVK Blog
Re[25]: И опять С++ vs С#
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 25.11.04 15:19
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Допустим, надо сделать generic контейнер с произвольным доступом, позволяющий эффективно вставлять элементы как в начало, так и в конец. Сделать такой контейнер — в общем-то не большая проблема: для этого нужно хранить элементы блоками. Но вот можно ли сделать в C# + .Net без copy-paste, с сохранением статической типизации, и не реализуя эти операции заново для разных контейнеров, чтобы данный контейнер можно было сортировать, искать в нем элементы последовательным поиском, бинарным поиском, искать в нем подпоследовательность, как с начала, так и с конца и т.п.?


Можно. Предвосхищая твой вопрос — нет, я не пробовал и пробовать не буду, поскольку у меня нет такого количества свободного времени.
... << RSDN@Home 1.1.4 beta 3 rev. 235>>
AVK Blog
Re[26]: И опять С++ vs С#
От: Павел Кузнецов  
Дата: 25.11.04 15:58
Оценка:
AndrewVK,

> ПК> Допустим, надо сделать generic контейнер с произвольным доступом, позволяющий эффективно вставлять элементы как в начало, так и в конец. Сделать такой контейнер — в общем-то не большая проблема: для этого нужно хранить элементы блоками. Но вот можно ли сделать в C# + .Net без copy-paste, с сохранением статической типизации, и не реализуя эти операции заново для разных контейнеров, чтобы данный контейнер можно было сортировать, искать в нем элементы последовательным поиском, бинарным поиском, искать в нем подпоследовательность, как с начала, так и с конца и т.п.?


> Можно. Предвосхищая твой вопрос — нет, я не пробовал и пробовать не буду, поскольку у меня нет такого количества свободного времени.


А как? У меня, по моей ограниченной осведомленности в C#/.Net, возникает ощущение, что все эти новые контейнеры для реализации этой возможности придется наследовать от какого-то одного и того же интерфейса. Это так? Если да, то как предполагается организовать взаимодействие разных библиотек: ведь они могут добавлять функциональность независимо друг от друга, таким образом, вводя новые, разные интерфейсы... Как тогда использовать функциональность, представляемую одной библиотекой, для контейнеров из другой библиотеки?
Posted via RSDN NNTP Server 1.9 gamma
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[28]: И опять С++ vs С#
От: Курилка Россия http://kirya.narod.ru/
Дата: 25.11.04 16:25
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, Павел Кузнецов, Вы писали:


ПК>>А как? У меня, по моей ограниченной осведомленности в C#/.Net, возникает ощущение, что все эти новые контейнеры для реализации этой возможности придется наследовать от какого-то одного и того же интерфейса.


AVK>Ну где то так. Причем скорее всего от дженерик интерфейса. Да, в дотнете правильно говорить реализовать интерфейс, а не наследовать.


Скромно замечу — вроде бы это далеко не только в .нете интерфейсы реализуются, а не наследуются...
Re[29]: И опять С++ vs С#
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 25.11.04 16:38
Оценка:
Здравствуйте, Курилка, Вы писали:

К>Скромно замечу — вроде бы это далеко не только в .нете интерфейсы реализуются, а не наследуются...


Возможно. Просто в С++ интерфейсов как сущностей нет и вместо них используют абстрактные классы, поэтому там говорить наследоваться от интерфейсов с практической точки корректно. А вот в дотнете везде в спецификации употребляется слово realize, что, имхо, является достаточным основанием чтобы считать этот термин единственно правильным..
... << RSDN@Home 1.1.4 beta 3 rev. 235>>
AVK Blog
Re[25]: И опять С++ vs С#
От: VladD2 Российская Империя www.nemerle.org
Дата: 25.11.04 21:56
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>AndrewVK,


>> V> Да ладно, все коллекции в дотнете — сплошной copy&paste.


И эти: System.Collections.Generic?

>> Для этого в 2.0 как раз и добавили дженерики, кои эту проблему решают превосходно.


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


Вроде этой Создание эффективной реализации сортированного списка с использованием generics
Автор(ы): Сергей Смирнов (Serginio1)
Дата: 14.08.2004
Пример реализации двухуровневого массива с помощью нового средства С# — generics. Сравнение производительности различных реализаций сортированных списков.
?

ПК> Сделать такой контейнер — в общем-то не большая проблема: для этого нужно хранить элементы блоками. Но вот можно ли сделать в C# + .Net без copy-paste, с сохранением статической типизации, и не реализуя эти операции заново для разных контейнеров, чтобы данный контейнер можно было сортировать, искать в нем элементы последовательным поиском, бинарным поиском, искать в нем подпоследовательность, как с начала, так и с конца и т.п.?


Несомненно.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[31]: И опять С++ vs С#
От: Павел Кузнецов  
Дата: 25.11.04 23:20
Оценка:
VladD2,

> AVK> в дотнете везде в спецификации употребляется слово realize, что, имхо, является достаточным основанием чтобы считать этот термин единственно правильным..


> В разговоре же часто говорят наследует интерфейс, и от контекста все становится совершенно понятно.


Имхо, вы оба правы. Андрей — в том смысле, что в данном разговоре, касающемся только C#, пожалуй, правильно говорить "реализует", раз уж в спецификации такая терминология. И я согласен с тобой, что от того, что кто-нибудь скажет "наследует", особенно если бы это было в разговоре, где речь не только о C#, все все прекрасно поймут
Posted via RSDN NNTP Server 1.9 delta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[28]: И опять С++ vs С#
От: Павел Кузнецов  
Дата: 25.11.04 23:32
Оценка:
VladD2,

> ПК>У меня, по моей ограниченной осведомленности в C#/.Net, возникает ощущение, что все эти новые контейнеры для реализации этой возможности придется наследовать от какого-то одного и того же интерфейса.


> Ну, ты сам написал почему. Я бы вот осбудил почему выражая подобные сомения ты до сих пор не изучил обсуждаемый вопрос?


То есть, можно и не наследуя контейнеры от общих интерфейсов? Интересно, как, если без указания интерфейса, реализуемого параметром generic класса, у него доступны только методы object?

> ПК> Это так? Если да, то как предполагается организовать взаимодействие разных библиотек: ведь они могут добавлять функциональность независимо друг от друга, таким образом, вводя новые, разные интерфейсы... Как тогда использовать функциональность, представляемую одной библиотекой, для контейнеров из другой библиотеки?


> Прочти вот это: Нововведения в C# 2.0
Автор(ы): Владислав Чистяков (VladD2)
Дата: 24.06.2004
В статье рассказывается о новшествах, которые должны появиться в новой версии языка C#

. Думаю, тебе этого будет более чем достаточно. Если конечно ты не начнешь дальше настраивать себя против всего нового.


Я читал и новую спецификацию, и соответствующие статьи. Пока способа организовать библиотеку алгоритмов, не требуя от контейнеров реализовывать одни и те же интерфейсы, не нашел по причине требования задавать constraints. Почему бы тебе, если ты такой способ известен, просто о нем не сказать?
Posted via RSDN NNTP Server 1.9 delta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[26]: И опять С++ vs С#
От: Павел Кузнецов  
Дата: 25.11.04 23:41
Оценка:
VladD2,

>>> Для этого в 2.0 как раз и добавили дженерики, кои эту проблему решают превосходно.


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


> Вроде этой Создание эффективной реализации сортированного списка с использованием generics
Автор(ы): Сергей Смирнов (Serginio1)
Дата: 14.08.2004
Пример реализации двухуровневого массива с помощью нового средства С# — generics. Сравнение производительности различных реализаций сортированных списков.
?


Да, приблизительно, но в данной статье нарушено условие ниже:

> ПК> Сделать такой контейнер — в общем-то не большая проблема: для этого нужно хранить элементы блоками. Но вот можно ли сделать в C# + .Net без copy-paste, с сохранением статической типизации, и не реализуя эти операции заново для разных контейнеров, чтобы данный контейнер можно было сортировать, искать в нем элементы последовательным поиском, бинарным поиском, искать в нем подпоследовательность, как с начала, так и с конца и т.п.?


> Несомненно.


Выделенное условие нарушено. В частности, в статье бинарный поиск реализуется "ручками".
Posted via RSDN NNTP Server 1.9 delta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[29]: И опять С++ vs С#
От: VladD2 Российская Империя www.nemerle.org
Дата: 26.11.04 00:55
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>То есть, можно и не наследуя контейнеры от общих интерфейсов?


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

Объясняю. Это не С++!

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

Например, абстрагирование бинарного поиска:
using System;
using System.Collections.Generic;

class Program
{
    // Generic-реализация BinarySearch абстрагированная с помощью интерфейса.
    public static int BinarySearchItf<T>(IList<T> list, int lo, int hi, T value, IComparer<T> comparer)
    {
        while (lo <= hi)
        {
            int i = (lo + hi) >> 1;
            int cmpResult = comparer.Compare(list[i], value);
            if (cmpResult == 0)
                return i;
            else if (cmpResult < 0)
                lo = i + 1;
            else
                hi = i - 1;
        }

        return ~lo;
    }

    public static int BinarySearchItf<T>(IList<T> list, T value, IComparer<T> comparer)
    {
        return BinarySearchItf<T>(list, 0, list.Count - 1, value, comparer);
    }


    // Generic-реализация BinarySearch абстрагированная с помощью делегата.
    public delegate int CompareFunctor<T>(T x, T y);

    public static int BinarySearchDel<T>(IList<T> list, int lo, int hi, T value, CompareFunctor<T> compare)
    {
        while (lo <= hi)
        {
            int i = (lo + hi) >> 1;
            int cmpResult = compare(list[i], value);
            if (cmpResult == 0)
                return i;
            else if (cmpResult < 0)
                lo = i + 1;
            else
                hi = i - 1;
        }

        return ~lo;
    }

    public static int BinarySearchDel<T>(IList<T> list, T value, CompareFunctor<T> compare)
    {
        return BinarySearchDel<T>(list, 0, list.Count - 1, value, compare);
    }

    static void Main(string[] args)
    {
        // Массивы всех типов реализуют IList<T>
        int[] array = new int[] { 2, 4, 7, 8, 10, 20, 22, 23, 24, 26 };

        // Указание спецификации (<int>) нужно чтобы компилятор понял, что int[] нужно привести к IList<int>
        int resItf1 = BinarySearchItf<int>(array, 9, Comparer<int>.Default); // применение реализации компоратора по умолчанию.
        int resItf2 = BinarySearchItf<int>(array, 9, new MyComparer());      // применение "ручной" реализации компоратора.
        int resDel  = BinarySearchDel<int>(array, 9, delegate(int x, int y) { return x - y; }); // применение анонимного метода.

        Console.WriteLine("resItf1 = {0} (~resItf1 = {1})", resItf1, ~resItf1);
        Console.WriteLine("resItf2 = {0} (~resItf2 = {1})", resItf2, ~resItf2);
        Console.WriteLine("resDel  = {0} (~resDel  = {1})", resDel, ~resDel);
    }

    // Реализация дженерик-интерфейса для конкретного типа (int)
    class MyComparer : IComparer<int>
    {
        public int Compare(int x, int y) { return x - y; }
        public bool Equals(int x, int y) { return x == y; }
        public int GetHashCode(int obj)  { return obj; }
    }
}


ПК> Интересно, как, если без указания интерфейса, реализуемого параметром generic класса, у него доступны только методы object?


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

>> Прочти вот это: Нововведения в C# 2.0
Автор(ы): Владислав Чистяков (VladD2)
Дата: 24.06.2004
В статье рассказывается о новшествах, которые должны появиться в новой версии языка C#

. Думаю, тебе этого будет более чем достаточно. Если конечно ты не начнешь дальше настраивать себя против всего нового.


ПК>Я читал и новую спецификацию, и соответствующие статьи. Пока способа организовать библиотеку алгоритмов, не требуя от контейнеров реализовывать одни и те же интерфейсы, не нашел по причине требования задавать constraints. Почему бы тебе, если ты такой способ известен, просто о нем не сказать?


Если бы ты прочел не "соответствующие статьи", а конкретно эту, то и вопроса не возникло бы. Ну, да выше я привел настолько простое описание насколько сомг. Если и это не понятно, то я даже и не знаю, что и как объяснять. Тут уже стереотипы ломать нужно.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[27]: И опять С++ vs С#
От: VladD2 Российская Империя www.nemerle.org
Дата: 26.11.04 01:01
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Да, приблизительно, но в данной статье нарушено условие ниже:


>> ПК> Сделать такой контейнер — в общем-то не большая проблема: для этого нужно хранить элементы блоками. Но вот можно ли сделать в C# + .Net без copy-paste, с сохранением статической типизации, и не реализуя эти операции заново для разных контейнеров, чтобы данный контейнер можно было сортировать, искать в нем элементы последовательным поиском, бинарным поиском, искать в нем подпоследовательность, как с начала, так и с конца и т.п.?


>> Несомненно.


ПК>Выделенное условие нарушено. В частности, в статье бинарный поиск реализуется "ручками".


Я не знаю, что ты там углядел, но ответ для себя (я надеюсь) ты найдешь вот тут: Re[29]: Качество стандарт
Автор: VladD2
Дата: 26.11.04
.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[31]: И опять С++ vs С#
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 26.11.04 11:12
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Как минимум есть наследование интерфейсов (один можно унаследовать от другого).


Есть.

VD> В разговоре же часто говорят наследует интерфейс, и от контекста все становится совершенно понятно.


Тем не менее все равно неверно.
... << RSDN@Home 1.1.4 beta 3 rev. 235>>
AVK Blog
Re[32]: И опять С++ vs С#
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.11.04 02:49
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Тем не менее все равно неверно.


Это если очень узко подходить. Реально наследование интерфейсов ни чем не худший термин чем их реализация. Просто Шарп навязывает свою терминалогию.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[31]: И опять С++ vs С#
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.11.04 02:49
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

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


ПК>Дык, он и раньше тем же самым был


Раньше было неверное утверждение.

>> Объясняю. Это не С++! В дотнете ввели понятие дженерик-интерфейса и дженерик-делегата. Все что нужно абстрагировать выражается в их терминах. <...>


ПК>В таких пределах я это все знаю.


Тогда в чем вопрос?

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


Не работай.

ПК>Например, всякая математика.


Не вижу разницы.

ПК> Для простоты возьмем алгоритм решения систем линейных уравнений.


Для простоты я бы не брал.

ПК> В C++ его можно написать в обобщенном виде, так что он будет работать с любыми матрицами любых чисел. От матриц достаточно операции [i][j],


Это не проблема. Задай Xxx<T>(T[,]...)...

ПК> от чисел — обычных для арифметики операций.


Тоже не проблема. Опиши в виде делегата или интерфейса.

ПК> В том числе программист может подставить типы, представляющие числа большей точности.


Пофигу.

ПК> Очевидно, если числа будут наследоваться от интерфейсов,


Это не требуется.

ПК> то работа с ними будет для вычислений слишком медленной.


Это проблемы оптимизации. VC уже без проблем устраняет виртуальные вызовы в простых случаях. Пройдет некоторое время и тоже самое появится везде. Технологие то наработаны. Да и в реальной жизни чаще применяются алгоритмы на которые пара виртуальных вызовов серьезного влияния оказать не может.

ПК>Кроме того, если не ошибаюсь, в C# "эффективными" типами являются структуры, которые наследовать нельзя.


Ошибашся. Такого понятия нет. Да и наследование не требуется. Включай воображение.

ПК>Можно ли в C# сделать подобные обобщенные алгоритмы, которые можно будет использовать повторно, не требующие наследования от интерфейсов?


Можно. Я тебе кажется уже показал обобшенный бинарный поиск. Поробуй внимательно посмотреть код.

ПК>Или же там будет происходить какая-то "магия" все оптимизирующая до скорости встроенных типов даже при работе через интерфейсы? Что-то сложно верится...


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

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

>>Тут уже стереотипы ломать нужно.


ПК>Это-то все понятно. Непонятно как решить, используя возможности generics, приведенные задачи при условии, что через интерфейс работать нельзя...


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

Если не говорить о производительности, то проблем у дженериков нет.

Если же начать говорить о производительности, то нужно учитывать множество факторов. Главное для тех кто проектирует Шарп и дотнет — концептуальная чистота. И тут я очень понимаю почему они не выбирают "простых путие" избраных в С++. Надежность, компонентность, простота все это стоит даже того чтобы пожетвовать 20 процентами производительности. И если учесть, что потенциально все проблемы производительности можно решить средствами оптимизации, то становится понятно что их подход более дальновидный.

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

Посмотри в будующее хотя бы на пару лет. МС уже во всю клепает Авалон, Индигу и ВыньФС. Все они обладают менеджед АПИ и мы ничего не выиграем применением С++. Эти АПИ будут принципияльно предпочтительнее чем старые анменеджед АПИ. Причем не потому что они скомпилированы на более быстром компилыторе, а потому что они более качественно спроектированы, удобны и аппаратно ускорены. Ну, не сможешь ты на С++ и сегодняшнего ВыньАПИ породить код который сравнится по скорости с кодом написанном на ВБ но использующим аппаратную акселерацию Авалона. Принципиально не сможешь! Выигрыш от лучшей оптимизации составит проценты, а от аппаратной акселерации пордки. На, а надежность и простота поставят окончательную точку.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[18]: И опять С++ vs С#
От: Зверёк Харьковский  
Дата: 28.11.04 18:04
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>
VD>ОК. Изобрази на нем подобный код:
VD>class Test
VD>{
VD>    public IEnumerator<int> GetEven()
VD>    {
VD>        for (int i = 2;; i += 2)
VD>            yield return i;
VD>    }
    
VD>    public IEnumerator<int> GetOdd()
VD>    {
VD>        for (int i = 1;; i += 2)
VD>            yield return i;
VD>    }
VD>}
VD>


Влад, а что этот код делает? Я не иронизирую, мне просто интересно. Что такое yield?
сам слушаю и вам рекомендую: в тишине сижу
FAQ — це мiй ай-кью!
Re[20]: И опять С++ vs С#
От: Зверёк Харьковский  
Дата: 28.11.04 19:57
Оценка:
Здравствуйте, VladD2, Вы писали:

ЗХ>>Влад, а что этот код делает? Я не иронизирую, мне просто интересно. Что такое yield?


VD>Вот тут http://gzip.rsdn.ru?/article/csharp/newincsharp.xml#XSLTPART149120120
Автор(ы): Владислав Чистяков (VladD2)
Дата: 24.06.2004
В статье рассказывается о новшествах, которые должны появиться в новой версии языка C#

все описано (см. раздел "Итераторы").


VD>Основная суть:

VD>...

Спасибо, стало понятнее!

Поправь меня, если я ошибаюсь: все это предназначено для того, чтобы локализовать код итерации по классы в самом классе, а не выносить в отдельный класс итератора, isn't it?
сам слушаю и вам рекомендую: в тишине сижу
FAQ — це мiй ай-кью!
Re[22]: И опять С++ vs С#
От: Зверёк Харьковский  
Дата: 28.11.04 23:36
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, Зверёк Харьковский, Вы писали:


ЗХ>>Поправь меня, если я ошибаюсь: все это предназначено для того, чтобы локализовать код итерации по классы в самом классе, а не выносить в отдельный класс итератора, isn't it?


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


VD>Сила "yield return" в том, что он позволяет превратить алгоритм в список. При этом не вынуждая копировать все результаты, а стало быть позволяя делать линивые алгоритмы.


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

и еще: как без вышеприведенного примера формулируется предназначение слова yield?

и еще (вопрос на 5 ): желательно связать эту формулировку со значением слова yield ("выдавать, производить, собирать урожай").

спасибо за помощь и извините за тупость
сам слушаю и вам рекомендую: в тишине сижу
FAQ — це мiй ай-кью!
Re[22]: И опять С++ vs С#
От: Зверёк Харьковский  
Дата: 28.11.04 23:37
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Здравствуйте, Зверёк Харьковский, Вы писали:


ЗХ>>Поправь меня, если я ошибаюсь: все это предназначено для того, чтобы локализовать код итерации по классы в самом классе, а не выносить в отдельный класс итератора, isn't it?


V>нет, это для того, чтобы пошаговый алгоритм превратить в обычный цикл.


V>Компилятор создает экземпляр класса-енумератора, добавляет в него как поля твои "локальные" переменные.

V>Добавляет поле current. Конструкция yield return someValue записывает значение в current и возвращает true как результат MoveNext() итератора. В первый вызов MoveNext() алгоритм идет с начала метода до yield return. В следующие разы — продолжает алгоритм от этого места (их может быть несколько). Выход за предела алгоритма означает возврат false как результат вызова MoveNext() итератора.

угу. а чем это отличается от моей формулировки?
сам слушаю и вам рекомендую: в тишине сижу
FAQ — це мiй ай-кью!
Re[33]: И опять С++ vs С#
От: Sinclair Россия https://github.com/evilguest/
Дата: 29.11.04 07:27
Оценка:
Здравствуйте, vdimas, Вы писали:

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


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

А можно вот в этом месте подробнее? Во-первых, вроде как в текущей бете уже нет боксинга при параметризации вэлью-типом, подверженным интерфейсном констреинту. Т.е. в момент инстанцирования дженерика рантайм точно знает все адреса реализаций интерфейсных методов. Это означает, что джит может выполнить инлайнинг даже без хотспоттинга. А?
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[23]: И опять С++ vs С#
От: Mikl Kurkov Россия  
Дата: 29.11.04 07:48
Оценка:
Здравствуйте, Зверёк Харьковский, Вы писали:

ЗХ>и еще (вопрос на 5 ): желательно связать эту формулировку со значением слова yield ("выдавать, производить, собирать урожай").


Есть еще значения слова yield — прервать оратора, уступить трибуну.
Re[33]: И опять С++ vs С#
От: VladD2 Российская Империя www.nemerle.org
Дата: 29.11.04 21:55
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Эти постулаты мы и сами знаем.


Видимо фигово, раз постоянно про них забываете.

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


Про порядки — это досужие домыслы. Практика показывает, что максимум в 3 раза. И то в наихудших условиях. Ну, а по жизни разница оказывается на проценты. А то и наоборот (получается выигрыш). К тому же весь проигрышь — это всего лишь резальтат недостаточной оптимизации. Рано или поздно оптимизаторы улучшатся и разница изчезнет. А вот удобство и простота останется.

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


Это не так. VC7.x делает подобные оптимизации на ура. И это при статической компиляции которая не позволяет увидить всю программу целиком. А у менеджед-кода компиляция может производиться при инсталляции приложения на конкретную машину. При этом весь код доступен и можно делать более мошьные спекулятивные оптимизации. Так что это вопрос времени и денег положенных на оптимизацию. Чем бльше менеджед-кода будет в Виндовс, тем более выгодно МС будет вкладывать деньги в оптимизацию компиляции менеджед-кода. Так что думаю в ближайшие 2-5 лет скоростные хорактеристики менеджед-кода сравняются с характеристиками лучших компиляторов С++, а то и превзойдут их (ведь возможностей по оптимизации куда больше).

V>Все это здорово, за исключением одного но...

V>Что мешает разработать С++ для аппаратного байт-кода?

Что такое "аппаратный байткод"?

V>(С++/CLR — это не то. Он отделяет managed код от обычного. А тут именно с прицелом на тот самый байт код VM.)


Что-то я не пойму чему ты тут радуешся. Изложи свои мысли более внятно.

V>--------

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

MSIL разработан под компиляцию в машинный код. Они никогда не интерпретируется и то, что он основан на стэковой машине (видимо именно об этом ты пытаешся вести речь ) ровным счетом ничего не значит. После компиляции получается обычный машинный код ничем от С++-ного не отличающийся.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[34]: И опять С++ vs С#
От: VladD2 Российская Империя www.nemerle.org
Дата: 29.11.04 21:55
Оценка:
Здравствуйте, Sinclair, Вы писали:

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


Совершенно верно. Для типов параметризуемых вэлью-типами рантайм обязан порождать специализированный код. Но к сожалению качество его пока не вилеко и выигрыша в скорости не получается. Ну, да это всего лишь вопрос времени. Работы по оптимизации уже видутся и в ближайшие несколько лет, думаю, ситуация с оптимизацией изменится.

В общем, точно такие же разговоры 10 лет назад велись по поводу компиляторов С++. Оптимизация С++ задача куда более сложная нежели С. И на основании того, что тогда она еще не была сделана скептики тоже делали далеко идущие выводы. Сейчас эти скептики на помойке истории. Пройдет несколько лет и эти будут там же.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[25]: И опять С++ vs С#
От: VladD2 Российская Империя www.nemerle.org
Дата: 29.11.04 21:56
Оценка:
Здравствуйте, vdimas, Вы писали:

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


VD>>Еще одна непрада. Твой код не только больше, он еще и не полон. Ты каждый раз забываешь продемонстрировать код самого шаблона. И каждый раз пытаешся опустить тот факт, что тебе нужно резко усложнять алгоритм.


V>Так и есть. По диагонали все-таки читаешь.


Просто тебе очень хочется так думать.

V> Учитывая твои предыдущие замечания на этот раз я приводил ПОЛНЫЙ код.

V> Там 2 блока — блок с шаблонными классами-хелперами и блок, где я их применяю. И он полностью эквивалентен твоему примеру.

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

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


V>No comments...


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

V> Похоже ты всерьез считаешь компилятор умнее меня


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

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


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

V>Все т.н. ленивые перечисления — это элементарщина, в том коде решено 2-мя строками целевого алгоритма (метод MoveNext). Вся остальная т.н. "тонна кода" — суть строки объявления класса и реализуемых методов интерфейса.


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

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

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


V>Какая нахрен предвзятость?


Махровая!

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


Я привел абстрактый пример. Это ты все пытаешся свести его к конкретному. Это был пример демонстрирующий элегантую и простую реализацию паттерна проектриования "Итератор". Ты же продемонстрировал неспособность С++ так же элегантно реализовать тот же паттерн.

V> Я ввел пару шаблонных хелперов, которые решают твой же пример более чем просто.


Ты нагородил кучу грязи в которой еще разобраться нужно. А разбираться болшинство не буед.

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


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

V>Уже создал — NestedEnumerator. Теперь мой код обхода дерева может быть строка-в-строку похож на твой.


Это не правда.

V> Но это, как раз таки, не суть важно. Ты не ответил на принципиальный вопрос о применимости рекурсивных итераторов.


А что ты хочешь о них услышать?

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


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

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


Спорить с людьми утвреждающиеми, что и так все можно мне надоело уже в начале 90-ых, когда они утверждали, что все что можно на С++, можно и на С. Доказать таковым ничего нельзя. Их выличит только время. Крикуны от С и ассемблера уже докричались (хотя до сих пор иногда слышатся отдельные голоса). С++-ники пока что еще кричат. Ну, что-же... пусть кричат.

V>-------------

V>несколько абзацев со строками типа "цепляешься за старое" я позволил себе проигнорировать как беспредметные ответвления.

Понятно. Тебе обязательно нужно их игнорировать.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[23]: И опять С++ vs С#
От: VladD2 Российская Империя www.nemerle.org
Дата: 29.11.04 21:56
Оценка:
Здравствуйте, Зверёк Харьковский, Вы писали:

ЗХ>мняяя.... а это настолько специфично, что для этого нужно новое ключевое слово?


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

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

ЗХ>я, опять же, не иронизирую, я пытаюсь разобраться.


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

ЗХ>то есть без введения нового ключевого слова эту проблему никак было не решить?


yield всего лишь часть синтаксиса. К тому же он не является ключевым словом. Ты по прежнему можешь создать переменную с именм yield и никаких проблем не будет.

ЗХ>и еще: как без вышеприведенного примера формулируется предназначение слова yield?


Непонял вопроса.

ЗХ>и еще (вопрос на 5 ): желательно связать эту формулировку со значением слова yield ("выдавать, производить, собирать урожай").


Я не историк и не знаток английского языка. Лингво по поводу этого слова говорит:

yield
1) (производственный) выход; выход (годных) изделий; выпуск; объем выпуска (продукции)
2) вырабатывать (значение)
3) давать, выдавать (импульс)


Пункт 2 мне кажется самым подходящим.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[24]: И опять С++ vs С#
От: Зверёк Харьковский  
Дата: 29.11.04 22:12
Оценка:
Здравствуйте, VladD2, Вы писали:

ЗХ>>мняяя.... а это настолько специфично, что для этого нужно новое ключевое слово?


VD>Это вопрос или сомнение?

Это вопрос.

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

Это к чему сказано?

ЗХ>>я, опять же, не иронизирую, я пытаюсь разобраться.

VD>Такое количество оправданий наводит на обратную мысль.
Нет. просто тебе свойственно воспринимать такого рода вопросы как иронию. Поэтому я специально уточнил:

Я просто занимаюсь самообразованием. (Возможно, правда, что в этой ветке это — офтопик )
И попросил сформулировать смысл и предназначение слова yield.
Всего лишь.

ЗЫ: Чего ты опять с ветряными мельницами воюешь?
сам слушаю и вам рекомендую: в тишине сижу
FAQ — це мiй ай-кью!
Re[23]: И опять С++ vs С#
От: Sinclair Россия https://github.com/evilguest/
Дата: 30.11.04 10:15
Оценка:
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>мняяя.... а это настолько специфично, что для этого нужно новое ключевое слово?
ЗХ>я, опять же, не иронизирую, я пытаюсь разобраться.
ЗХ>то есть без введения нового ключевого слова эту проблему никак было не решить?
Это не просто введение нового ключевого слова.
Это на самом деле нарошный синтаксис для сокращения записи кода. Синтаксический сахар. Никакого другого способа добиться того же результата в рамках C# 1.0 нет. Просто сначала позаботились о пользователях коллекций, введя
foreach(A a in b){...} === (for IEnumerator e = ((IEnumerable)b).GetEnumerator(); e.MoveNext()) {a = e.Current; ... }

Эта красивая идея, однако, оказалась не очень удобной для разработчиков коллекций, т.к. паттерн требует реализации лишнего класса. Тогда и решили упростить эту задачу так, чтобы программисту достаточно было написать самое необходимое, причем в одном месте, а не размазать все по четырем методам двух классов.
ЗХ>и еще (вопрос на 5 ): желательно связать эту формулировку со значением слова yield ("выдавать, производить, собирать урожай").
Выдать часть урожая
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[24]: И опять С++ vs С#
От: Зверёк Харьковский  
Дата: 30.11.04 12:02
Оценка:
Здравствуйте, Sinclair, Вы писали:

ЗХ>>мняяя.... а это настолько специфично, что для этого нужно новое ключевое слово?

ЗХ>>я, опять же, не иронизирую, я пытаюсь разобраться.
ЗХ>>то есть без введения нового ключевого слова эту проблему никак было не решить?
S>Это не просто введение нового ключевого слова.
S>Это на самом деле нарошный синтаксис для сокращения записи кода. Синтаксический сахар. Никакого другого способа добиться того же результата в рамках C# 1.0 нет. Просто сначала позаботились о пользователях коллекций, введя
S>
S>foreach(A a in b){...} === (for IEnumerator e = ((IEnumerable)b).GetEnumerator(); e.MoveNext()) {a = e.Current; ... }
S>

S>Эта красивая идея, однако, оказалась не очень удобной для разработчиков коллекций, т.к. паттерн требует реализации лишнего класса. Тогда и решили упростить эту задачу так, чтобы программисту достаточно было написать самое необходимое, причем в одном месте, а не размазать все по четырем методам двух классов.
Ну, я это понял еще из первого ответа Влада. Чего мне не понятно до сих пор — каково предназначение именно ключевого слова yield.
сам слушаю и вам рекомендую: в тишине сижу
FAQ — це мiй ай-кью!
Re[25]: И опять С++ vs С#
От: Sinclair Россия https://github.com/evilguest/
Дата: 30.11.04 12:43
Оценка:
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>Ну, я это понял еще из первого ответа Влада. Чего мне не понятно до сих пор — каково предназначение именно ключевого слова yield.
А как ты иначе отличишь "постепенную" выдачу результатов?
Ну вот смотри:
public class Test
{
  private int[] digits;
  public IEnumerator GetEnumerator()
    {
      return digits.GetEnumerator(); // возвращаем встроенную реализацию IEnumerator для массивов;
    }
    public IEnumerator GetReverseEnumerator()
    {
      for(int i=digits.Count-1; i>=0; i++) // итерируемся сами
          yield return digits[i];  // и отдаем результат по частям
    }
    public IEnumerator AchieveError()
    {
      return digits[0]; // так нельзя - ошибка типа.
    }
}
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[22]: И опять С++ vs С#
От: vdimas Россия  
Дата: 30.11.04 12:48
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Хороший пример — алогоритмы обхода бинарного дерева. Дерево можно обойти множеством способов. Обход прекрасно выражается в иде рекурсивных процедур. Однако намного удобнее оперировать не рекурсией, а абстракцией "список". Самым легким решением было бы копирование всех объодимых элементов в некий список, но елси учесть, что зачастую объод делается частичный, и то что дерево может иметь большой объем, намного выгоднее было бы сделать некий динамический списк элементы которого формируются по мере запроса. Вот для таких задач "yield return" отличное решение. Мы пишем нужный рекурсивный алгоритм, тесно связанный с реализацией дерева, а на выходе получаем независимый, динамически формируемый списк.


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

В случае применения итераторов для обхода дерева получим вот: здесь
Автор: vdimas
Дата: 24.11.04

(смотреть последнюю часть поста)
Re[24]: И опять С++ vs С#
От: Зверёк Харьковский  
Дата: 30.11.04 13:30
Оценка:
Здравствуйте, vdimas, Вы писали:

ЗХ>>угу. а чем это отличается от моей формулировки?

V>тем, что алгоритм итерации будет развернут принципиально по-другому, чем в случае выноса в отдельный класс.
Не понял
сам слушаю и вам рекомендую: в тишине сижу
FAQ — це мiй ай-кью!
Re[26]: И опять С++ vs С#
От: Шахтер Интернет  
Дата: 01.12.04 01:30
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Шахтер,


>> ПК>
>> ПК>void f(ref<T>);
>> ПК>

>> ПК>Ну-ка то же самое, да на C# (чур, препроцессоры не предлагать)

>> Щаз скажу страшное -- а зачем в C# проверять на нуль? Это делается автоматом средой с генерацией исключения. Причем с трассировкой стека.

>> Масло маслянное.

ПК>Дык, 1) в отличие от приведенного примера на C++, во время исполнения, никаких подсказок во время компиляции;


Не совсем понял, а какие подсказки во время компиляции будут в C++?

void gun(T *ptr)
 {
  fun(*ptr);
 }


ПК>2) исключение возникнет во время разыменования, а не там, где этот null возник (Влад даже статью про важность локализации таких вещей написал, "As is...").


Ну, если разыменование в той же функции, то это не проблема. Если же этот указатель запоминается, а потом где-то разыменовывется, то да, согласен -- тут лучше вставить код для проверки контракта вызова.
... << RSDN@Home 1.1.0 stable >>
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[27]: И опять С++ vs С#
От: Павел Кузнецов  
Дата: 01.12.04 01:39
Оценка:
Шахтер,

> Не совсем понял, а какие подсказки во время компиляции будут в C++?

>
> void gun(T *ptr)
>  {
>   fun(*ptr);
>  }    
>


Дык, ты же сделал разыменование — теперь сам виноват Подсказки были бы, если бы передавал указатель. Плюс, если хочется, можно их организовать для случая:
void f(ref<T>);
Posted via RSDN NNTP Server 1.9 delta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[28]: И опять С++ vs С#
От: Шахтер Интернет  
Дата: 01.12.04 01:48
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Шахтер,


>> Не совсем понял, а какие подсказки во время компиляции будут в C++?

>>
>> void gun(T *ptr)
>>  {
>>   fun(*ptr);
>>  }    
>>


ПК>Дык, ты же сделал разыменование — теперь сам виноват Подсказки были бы, если бы передавал указатель. Плюс, если хочется, можно их организовать для случая:

ПК>
ПК>void f(ref<T>);
ПК>


Не могу никак въехать, что за подсказки???
... << RSDN@Home 1.1.0 stable >>
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[28]: И опять С++ vs С#
От: Шахтер Интернет  
Дата: 01.12.04 01:56
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Шахтер,


>> Не совсем понял, а какие подсказки во время компиляции будут в C++?

>>
>> void gun(T *ptr)
>>  {
>>   fun(*ptr);
>>  }    
>>


ПК>Дык, ты же сделал разыменование — теперь сам виноват Подсказки были бы, если бы передавал указатель. Плюс, если хочется, можно их организовать для случая:

ПК>
ПК>void f(ref<T>);
ПК>


Или ты имеешь ввиду что-то типа

template <class T>
class ref
 {
    T *ptr; 
     
   public:

    ref(T *ptr_) { ptr=ptr_; ASSERT(ptr_); }    
     
    operator T & () const { return *ptr; }
 };
... << RSDN@Home 1.1.0 stable >>
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[29]: И опять С++ vs С#
От: Павел Кузнецов  
Дата: 01.12.04 03:28
Оценка:
Шахтер,

>>> Не совсем понял, а какие подсказки во время компиляции будут в C++?

>>>
>>> void gun(T *ptr)
>>>  {
>>>   fun(*ptr);
>>>  }    
>>>


> ПК>Дык, ты же сделал разыменование — теперь сам виноват Подсказки были бы, если бы передавал указатель. Плюс, если хочется, можно их организовать для случая:

> ПК>
> ПК>void f(ref<T>);
> ПК>


> Не могу никак въехать, что за подсказки???


Давай вернемся к самому началу
Автор:
Дата: 27.11.04
. Человек хотел, чтобы автоматизировать проверку аргументов функции на null.

В C++ требования того, чтобы аргумент функции не был null, добиться элементарно: достаточно использовать ссылки. Во всех местах, где функция будет вызвана с потенциально нулевыми указателями, последуют ошибки компиляции — "подсказки", и у программиста будет возможность подумать, прежде чем написать * перед указателем. Плюс по объявлению функции сразу понятно: null принимать она не хочет.

Если разыменование покажется слишком легким действием, то можно сделать свой класс ref<T>, объекты которого нужно будет создавать явно. Думать можно будет дольше

Все. Никакой rocket science Но в результате пожелание об автоматизированных проверках аргументов на null выполнено.

К сожалению, в C# этого у меня сделать не получается.
Posted via RSDN NNTP Server 1.9 delta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[35]: И опять С++ vs С#
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 04.12.04 13:59
Оценка:
Здравствуйте, vdimas, Вы писали:

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


А вот совсем недавно Кирилл Фаенов, директор группы высокопроизводительных вычислений в Редмонде, говорил что для этих самых вычислений нередко используют Java. Догадываешься почему?

VD>>К тому же весь проигрышь — это всего лишь резальтат недостаточной оптимизации.

V>Нет, если метод ожидает именно интерфейс в твоем случае, и ты реально подаешь туда различные имплементаторы этого интерфейса, то никакого инлайна в этом конкретном методе не может происходить по принципиальным причинам. Он ОБЯЗАН вызывать виртуальные ф-ии имплементаторов. И он их честно вызывает.

Тебе уже вроде говорили — в дотнете это не всегда так. И, это, может ты объяснишь чем тебя не устраивает нормальное русское слово реализатор?

VD>>Так что это вопрос времени и денег положенных на оптимизацию.

V>Нет, это вопрос самой сущности виртуальных ф-ий.

Видишь ли — в дотнете реализация интерфейса не обязана быть виртуальной.
... << RSDN@Home 1.1.4 beta 3 rev. 241>>
AVK Blog
Re[27]: И опять С++ vs С#
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 04.12.04 13:59
Оценка:
Здравствуйте, vdimas, Вы писали:

V>То, как сейчас ведут себя GUI-дотнет приложения на моей железке не выдерживает никакой критики )


О каких приложениях речь?
... << RSDN@Home 1.1.4 beta 3 rev. 241>>
AVK Blog
Re[27]: И опять С++ vs С#
От: VladD2 Российская Империя www.nemerle.org
Дата: 07.12.04 00:26
Оценка:
Здравствуйте, vdimas, Вы писали:

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


Со своей стороны выскажу это тебе и ПК. Мне кажется вы тут больше преуспели. Так разговор о совершенно конкретной граматике (а во основе о сложностях ее реализации) вы очень быстро свели к разговору о гипотетической граматике.

V>Ты говорил, вроде, что я привел код не полностью.


Возможно я нетуда посмотрел.

V> Он приведен полностью и функционально эквивалентен твоему.


Он не универсален, а стало быть о эквиалентности говорить уже не приходится.

Ты приводишь решения на базе паттернов. А паттерны и ЯП — это не совсем одно и тоже. Эдак я могу утверждать, что — это ООЯП, так как в нем возможно реализовать ООП в виде паттерна.

V>На практике у С++ программистов по-другому реализована концепция итераторов. Хотя она вписывается в паттерн.


На практике я сам как бы С++-программист. Так что не нужно мне рассказывать примитивные вещи. Ты не даром оговорился о паттерне. Все программирование на С++ — это череда применения кучу паттернов причем во многих случаях этих реализаций этих паттернов море и их реализация далека от идиальной.

Собственно C# — это и был язык в котором хотели избавиться от морей паттернов дав набор паттернов интергрированных в языкх и фрэймворк настолько хорошо, что они уже перестают быть паттернами и становятся базисом языка/платформы.

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


Я стал читать сам код, но надо признаться с большим усилием над собой и не сильно вдаваясь в подробности (так как этот код мне вряд ли когда-нибудь пригодится).

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


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


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

В общем, похоже мы опять скатывается к теме сомнений по поводу возможностей оптимизации.

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

Собственно я явно повторясь. Почитай вот это: Re[35]: И опять С++ vs С#
Автор: VladD2
Дата: 07.12.04
сообщение. Оно хотя и малость о другом, но подоплека твоих сомнений и скепсиса та же самая.

V>А здесь
Автор: vdimas
Дата: 24.11.04
указал на мааленький такой подводный камешек. Последняя часть поста.


Ну, то есть тебя снова беспокоют вопросы производительности?

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

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

VD>>Чушь поришь тут ты утверждая, что горы малопонятного кода лучше простых и ясных конструкций.

V>Повтори это после прочтения указанной сыылки

Ты уж сам лучше прочти в цикле сколько нужно раз.

V>Я активно использую дотнет.


Наверно для тренировки, так как все что тебе нужно можно нманого сделать на С++ намного быстрее.

V> Прямо сейчас проектирую проект, где сервак приложений будет на дотнете, и будет несколько типов агентов к нему, и на С++ в т.ч.


Интересно кто выбрал такое (довольно мудрое решение)? И чем мотивировал?

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


Можно узнать характеристики этих слабых десктопов?

V> Во всей этой ветке речь не шла о том, что дотнет не имеет будущего.


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

V> Это же очевидно, что имеет и еще как. Речь шла о том, что ты сильно заблуждаешься, считая что дотнет легко вытеснит С++ из всех областей (ты приводил то качество стандарта как аргумент, то тот факт что в системных областях С лучше С++, то вот конструкции всякие).


Э... как говорится, стоять Зорька!
Где это я такое утверждал? Где я говорил, что легко, да и вытеснит.

Окончательно не вытиснит скорее всего никогда. Скорее их обоих вытеснит какая-нибудь новая, более перспективная, технология. Скорее всего оная будет основана в немалой мере на том самом дотенете. Что можно взять в оную из С++ я убей бог не вижу. Все пиемущества С++ жалкое подобие того, что есть во многих исследовательских языках и технологиях. То же матапрограммирование на шаблонах — это детских лепет по сравнению с препроцессорами/макросами/матаподсистемами многих функциональных языков или того же R#-а. А полезные вещи из С++ уже повзаимствованы.

Что касается скорого вытеснения, то я думаю, что раньше чем в следующем десятилетии об этом серьезно говорить не прийдется. Но процесс уже идет. Потихоньку, помаленьку... но идет. Комьюнити дотнетных программистов на RSDN-е уже практически равно комьюнити С++-ников. И со временем дотнтеное комьюнити привысит С++-ное. Мне кажется это очевидным, хотя и с этим очень многие поспорят с пеной у рта. Я даже думаю, что стольк рьяное наставление плюсов всем кто защищает С++ — это проявление подспудной боязни данных мыслей.

V>Наши итераторы — суть маленькое лирическое отступление, не более. Мне вообще эта тема не интересна,


Оно и видно.

V> ибо итераторы в C# — весьма тяжеловесная сущность.


На чем основывается это утверждение?

V> А нынешняя возможность легко создавать рекурсивные итераторы меня вообще веселит.


Ну, что-же. Это как раз то веселье которое ничем плохим окончится не может. Так как в любом случае пострадавших не будет.

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


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

Если ты готов спонсировать разработку, я готов взяться за оптимальную реализацию (на R#-е, так как не имею доступа к исходникам компилятора) итераторов C# 2.0 по эффективности практически неотличимой от аналогичной ручной реализации. Цена вопроса 2 килобакса. Обещаю вернуть эту сумму в двойне в случае неудачи проекта.

V> Скажи мне о таких цифрах и этих ощущениях лет 10 назад — не поверил бы. Ты там говоришь, что через 10 такие как я вымрут... А я просто уверен, что через 10 лет на железке порядка 30-50GHz я тоже не буду чуствовать мощщи и скорости. То, как сейчас ведут себя GUI-дотнет приложения на моей железке не выдерживает никакой критики )


Извини, но это безотвественный треп. Моя железка не намного лучше твоей (AMD 64 3500), но оные приложения у меня просто летают. Вот сейчас пишу это сообщение из одного из них (можешь убедиться в этом взглянув на мою подпись). Да и не ГУИ тоже. Например, постоянно вожусь с R#-овским парсером который парсит любой проект доступный мне за доли секунды.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[25]: И опять С++ vs С#
От: VladD2 Российская Империя www.nemerle.org
Дата: 07.12.04 00:26
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>1)STL-Like итераторы в С++ это совсем не те итераторы что в C#


А где я говорил вообще STL и в частности про их итераторы? Я как раз о реализации всего паттерна в целом.

WH>2)Если приминить мозги то реализация STL-Like итератора дело не такое уж и напряжное


Как я уже говорил не о них речь. Речь о простоте дизайна и о переведении паттернов в разряд простых фич языка. Итераторы C# 2.0 — это как раз тот случай.

Гора кода поскипана. Могу скзать, только что паттернами решаются любые задачи в том числе ООП на С. Вот только любые паттерны менее удобны и просты чем продуманные и хорошо встроенные идиомы языка.

WH>С этим итератором можно делать гораздо больше чем с итераторами из C#.


Ты уверен что полностью понимашь, что такое итераторы C# 2.0?

WH>Шаблон iterator_facade_t пишется раз и навсегда.(могу показать он очень простой но там кода много... почти все операторы перегружаются)


Программирую на С++ я вынужден каждый раз писать приметивные базовые вещи. Зачем? Зачем мне извращаться и ломать голову как реализовать тот или иной патерн? Мне проще когда все это делает порой строк кода используемого мной языка. Бесспорно, что на С++ с некоторой натяжкой в виде паттернов можно сэмулировать практически любую возможность C#. Так делегаты в общем-то можно заменить объемистыми классами Буста или Локи, а итераторы еще какой-нибудь горкой кода в сочетании с малопонятным синтаксисом их применения. Но зачем все это? Я правильно понимаю, чтобы убить еще чес при компиляции или чтобы запутаться в десятках реализаций?

VD>>Что лучше "чистота" языка или удобство и простота каждый решат для себя сам.

WH>Что есть чистота языка вопрос очень филосовский...

Да нет — это вопрос дизайна языка. К дизайну С++ подходили довольно наплевательски. Он приносился в жертву эффективности и совместимости. В итоге получился довольно уродливый монстр который не хотят (а возможно боятся) менять сами его создатели.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[23]: И опять С++ vs С#
От: VladD2 Российская Империя www.nemerle.org
Дата: 07.12.04 00:26
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Обход дерева — самый неудачный пример применения итераторов.


Отличный пример! Просто надо вгнать из головы всех тараканов связанных с оптимизацией.

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


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

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

V>В случае применения итераторов для обхода дерева получим вот: здесь
Автор: vdimas
Дата: 24.11.04

V>(смотреть последнюю часть поста)

Думаю, не нужно обяснять почему решение на итераторах окажется проще в реализации?
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[29]: И опять С++ vs С#
От: VladD2 Российская Империя www.nemerle.org
Дата: 07.12.04 02:24
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Похоже, ты упорно не понимаешь, что не все видят именно архитектурные аспекты одинаково, и не все согласны с твоими оценками именно архитектурных отличий C# от C++ как безусловных преимуществ.


Этих людей мне тже залко.
... << RSDN@Home 1.1.4 beta 3 rev. 249>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[25]: И опять С++ vs С#
От: VladD2 Российская Империя www.nemerle.org
Дата: 07.12.04 02:24
Оценка:
Здравствуйте, Зверёк Харьковский, Вы писали:

ЗХ>Ну, я это понял еще из первого ответа Влада. Чего мне не понятно до сих пор — каково предназначение именно ключевого слова yield.


Передача управления во вне итератора. Грубо говоря во время его выполнения работает код который использует итератор. После обработки очередного элемента управление приезжает обратно и возмобнавляется со следующей за yield строкой.
... << RSDN@Home 1.1.4 beta 3 rev. 249>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[28]: И опять С++ vs С#
От: vdimas Россия  
Дата: 07.12.04 12:06
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Интересно кто выбрал такое (довольно мудрое решение)? И чем мотивировал?


Я выбрал. Мотивировал наличием библиотеки RFD. На базе которой будет свое, немного более узконаправленное решение. В общем, мотивировка — в наличие подробной метаинформации.

Да и ремоутинг на дотнете ВЕСЬМА удобен. Как channel подаем IIOP.Net и наши CORBA клиенты легко работают с серверными дотнетовскими объектами.

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


VD>Можно узнать характеристики этих слабых десктопов?

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

GUI-клиенты будут на дотнете, они будут "крутиться" на нормальных машинах.

VD>Да нет. Она тут идет подспудно постоянно. Ты вот постоянно пыташся доказать, что вопросы производительности являются приговором, и что они куда важнее чистоты дизайна. Иначе твои слова вообще никак объяснить нельязя. Не спориш же ты со мной только от того, что тебе противно то что ты со мной согласен?


Да, со многими твоими резкими пророчествами согласиться не могу, извини.

VD>Окончательно не вытиснит скорее всего никогда. Скорее их обоих вытеснит какая-нибудь новая, более перспективная, технология. Скорее всего оная будет основана в немалой мере на том самом дотенете.

Угу, в язык С# 3.0 добавят еще шаблонных фич из С++, потом сделают возможность помечать типы, для которых метаинформация НЕ НУЖНА, и будет это уже "C++ + GC + metainformation + Rich-Runtime"

VD>Извини, но это безотвественный треп. Моя железка не намного лучше твоей (AMD 64 3500), но оные приложения у меня просто летают. Вот сейчас пишу это сообщение из одного из них (можешь убедиться в этом взглянув на мою подпись). Да и не ГУИ тоже. Например, постоянно вожусь с R#-овским парсером который парсит любой проект доступный мне за доли секунды.


Да ну блин. Я одновременно пишу ГУЙ и на С++ и на дотнете. Меня эти подергивания, мини-паузы и т.д. на ТАКОЙ машине раздражают. С++ GUI вел себя так на пне 250.
Re[30]: И опять С++ vs С#
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 07.12.04 13:26
Оценка:
Здравствуйте, VladD2, Вы писали:

ПК>>Похоже, ты упорно не понимаешь, что не все видят именно архитектурные аспекты одинаково, и не все согласны с твоими оценками именно архитектурных отличий C# от C++ как безусловных преимуществ.

VD>Этих людей мне тже залко.
Ага, а мне — всю нашу индустрию.
... << RSDN@Home 1.1.3 stable >>
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[29]: И опять С++ vs С#
От: VladD2 Российская Империя www.nemerle.org
Дата: 08.12.04 21:43
Оценка:
Здравствуйте, WolfHound, Вы писали:

VD>>И все же похоже ты действительно не очень понимашь о чем идет речь. Речь идет не об энумераторах, а об итераторах — новой концепци реализации тех самх энумераторов. см. http://gzip.rsdn.ru/article/csharp/newincsharp.xml#EJA
Автор(ы): Владислав Чистяков (VladD2)
Дата: 24.06.2004
В статье рассказывается о новшествах, которые должны появиться в новой версии языка C#

раздел "Итераторы".

WH>Ты меня точно с кемто путаешь. Про этот синтаксический сахар я прекрасно знаю. Но он не добавляет никакой функциональности.

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

WH>Кстати а как там с

WH>

Из обнаруженных мной проблем можно выделить то, что мне не удалось создать итератор, производящий рекурсивный вызов. Это довольно серьезное ограничение, поскольку итераторы как нельзя лучше подошли бы для деревьев и других рекурсивных структур, для которых создавать перечислители особо сложно и неудобно. Будем надеяться, что к release-версии эту проблему устранят.


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

WH>Да все так и делают.


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

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


Гы "не худшее... но... лучше".
В общем, я тоже по начлу сокрушался об отсуствии деструкторов. А вот сейчас уже понимаю, что эта потеря илюзорана. Потребности в них особой нет. Так что это просто одна из привычек кторую нужно изжить и просто учитывать их отсутствие в дизайне приложения.

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

WH>Я бы не сказал что это проще и элегантней.


Не думать всегда проще чем думать.

WH>К томуже у меня есть чувство что будут проблемы.


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

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

VD>>Кмпиляцию тормозя,

WH>Миф

Я с этого мифа несколько лет начинал свой рабочий день.

VD>>с полиморфизмом проблемы,

WH>В смысле

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

VD>>между процессами не передаш,

WH>Ну это проблемы несколько иного порядка и решать их надо на несколько другом уровне.

Все того же. Это резко портит архитектуру. Сделав решение локально я не смогу использовать его при масшатабировании или в качестве универсального паттерна.

VD>>интерграция с разными компонентными технологиями вроде COM фиговая и т.п.

WH>Ну не знаю. У меня проблем небыло.

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

VD>>Это сказка для не посвященных. Я как бы сам плавал с 25-минутной компиляцией проекта со всем инкриментами и прекомпайлами.

WH>Я какбы сам компилировал.

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

Сейчас в R#-е и объемы немаленькие, и перекомпиляция полная происходит переодически, а проблем нет, так как вся перекомпиляция занимает несколько секунд.

VD>>Проблемы с вызовом деструкторов у суперклассов не имеющих виртуального деструктор тебе знакомы?

WH>Я тебя умоляю... Ты уже устраивал флейм на эту тему. Результаты на лицо... тебя никто не поддержал ибо это не проблема.

А ты не умаляй. Грабли есть? Люди на них переодически наступают? А то, что большинство плюсовиков бревна в глазу своего любимого языка незаметят — это и так ясно. Да и разговор этот показал, что дело именно в оптимизации.

VD>>А размер int-а?

WH>А что размер инта? У тебя хоть раз с ним были проблемы?

Они есть у всех кто пишет код для платформ где он разный. Так как я писал код для ДОС-а и Вынь16, то естественно поимел пролем и я. МС вон, в Вынь64 так и оставил его 32-разрядным от греха подальше. А то ведь такая мелочь может создать столько проблем, что охринеешь. И все это именно для оптимизации. А нужна она тому кто язык использует или нет никто не спрашивает.

WH>А валью типы в шарпе? Нафига еще одна сущность?

это выбор скорости в ущерб стройности дизайна языка и простоте его использования


Видимо ты имел в виду струкутры, а не вэлью типы. Так как энумы и простые типы тоже вэлью-типы. Тут, согласен. В Яве так и аргументировли их отсуствие. Более того, я лично зачемчаю, что использую их очень редко. На весь парсер R#-а их ровно две штуки Location и Modifiers. Оба влэлью-типы по своему смыслу.

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

WH>Твои предложения на счет деструкторов точно не реально.


Тебе так только кажется. Просто ты не как не можешь предствить, что может быть другой С++.

WH>Тебе самому не смешно? Это чудо можно использовать только для интеграции мендежет и анменеджед кода.


Отнюдь.

WH>К томуже проблемы то они и не решают.


Они демонстрируют пути решения. Этого достаточно.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[28]: [Offtop] UseWaitCursor()
От: _FRED_ Черногория
Дата: 09.12.04 02:56
Оценка:
Здравствуйте, VladD2, Вы писали:

WH>>Тоже относится и к C#. Вот например так я вешаю курсор песочные часы на форму.

WH>>
WH>>            using(WaitCursor waitCursor = owner.WaitCursor())
WH>>            {
WH>>            //тут гора тормозного кода который может кинуть исключение итп
WH>>            }
WH>>

WH>>Ладно что хоть с try/finnaly возится не приходится... А все почему? А по тому что в C# нет автоматических деструкторов. И их приходится эмулировать.

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


VD>А твою проблему можно решить намного проще и элегантрее. Например, так:

VD>
VD>partial class Form1 : Form
VD>{
VD>    public Form1()
VD>    {
VD>        InitializeComponent();
VD>    }

VD>    void UseWaitCursor()
VD>    {
VD>        if (Form.ActiveForm != null)
VD>        {
VD>            Form currForm = Form.ActiveForm;
VD>            currForm.Cursor = Cursors.WaitCursor;
VD>            Application.Idle += delegate(object sender, System.EventArgs e)
VD>            {
VD>                currForm.Cursor = Cursors.Default;
VD>            };
VD>        }
VD>    }

VD>    private void button1_Click(object sender, EventArgs e)
VD>    {
VD>        // Test!
VD>        UseWaitCursor();
VD>        for (int i = 0; i < int.MaxValue; i++)
VD>        {
VD>        }
VD>    }
VD>}
VD>


[Offtop]
Не, этак не пойдёт — нехорошо будет, если внутри цикла вызывать что-то, тоже использующее UseWaitCursor().
А если в цикле ещё и Application.DoEvents() дёргать периодически

VD>Дык, как видишь ты с успехом обошелся без деструктора. При грамотном подходе потребоность в них появляется очень редко.

Help will always be given at Hogwarts to those who ask for it.
Re[29]: [Offtop] UseWaitCursor()
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.12.04 20:05
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>[Offtop]

_FR>Не, этак не пойдёт — нехорошо будет, если внутри цикла вызывать что-то, тоже использующее UseWaitCursor().

Это не рабочий код! Это приблизительное решение, описывающее общую идею.

_FR>А если в цикле ещё и Application.DoEvents() дёргать периодически


Никаких проблем не будет. Idle вызывается только когда процессор бездействует. Так что до прекращения работы управление туда не попадет.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[27]: И опять С++ vs С#
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 10.12.04 22:39
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Вот именно? Почему Микрософтовци не сдлелали поддержку MVC? Почему мне пришлось это избретать самому?


Потому что контролы WinForms, кроме двух это всего лишь интерфейс к контролам виндов. А оставшиеся два вполне себе MVC. Так что жди Avalon
... << RSDN@Home 1.1.4 beta 3 rev. 255>>
AVK Blog
Re[28]: И опять С++ vs С#
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 10.12.04 22:39
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>А твою проблему можно решить намного проще и элегантрее. Например, так:

VD>
VD>partial class Form1 : Form
VD>{
VD>    public Form1()
VD>    {
VD>        InitializeComponent();
VD>    }

VD>    void UseWaitCursor()
VD>    {
VD>        if (Form.ActiveForm != null)
VD>        {
VD>            Form currForm = Form.ActiveForm;
VD>            currForm.Cursor = Cursors.WaitCursor;
VD>            Application.Idle += delegate(object sender, System.EventArgs e)
VD>            {
VD>                currForm.Cursor = Cursors.Default;

Отписаться забыл.

VD>            };
VD>        }
VD>    }

VD>    private void button1_Click(object sender, EventArgs e)
VD>    {
VD>        // Test!
VD>        UseWaitCursor();
VD>        for (int i = 0; i < int.MaxValue; i++)
VD>        {
VD>        }
VD>    }
VD>}
VD>
... << RSDN@Home 1.1.4 beta 3 rev. 255>>
AVK Blog
Re[29]: И опять С++ vs С#
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.12.04 21:30
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Отписаться забыл.

Я в курсе. Это как всегда. Я этот код вообще не запускал.

Надо бы запрос на фичу подать... автоматическая отписка от событий.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[25]: И опять С++ vs С#
От: alexeiz  
Дата: 20.12.04 05:31
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>1)STL-Like итераторы в С++ это совсем не те итераторы что в C#

WH>2)Если приминить мозги то реализация STL-Like итератора дело не такое уж и напряжное
WH>Например реализация итератора для двусвязного списка
WH>
WH>    struct iterator
WH>        :iterator_facade_t
WH>            < iterator
WH>            , value_type
WH>            , std::bidirectional_iterator_tag
WH>            >
WH>    {
WH>      ...
WH>    };
WH>


Что-то на boost::iterator_facade сильно похоже . Слизал, понимаешь, и даже ссылку не дал. Нехорошо
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.