Здравствуйте, c-smile, Вы писали:
CS>Это не я хитрый, а автор Heron'a умный.
Он тут не при чем. Я задал тебе конкретный вопрос и до сих пор не получил ответа.
AVK>>Я сам буду решать, что мне нужно. Вот к примеру типичный вариант использования интерфейсов.
CS>Ничего ты не можешь решать.
Забавно
CS>Статический полиморфизм тебе не дан большими дядями.
Я тебе уже говорил — статический полиморфизм это не только шаблоны. Кстати, было бы интересно посмотреть на ассемблерный код приведенного тобой примера.
CS>Т.е. для примера предлагаемого тобой (ниже) я могу выбрать наиболее оптимальное и эффективное решение.
Мне не надо другое решение. Мне нужен конкретный ответ на конкретный вопрос — реализуемо ли это решение на Хероновских интерфейсах.
Здравствуйте, McSeem2, Вы писали:
MS>Причем, вне зависимости от каких-либо X,Y. Поскольку Base не имеет сигнатур, описанных в IA, то и использование Base в качестве интерфеса становится невалидным.
Собственно это я и хотел услышать.
MS>А, кстати, что произойдет в C# в описанной ситуации (у класса X удалили void Foo())? MS>Я имею в виду — кто эту бяку обнаружит?
Естественно не компилятор, у него такой возможности просто нет. Вылетит TypeCastException.
Здравствуйте, McSeem2, Вы писали:
MS>... Это статический, compile time полиморфизм, почти то же что и шаблоны, но с более строгой спецификацией сигнатур интерфейсных функций.
Тут некий симбиоз:
Операция получения интерфейса — статитческая. Но сама интерфейсная ссылка которя уже
есть нечто типа
IRef<typename A>
{
A *pa;
void* methods[] = {
void (*A::Foo)();
int (*A::Bar1)();
int (*A::Bar2)(int);
....
};
}
есть некая переменная которая уже живущая своей динамическойц жизнью. Может быть параметром функции, элементом колекции и пр.
В принципе это то что в c-smile было определено как object-method-reference — тип
значения содержащий и this и method указатели как один агрегат.
Т.е. всякого рода events и listeners делались просто:
MS>>А, кстати, что произойдет в C# в описанной ситуации (у класса X удалили void Foo())? MS>>Я имею в виду — кто эту бяку обнаружит?
AVK>Естественно не компилятор, у него такой возможности просто нет. Вылетит TypeCastException.
Смею тебя уверить что именно компилятор ругнется. Типа: IA не имплементирован полностью в классе X.
Здравствуйте, AndrewVK, Вы писали:
MS>>Причем, вне зависимости от каких-либо X,Y. Поскольку Base не имеет сигнатур, описанных в IA, то и использование Base в качестве интерфеса становится невалидным.
AVK>Собственно это я и хотел услышать.
Дык! Я вообще не понимаю, о чем такой мощный флейм. Есть статический полиморфизм, есть динамический полиморфизм, между ними существует фундаментальная разница. В C# это все свалено в одну кучу и дядя-компилятор сам решает (по вторичным половым признакам), чего же тебе на самом деле надо.
А в свете того, что "Unintrusive Retroactive Polymorphism" является принципиально статическим и все происходит в compile time, то фраза
А какие от этого бенефиты, кроме повышения зависимости от опечаток?
теряет всякий смысл.
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Здравствуйте, McSeem2, Вы писали:
MS>Ты имеешь в виду C#? Если да, то что-то не верится.
Пардон. Это AndrewVK неверно ответил на вопрос и ввел меня в заблуждение. Конечно же, компилятор. В run-time будет исключение, если X забудут унаследовать от IA.
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Здравствуйте, AndrewVK, Вы писали:
CS>>Т.е. ты утверждаешь что вот это вот валидная конструкция?
AVK>Забавно . Нет. Неужели ты не понял о чем речь? Еще раз задаю вопрос — будет ли в Хероне работать мой пример без изменений? И если будет то каким образом?
Не будет, конечно же. AFAIU, вопросы позднего связывания данной (хероновской) конструкцией вообще не решаются. Наверняка там есть какие-то другие конструкции для этого, поскольку динамический полиморфизм заслуженно признан полезным и нужным.
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Здравствуйте, c-smile, Вы писали:
CS>Тут некий симбиоз: CS>Операция получения интерфейса — статитческая. Но сама интерфейсная ссылка которя уже CS>есть нечто типа
CS>IRef<typename A>
CS>{
CS> A *pa;
CS> void* methods[] = {
CS> void (*A::Foo)();
CS> int (*A::Bar1)();
CS> int (*A::Bar2)(int);
CS> ....
CS> };
CS>}
[. . .]
Что-то мне это навевает... Старую-древнюю имплементацию виртуальных функций в C++, где каждый объект хранил не указатель на vtbl, а саму vtbl целиком.
В общем и целом, понадобилось много лет, чтобы осознать, что подобная схема имеет свои преимущества. Тем более, что как говорит Vlad2, память сейчас — это вообще не ресурс .
Но они, конечно же, презрительно ухмыльнутся и скажут, "да ччо вы тут вааще возитесь, на спичках экономите — в си-шарпе уже все сделато и придумато".
Не работает, правда ни хрена, но это же мелочи. Главное — идея!
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Здравствуйте, McSeem2, Вы писали:
MS>Дык! Я вообще не понимаю, о чем такой мощный флейм. Есть статический полиморфизм, есть динамический полиморфизм, между ними существует фундаментальная разница. В C# это все свалено в одну кучу и дядя-компилятор сам решает (по вторичным половым признакам), чего же тебе на самом деле надо.
Ну, дык я и пытаюсь эту фундаментальную разницу объяснить.
...эх...ну в общем все как всегда...
Здравствуйте, c-smile, Вы писали:
CS>это фактически образование (compile time) таблицы method references — (this,funcptr) CS>Соответсвенно вызов такого "виртуального" метода — это вызов обычной невиртуальной функции.
Здорово (я не шучу). Это действительно можно было бы использовать для реализации идеи ограничений (констрэйнов) для параметов шаблонов С++ и тем самым хоть немного сняло бы сложность этого языка. Но... но рантайм полиморфизм через такой мехазнизв вроде как не возможен, а это резко усложнит ОО-дизайн и в итоге может привести к проблемам.
CS>Я считаю что механизм полезен и окажет свое воздействие на С++.
А вот вот в это я уже совсем не верю. С++ похоже уже будет развиваться только в сторону усложения. К тому же когда появится новый стандарт никому не ясно.
... << RSDN@Home 1.1.4 beta 3 rev. 273>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
CS>>IRef<typename A>
CS>>{
CS>> A *pa;
CS>> void* methods[] = {
CS>> void (*A::Foo)();
CS>> int (*A::Bar1)();
CS>> int (*A::Bar2)(int);
CS>> ....
CS>> };
CS>>}
MS>
MS>Что-то мне это навевает... Старую-древнюю имплементацию виртуальных функций в C++, где каждый объект хранил не указатель на vtbl, а саму vtbl целиком.
Я наверное неочевидно написал...
На самом деле так:
sizeof(IRef) == sizeof(void*) * 2; — два указателя: this и function table.
Т.е. по размеру один указатель на интерфейс эквивалентен member function pointer в C++
с чем уже все смирились
MS>В общем и целом, понадобилось много лет, чтобы осознать, что подобная схема имеет свои преимущества. Тем более, что как говорит Vlad2, память сейчас — это вообще не ресурс . MS>Но они, конечно же, презрительно ухмыльнутся и скажут, "да ччо вы тут вааще возитесь, на спичках экономите — в си-шарпе уже все сделато и придумато". MS>Не работает, правда ни хрена, но это же мелочи. Главное — идея!
Здравствуйте, c-smile, Вы писали:
CS>Я наверное неочевидно написал...
CS>На самом деле так: CS>sizeof(IRef) == sizeof(void*) * 2; — два указателя: this и function table.
CS>Т.е. по размеру один указатель на интерфейс эквивалентен member function pointer в C++ CS>с чем уже все смирились
А мне сдается, что нефига тут выпендриваться, а надо просто сделать удобный механизм для автоматического построения массива указателей на функции в каждом экземпляре интерфейса. Тем более, что на современных процах косвенный вызов работает так же быстро, как и прямой. А вот виртуальный (двойная косвенность) сбивает весь конвейер и вряд ли они когда либо смогут "предсказывать наперед" такие вещи. Года 3 назад мне пришлось вручную на C++ имплементировать косвенные вызовы заместо штатного механизма наследования. Задача была тяжелая, DNA Contig Assembly, и работало это все на DEC-Alpha. За счет устранения одного уровня косвенности производительность всей процедуры выросла процентов на 30.
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Здравствуйте, VladD2, Вы писали:
VD>Здорово (я не шучу). Это действительно можно было бы использовать для реализации идеи ограничений (констрэйнов) для параметов шаблонов С++ и тем самым хоть немного сняло бы сложность этого языка. Но... но рантайм полиморфизм через такой мехазнизв вроде как не возможен, а это резко усложнит ОО-дизайн и в итоге может привести к проблемам.
Динамический полиморфизм — это принципиально другой механизм и он уже не требует какого-то глобального пересмотра.
CS>>Я считаю что механизм полезен и окажет свое воздействие на С++.
VD>А вот вот в это я уже совсем не верю. С++ похоже уже будет развиваться только в сторону усложения. К тому же когда появится новый стандарт никому не ясно.
О! Вот это тот редкий случай, когда я с Владом полностью согласен. Но этот случай подпадает под категорию "увы". Нужна серьезная ревизия C++, слишком много в нем накопилось синтаксической и семантической энтропии, но увы, это вряд ли осуществимо на практике.
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, c-smile, Вы писали:
CS>>это фактически образование (compile time) таблицы method references — (this,funcptr) CS>>Соответсвенно вызов такого "виртуального" метода — это вызов обычной невиртуальной функции.
VD>Здорово (я не шучу). Это действительно можно было бы использовать для реализации идеи ограничений (констрэйнов) для параметов шаблонов С++ и тем самым хоть немного сняло бы сложность этого языка. Но... но рантайм полиморфизм через такой мехазнизв вроде как не возможен, а это резко усложнит ОО-дизайн и в итоге может привести к проблемам.
Угу, мне тоже понравилось. Не часто принципиальные идеи появляются.
Про рантайм: так как interface reference (a la Heron) это
пара {this, function table pointer} то на них красиво делаются
delegates (closures) например.
interface reference это как бы мост меж двух миров templates (static polymorph) и virtual (dynamic polymorph).
CS>>Я считаю что механизм полезен и окажет свое воздействие на С++.
VD>А вот вот в это я уже совсем не верю. С++ похоже уже будет развиваться только в сторону усложения. К тому же когда появится новый стандарт никому не ясно.
Есть такое дело со стандартами. И это наверное разумно. Не знаю.
AndrewVK,
> ПК> Оптимизация была сделана ранее: примитивные типы отделили от остальных, хотя на логическом уровне оставили их наследниками Object. Вот это и было оптимизацией. Боксинг — следствие принятой (для оптимизации) модели.
> Паша, зуб даю, генезис боксинга совершенно иной. Не общий корень привел к боксингу, а наоборот, наличие автобоксинга позволило на логическом уровне ввести общий корень.
А зачем изначально по-твоему было введено разделение на reverence- и value- типы? Скажем, в том же SmallTalk, тоже объектно-ориентированном языке, такого разделения нет. Там все типы — наследники Object.
>>> К примеру держишь ты в памяти строку из БД. А там и int, и float, и string, и byte[]. И хранить это нужно в одной коллекции. Вот тут тебе и придется либо боксить, либо приводить все к void*.
> ПК> Верно. Но есть и другие случаи полиморфной работы с объектами разных типов, где можно было бы обойтись без боксинга.
> Например?
Например, передать ссылку на базовый интерфейс в функцию, чтобы она через этот интерфейс данный объект изменила.
Posted via RSDN NNTP Server 1.9
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, McSeem2, Вы писали:
MS>... Нужна серьезная ревизия C++, слишком много в нем накопилось синтаксической и семантической энтропии, но увы, это вряд ли осуществимо на практике.
Ну должно же быть хоть что-то постоянное в этом мире
А то что слишком часто нам приходится петь песню про "sic transit gloria mundi" и компонентные технологии ...
... все, все, молчу ...
Ниччо, еще пара тройка Александреску и комитет шо хош утвердит лиш бы не смотреть на сие безобразие.
Здравствуйте, c-smile, Вы писали:
CS>А то что слишком часто нам приходится петь песню про "sic transit gloria mundi" и компонентные технологии ... CS>... все, все, молчу ...
По поводу "компонентных технологий" противоречие заключается в том, что современный C++ давно перерос парадигму о раздельной компиляции. Не говоря даже о шаблонах, динамический полиморфизм в эту парадигму уже не вписывается. Помню была десериализация, автоматически создающая нужные классы из потока через хитро организованную фабрику классов (по типу MFC). Так там самая большая засада была в том, что для всех классов надо было объявлять некие фиктивные объекты, чтобы линкер их подцепил, иначе заместо объекта будет создана пустышка, которая ни на что не годится.
CS>Ниччо, еще пара тройка Александреску и комитет шо хош утвердит лиш бы не смотреть на сие безобразие.
Ну да, еще Занавеску с Позаранку. Да, нужны, нужны доблестные братья румыны в комитете
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.