Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Как и макросы, шаблоны были призваны заменить собой copy-paste.
Ну, то есть дженерики надо понимать copy-paste собой не заменяют?
ПК> В отличие от generics,
Точно... не заменяют. Ну, давай доказывай.
ПК>они с этой задачей вполне в состоянии справиться.
Ну, ну... Примеры в студию.
ПК> И как оказалось впоследствии, и еще с некоторыми, хотя уже далеко не с такой же элегантностью
Не, Пашь, оказалось, что их макросная суть настолько макросная, что нетрудно втиснуть в средство, казалось бы, предназначенное только для обобщенного программирования еще и кодогенерацию.
>> Генерики полностью свободны от недостатков шаблонов, поскольку принципиально runtime. Но ведь они и не дают ничего существенного. Как было убедительно показано, они — всего лишь автоматизация dynamic cast.
ПК>+1
Осталось только доказать провату своих слов.
А пока я вижу ничем не обоснованные утверждения.
... << RSDN@Home 1.1.4 beta 3 rev. 279>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Нельзя использовать все возможности языка (того же C# в данном случае).
Ой ли?
ПК> Например, использовать перегруженные операторы,
Перегруженные тут причем?
Операторы? Ну, это как сказать. Вот так напрямую может и нельзя. А если абстарагировать, то вполне можно. Вот, например, обобщенное (гы-гы) сумирование:
using System;
using System.Collections.Generic;
class Program
{
delegate T Adder<T>(T x, T y);
static T Sum<T>(Adder<T> adder, IEnumerable<T> list)
{
return Sum<T>(adder, list, default(T));
}
static T Sum<T>(Adder<T> adder, IEnumerable<T> list, T init)
{
T value = default(T);
foreach (T elem in list)
value = adder(value, elem);
return value;
}
// Реализация абстрактных операций для целых и временных
// отрезков. Для строк ничего писать не нужно, так как можно воспользоваться
// функцией string.Concat. Заметь! Статической. :)static int IntAdd(int x, int y) { return x + y; }
static TimeSpan TimeSpanAdd(TimeSpan x, TimeSpan y) { return x + y; }
static void Main()
{
// Сумируем целые.int intValue = Sum<int>(IntAdd, new int[] { 1, 3, 5, 7, 8, 9 });
Console.WriteLine("intValue is " + intValue);
// Сумируем временные промежутки.
TimeSpan timeSpanValue = Sum<TimeSpan>(
TimeSpanAdd,
new TimeSpan[]
{
new TimeSpan(10, 0, 0), new TimeSpan(10000),
new TimeSpan(1, 12, 10), new TimeSpan(20000)
});
Console.WriteLine("timeSpanValue is " + timeSpanValue);
// Сумируем строки. Кстати, функция уже есть, так что писать ее не нужно.string strValue = Sum<string>(
string.Concat,
new string[] { "the ", "power ", "of ", "generic ", "programing! :)" }
);
Console.WriteLine("strValue is " + strValue);
}
}
ПК> статические методы,
А сверху то я какие передаю? Или мне вызвать что ли нельзя? Дык и это можно.
ПК> конструкторы с аргументами.
Как если их тоже обощить? Ну, делаем делегат:
delegate T ClassMethod<T, X>(int i, string s, X x);
и вперед с песней.
ПК> Последнее ограничение, например, не позволяет сделать шаблон фабрики. Первое — даже простейший шаблон accumulate.
О как? А я сверху не то же самое сотварил? Нет?
Одна подсказка. Для фабрик классов в дотнете рулят грибы Сарумяна и танковые клинья в виде все тех же обобщенных интерфейсов и делегатов.
В общем, то что ты считашь недоработками или недостаткаи есть резултат отличной работы дизайнеров языка кторым удалось впихнуть в рамки простого языка концепцию обобщенного прграммирования. При этом они это сделали очень задорово! Они не пожертвовали компонентными свойствами языка (и фрэмворка). Решили массу проблем. И самое главноее, они умудрились оставить язык простым!
Если ребята из команд "CLR performance team" и Феникса как следует напрягуться и сделают достойный оптимизирующий прекомпилятор и джит, то мы получим бескомпромисную и чртовски удобную систему разработи.
Остается только метапрограммирование. Ну, что же... эту проблему я думаю тоже рано или поздно решат. Возможно ни без моей помощи.
А от плюсов мня все больше и больше ташнит. Когда-то это был мой любимый язык. Он даже стал круче с тех пор как я забил на него. Но писать на нем не тянет. А воспоминания о нем далеко не радужные.
Питоны и Руби по своему красивы и уж точно достойны внимания. Но то что код написанный на них будет стольк же надежен и производителен лично лично у меня вызвает слишком большие сомнения. Да и не нравятся мне, откровенно говоря, нетипизированные языки.
... << RSDN@Home 1.1.4 beta 3 rev. 279>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Павел Кузнецов, Вы писали:
>> Щас снова скажу крамолу (вах, боюс-боюс). >> Шаблоны по своей сути — это макросы, какими бы умными "метапрограммированиями" их ни обзывали.
ПК>(Ну и гаразд же ты терминами крутить) собственно, в этом их сила. Как и макросы, шаблоны были призваны заменить собой copy-paste. В отличие от generics, они с этой задачей вполне в состоянии справиться.
Честно признаюсь, я в свое время не мог въехать шаблоны, пока не представил их именно в виде макросов по своей сущности. Тогда все сразу встало на свои места. Для меня основная сила шаблонов — в возможности параметризовать алгоритмы не только интерфейсами, но и базовыми типами и целочисленными константами. Именно это позволяет заменить copy-paste.
Производительность при динамической параметризации (переменными) сразу падает в несколько раз — на любом языке, хоть на ассемблере. Тут уж ничего не поделаешь. А в C#-генериках параметризовать константами нельзя. Единственный выход для сохранения производительности — copy/paste. В минимальном варианте получаем:
2 варианта ValueT — uint8, uint16,
4 варианта Order
3 варианта BaseShift для случая uint16 (12, 14, 16)
Итого 2*4 + 2*4*3 = 32 варианта одного и того же кода в виде банального Copy/Paste.
На голом Си это можно хотя-бы дефайнами сделать (тяжело, некрасиво, но можно). Ни на Java, ни на C#, ни на Фортнане задача не решается в принципе.
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
VladD2,
> Операторы? Ну, это как сказать. Вот так напрямую может и нельзя.
Именно о "напрямую" и идет речь.
> А если абстарагировать, то вполне можно. Вот, например, обобщенное (гы-гы) сумирование: >
> static int IntAdd(int x, int y) { return x + y; }
> static TimeSpan TimeSpanAdd(TimeSpan x, TimeSpan y) { return x + y; }
>
Теперь, пожалуйста, сделай generic вариант вот этих вот двух функций, чтоб не нужно было делать copy-paste для каждого нового типа. Что, не получается? То-то. Об этом и речь. Вот вариант в виде шаблона:
template<class T>
static T Add(T x, T y) { return x + y; }
> ПК> конструкторы с аргументами. > > Как если их тоже обощить? Ну, делаем делегат: >
> delegate T ClassMethod<T, X>(int i, string s, X x);
>
> и вперед с песней.
Ага, с песней. Для каждого типа.
> ПК> Последнее ограничение, например, не позволяет сделать шаблон фабрики. Первое — даже простейший шаблон accumulate. > > О как? А я сверху не то же самое сотварил? Нет?
Нет, ты сделал второй вариант. Чаще используется первый. Первый ты сделать на C# не сможешь из-за ограничений generics.
> В общем, то что ты считашь недоработками или недостаткаи есть резултат отличной работы дизайнеров языка кторым удалось впихнуть в рамки простого языка концепцию обобщенного прграммирования.
"Пока наши корабли бороздят просторы космоса". Может, оно и "результат отличной работы дизайнеров", но вот простую проблему избавления от copy-paste так и не решает...
Posted via RSDN NNTP Server 1.9
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, VladD2, Вы писали:
ПК>> Как и макросы, шаблоны были призваны заменить собой copy-paste.
VD> Ну, то есть дженерики надо понимать copy-paste собой не заменяют?
VladD2,
> > ПК> сформулируем просто: в шаблонах C++ можно использовать все возможности языка C++, в C# generics все возможности языка C# использовать нельзя. > > Да, Пашь, давать прямые форулировки чревато. Вот превое утверждение и сразу ошибка. То-то я гляжу ты все других на утверждения подбиваешь.
Т.е. непосредственно в generics можно вызвать статическую функцию для объекта класса, заданного generic параметром, или можно непосредственно вызвать операторы + — / *, или можно создать такой объект непосредственно в generic функции, если конструктор объекта требует аргументов? Ну-ну...
> ПК> Т.е. часть алгоритмов, которые можно на C# написать, обобщить до generics не получится. С шаблонами C++ таких проблем нет. > > В дженериках нельзя вызывать операторы и конструкторы с параметрами. Обе проблемы решаются с помощью дженерик-делегатов или дженерик-интерфейсаов.
Ага, с помощью copy-paste. Спасибо, не надо.
> В общем, приводи мне недженерик код на Шарпе и я тебе перепишу его на дженериках.
VladD2,
> У самого вместо аргументов докапывание к отдельным ошибкам аппонента не имеющим отношения к делу.
Имеющим самое непосредственное: от определения того, что является метапрограммированием, а что нет, напрямую зависит верность изначального тезиса о том, что отличия generics C# от шаблонов C++ сводятся к поддержке метапрограммирования.
> Давай-ка лучше ты сам поищешь доказательства своим утверждениям. Попытайся найти хотя бы один случай обобщенного программирования не реализуемый на дженериках но реализуемый на шаблонах.
> Случаи параметризации классов значениями тоже не берем, так как это уже случай приципиально не имеющий отношения к обобщенному программированию и кроме как для метапрограммирования особых приемуществ не дает (а вот понимание усложняет очень даже).
Принципиально или непринципиально, но это еще одно ограничение на использование обобщенного программирования.
> ПК> В данном случае я склонен согласиться с Брюсом Эккелем: generics aren't. > > Ты случаем не обратил внимания на две мелочи? Нет? Такие незаметнинькие... > 1. Он говорит о Яве. А в яве дженерики реализованы с серьезными ограничениями.
Читай внимательнее. Он говорит и о C#:
But in Java (and apparently C#), you can't seem to say "any type."
C# also doesn't support latent typing, and although it has a better generics model than Java (since they went ahead and changed the underlying IL so that, for example, a static field in a class will be different between class and class). So if you want latent typing you'll have to use C++ or D (or Python, Smalltalk, Ruby, etc.).
> 2. Они забыл разобраться в дэенериках.
Да уж, конечно, кроме тебя никто эту сложную вещь не понял.
> Мне вообще-то казалось, что сам факт того, что ты и сам додумался как их использовать должен был уберечь тебя от ссылки на стольк некомпетентные источники.
В результате своих экспериментов я и пришел к более-менее тем же выводам, что и Брюс Эккель.
Posted via RSDN NNTP Server 1.9
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, VladD2, Вы писали:
VD>А от плюсов мня все больше и больше ташнит. Когда-то это был мой любимый язык. Он даже стал круче с тех пор как я забил на него. Но писать на нем не тянет. А воспоминания о нем далеко не радужные.
То есть, был любимый язык, а теперь — тошнит? Это бывает. Подозреваю, что виноват не C++, а наикривейшие программы на нем, с которыми тебе приходилось иметь дело. Это такой психологический феномен — сексуальные неудачи юности могут обобщиться и развиться в различные фобиии и девиации. Точно так же, неудачный опыт с неким конкретным кодом на C++ в твоем сознании трансформировался в резкую неприязнь всего языка. Я язык-то здесь и не причем. Но вообще-то, правильно — C++ таит в себе очень мощную психологическую нагрузку — не всякий выдержит. Не для слабаков он.
А вот от чего лично меня тошнит — так это от форм-дизайнера. Более тупой, грязной и тошнотворной работы и представить себе сложно. Я считал, что хуже ручной верстки форм на HTML ничего и представить себе нельзя. Однако есть нечто гораздо хуже — называется дизайнер форм.
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Здравствуйте, Павел Кузнецов, Вы писали:
>> Операторы? Ну, это как сказать. Вот так напрямую может и нельзя.
ПК>Именно о "напрямую" и идет речь.
Я не понял. Тебя интересуют качественные возможности или фишки? Другими словами тебе фишечки нужны или ехать?
То ты тут пафосно заявляешь, что дженерики это замена приведенимя тиов, то начинаешь докапываться до совершенно не принципиальных вещей.
ПК>Теперь, пожалуйста, сделай generic вариант вот этих вот двух функций, чтоб не нужно было делать copy-paste для каждого нового типа. Что, не получается? То-то. Об этом и речь. Вот вариант в виде шаблона: ПК>
ПК>template<class T>
ПК>static T Add(T x, T y) { return x + y; }
ПК>
А у тебя получится? Если тип новый, то и методы у него нужно писать новые. Вот и пиши методы, а уже их вызывай из операторов. В общем, явно попытка поиска ведьм. Признайся что был не прав и не прейдется аргументы из пальца высасывать. Даже смешно ейбогу.
Ну, да ради искуства... напишу тебе универсальную функцию :
static Adder<T> GetAdditionOperator<T>()
{
return (Adder<T>)Delegate.CreateDelegate(
typeof(Adder<T>), typeof(T), "op_Addition");
}
...
TimeSpan timeSpanValue = Accumulate<TimeSpan>(
GetAdditionOperator<TimeSpan>(),
new TimeSpan[]
{
new TimeSpan(10, 0, 0), new TimeSpan(10000),
new TimeSpan(1, 12, 10), new TimeSpan(20000)
});
Console.WriteLine("timeSpanValue is " + timeSpanValue);
На жлабэйские операторы и вовсе доступны в виде методов.
ПК>Ага, с песней. Для каждого типа.
О, блин, проблема! Ты еще не забыл, что это можно просто по месту делать? Анонимные методы еще ведь никто не отменял:
Xxx(delegate(int i) { return new Yyy(i) });
Да и это ты уж совсем из пальца проблемы высасывашь. На практике такие изыки встречаются крайне редко. А фабрики классов обычно делаются на базе активатора, так как в отличии от плюсов все компоненты и любой класс можно создать динамически. С точки зрения фабрики классов намного выгоднее прописать все что нужно в файле настроек и создавать классы по этим описаниям. Например, плагины делаются на раз. Даже КОМ отдыхает.
ПК>Нет, ты сделал второй вариант. Чаще используется первый. Первый ты сделать на C# не сможешь из-за ограничений generics.
Опять высасываем проблему из пальца. Во-первых, смогу. Примерную реализацию я уже показал. А во-вторых, никому не помешает если будет передаваться метод. Функционально код одинаков и даже более абстрактен.
Вообще забавно само желание выискать проблему чтобы обяснить себе почему я не люлю ХХХ. Причем как всегда закапыванием в какие-то далекие от основного вопроса пытаемся уйти от ответа на главный вопрос. Ты еще не забыл, что я тут в основном против твоего заялления о бесполезности дженериков спорю
?
>> В общем, то что ты считашь недоработками или недостаткаи есть резултат отличной работы дизайнеров языка кторым удалось впихнуть в рамки простого языка концепцию обобщенного прграммирования.
ПК>"Пока наши корабли бороздят просторы космоса". Может, оно и "результат отличной работы дизайнеров", но вот простую проблему избавления от copy-paste так и не решает...
Я где-то сдублировал код? Или выдавать желаемое за действительное начинает входить в привычку? Как в прочем и желание найти проблему даже там где ее нет. В примере дублируются только строчки "x + y". И понятно почему. Дженерики не макросы. Они не могут работать текстуально. Операция обязана быть абстрактной. Для абстрагирования есть немало методов.
Не... я был бы только за если бы появились констрэйны типа "+" или "-". Но и без них особых проблем нет. Концепция полна и не противоричива. При чем подталкивает к большему абстрагированию и продумыванию интерфейса. Учитывая на то что язык и среда вообще подталкивают к ООП проблем не возникает. Типы обычно реализуют нужные интерфейсы которые спокойно можно задействовать в обощенном коде.
В общем, опять притягивания за уши. Только что были глобальные заявления про ущербность. Теперь вот откровенй ... про копипэст. Далее, думаю, аргументы будут еще более мелочными и не относящимися к делу.
Ну, а по факту. По факут примера демонстрирующего невозможность реализации чего-то обобщенного нет. Есть только мелочные придирки в основном сводящиеся к тому, что все не так как в С++.
Вот к С++ претензий хоть отбавляй. Попробуй ради хохмы передать ссылку на метод по сети. Получишь гору фрэймворков вроде КОМ или КОРБА и море геморроя.
и бульше не повторять эти заблуждения. Или все же предоставить пример обобщенной задачи, причем без ужимок и высасываний из пальца, который будет нельзя реализовать сдредствами дженериков дотнета. Ну, и закрыть на этом тему.
... << RSDN@Home 1.1.4 beta 3 rev. 279>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Т.е. непосредственно в generics можно вызвать статическую функцию для объекта класса, заданного generic параметром, или можно непосредственно вызвать операторы + — / *, или можно создать такой объект непосредственно в generic функции, если конструктор объекта требует аргументов? Ну-ну...
А что есть разница между посредственной или непосредственной? Факт в том, что можно. И довольно просто.
А вот классификация дженериков как средство борьбы с приведением типов в лучшем случае заблуждение.
>> В дженериках нельзя вызывать операторы и конструкторы с параметрами. Обе проблемы решаются с помощью дженерик-делегатов или дженерик-интерфейсаов.
ПК>Ага, с помощью copy-paste. Спасибо, не надо.
Где? У тебя уже копипэст просто мерешится везде. Копипэст скорее будет вызван соображениями производительности нежели проблемами с дженериками.
В общем, ты опять подменяешь тему чтобы уйти от необходимости признать очевидное.
>> В общем, приводи мне недженерик код на Шарпе и я тебе перепишу его на дженериках.
ПК>http://rsdn.ru/forum/?mid=1015985
VladD2,
> ПК> Т.е. непосредственно в generics можно вызвать статическую функцию для объекта класса, заданного generic параметром, или можно непосредственно вызвать операторы + — / *, или можно создать такой объект непосредственно в generic функции, если конструктор объекта требует аргументов? Ну-ну... > > А что есть разница между посредственной или непосредственной?
Да, естественно. Опосредованно шаблоны можно тоже из DLL экспортировать.
> А вот классификация дженериков как средство борьбы с приведением типов в лучшем случае заблуждение.
Пока так и не было продемонстрировано, что позволяют сделать generics, чего нельзя сделать обычным классом, если не принимать во внимание необходимость приведений типов во втором случае.
>>> В общем, приводи мне недженерик код на Шарпе и я тебе перепишу его на дженериках. > > ПК>http://rsdn.ru/forum/?mid=1015985
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Имеющим самое непосредственное: от определения того, что является метапрограммированием, а что нет, напрямую зависит верность изначального тезиса о том, что отличия generics C# от шаблонов C++ сводятся к поддержке метапрограммирования.
Нет уж. Не имеющих. Ты утверждаешь:
1. Дженерики всего лишь средство избавления от приведений типов.
2. Дженерики неполноценное средство обобщенного программирования.
То что итераторы не имеют отношения к метапрограммированию никак не касается этих утверждений. Так что уципился ты за них только потму-что больше не за что. И выглядит это очень некрасиво.
>> Давай-ка лучше ты сам поищешь доказательства своим утверждениям. Попытайся найти хотя бы один случай обобщенного программирования не реализуемый на дженериках но реализуемый на шаблонах.
ПК>http://rsdn.ru/forum/?mid=1015985
Зачем столько раз давать ссылку на то где тебе уже дали ответ? Мой код не решает проблемы? Он не обобщен?
Ну, вот и подищи что-нибудь по новее. И не нужно давать ссылку на мое же сообщение. Это уже не смешно.
>> Случаи параметризации классов значениями тоже не берем, так как это уже случай приципиально не имеющий отношения к обобщенному программированию и кроме как для метапрограммирования особых приемуществ не дает (а вот понимание усложняет очень даже).
ПК>Принципиально или непринципиально, но это еще одно ограничение на использование обобщенного программирования.
Это вообще не относится к обобщенному программированию. Параметризация константами (если о ней речь) может быть полезна только при генерации кода (метапрограммировании).
>> 1. Он говорит о Яве. А в яве дженерики реализованы с серьезными ограничениями.
ПК>Читай внимательнее. Он говорит и о C#:
Я читаю внимательно. Упоминаний Шарпа в статье два. Оба в суе и бездоказательно.
ПК>
But in Java (and apparently C#), you can't seem to say "any type."
apparently нареч.
1) очевидно, несомненно Syn: evidently
2) вероятно, видимо, по-видимому, предположительно Syn: to all appearance
Как ты думашь, автор применил слово в первом или втором значении? Если в первом, но от воинствующий ламер и слушать его просто глупо. Если во вотором, то возможно этим он хотел сказать, что просто не разбирался в дотнете?
Мне кажется я дал доволнь много примеров, что бы понять, что все слова о бессмысленности или ущербности дженериков просто бред сивой кобылы.
ПК>
C# also doesn't support latent typing, and although it has a better generics model than Java (since they went ahead and changed the underlying IL so that, for example, a static field in a class will be different between class and class). So if you want latent typing you'll have to use C++ or D (or Python, Smalltalk, Ruby, etc.).
И что ты тут усмотрел? То что в Шарпе дженерики лучше? Ды я и не спорю. Или то что макросы или интерпретация лучше чем компилируемые компоненты? Да арзные подходы. Но обоснования, что один хуже, а другой лучше я что-то не увидел.
>> 2. Они забыл разобраться в дэенериках.
ПК>Да уж, конечно, кроме тебя никто эту сложную вещь не понял.
Зачем же передергивать. Вешь не особо сложная. Вот только наблюдается явная тенденция к тому, что некоторые привыкшие к одному подходу воспринимают в штыки все новое и даже не пытаются вникнуть и оценить. Товаришь явно несет чушь. Стало быть или неразобрался, или развивает целенаправленную демагогию. Я склоняюсь к первому.
>> Мне вообще-то казалось, что сам факт того, что ты и сам додумался как их использовать должен был уберечь тебя от ссылки на стольк некомпетентные источники.
ПК>В результате своих экспериментов я и пришел к более-менее тем же выводам, что и Брюс Эккель.
Странно. А код получился хотя и кривой, но более мнее обобщенный. Не уж то избавление от привдения типов дает стольк мощьный эффект? А может тогда ну, их эти слова про бобщенное программирование? Может все что нужно это как раз избавление от приведения типов.
В общем, твои ужимки уже столь откровенны, что разговор становится не интересным. Ты начал называть черно белым и отрицать очевидные вещи. На это думаю, нужно и завершить. Люди с головой все поймут, а ты все равно не признаешь своих заблуждений.
... << RSDN@Home 1.1.4 beta 3 rev. 279>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, McSeem2, Вы писали:
MS>Подозреваю, что виноват не C++, а наикривейшие программы на нем, с которыми тебе приходилось иметь дело.
Видимо по собственному опыту...
MS> Это такой психологический феномен — сексуальные неудачи юности могут обобщиться и развиться в различные фобиии и девиации.
Это когда коленки болят? Поведай не опытным.
MS> Точно так же, неудачный опыт с неким конкретным кодом на C++ в твоем сознании трансформировался в резкую неприязнь всего языка.
MS> Я язык-то здесь и не причем. Но вообще-то, правильно — C++ таит в себе очень мощную психологическую нагрузку — не всякий выдержит. Не для слабаков он.
Это заявление я так понимаю тоже сделано на базе личного нервного срыва?
MS>А вот от чего лично меня тошнит — так это от форм-дизайнера. Более тупой, грязной и тошнотворной работы и представить себе сложно. Я считал, что хуже ручной верстки форм на HTML ничего и представить себе нельзя. Однако есть нечто гораздо хуже — называется дизайнер форм.
Я конечно рад за то что твоей жизненный опыт расширелся столь интеллектуальной работай. Но так и не понял что ты хотел сказать то? Ты как-нибудь попробуй без подтекста высказаться. А то мой ум еще пока не отточен филигранной тренировкой в формдизайнере и ручном рисовании ХМЛЯ.
ЗЫ
Ты знаешь, мне вот всегда прикалывает когда ты начинашь общаться в стиле "гуру". Типа "ты видел прямой код...". Я конечно рад, что ты успел попрограммировать на фортране разные устройства для выпиливания лобзиком по бумаге, но это еше не дает тебе право на снисходительный тон.
Ты вроде не сильно старше меня. И знаешь явно не больше. И вес пока тут не имешь такой чтобы снисходительно разговаривать. Так что давай ты не будеш тут меня "лечить". А то мы так и будем упражняться в острословии и изощренности уколов.
... << RSDN@Home 1.1.4 beta 3 rev. 279>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
VladD2,
> ПК>Именно о "напрямую" и идет речь. > > Я не понял. Тебя интересуют качественные возможности или фишки? Другими словами тебе фишечки нужны или ехать?
Нужно ехать: нужно, чтобы клиент не копипэйстил x + y в своем коде, а это было сделано один раз в шаблоне.
> ПК>Теперь, пожалуйста, сделай generic вариант вот этих вот двух функций, чтоб не нужно было делать copy-paste для каждого нового типа. Что, не получается? То-то. Об этом и речь. Вот вариант в виде шаблона: > ПК>
> ПК>template<class T>
> ПК>static T Add(T x, T y) { return x + y; }
> ПК>
> А у тебя получится?
С generics? Нет, и у меня не получится. Поэтому и говорю, что они этого не позволяют.
> Если тип новый, то и методы у него нужно писать новые. Вот и пиши методы, а уже их вызывай из операторов.
Не годится. Класс уже написан, не нами. Например, это int.
> Ну, да ради искуства... напишу тебе универсальную функцию : >
> static Adder<T> GetAdditionOperator<T>()
> {
> return (Adder<T>)Delegate.CreateDelegate(
> typeof(Adder<T>), typeof(T), "op_Addition");
> }
> ...
> TimeSpan timeSpanValue = Accumulate<TimeSpan>(
> GetAdditionOperator<TimeSpan>(),
> new TimeSpan[]
> {
> new TimeSpan(10, 0, 0), new TimeSpan(10000),
> new TimeSpan(1, 12, 10), new TimeSpan(20000)
> });
> Console.WriteLine("timeSpanValue is " + timeSpanValue);
>
> На жлабэйские операторы и вовсе доступны в виде методов.
Ерунда. Просто место copy-paste изменилось. Где само x + y, там и copy-paste.
> ПК>Ага, с песней. Для каждого типа. > > О, блин, проблема! Ты еще не забыл, что это можно просто по месту делать? Анонимные методы еще ведь никто не отменял: >
> Xxx(delegate(int i) { return new Yyy(i) });
>
Это означает, что клиенты моего "generic" класса будут в своем коде делать copy-paste для каждого нового типа, с которым они мой "generic" класс захотят использовать. Или, если "по месту", то не для каждого типа, а в месте каждого вызова.
> Да и это ты уж совсем из пальца проблемы высасывашь. На практике такие изыки встречаются крайне редко. А фабрики классов обычно делаются на базе активатора, так как в отличии от плюсов все компоненты и любой класс можно создать динамически. С точки зрения фабрики классов намного выгоднее прописать все что нужно в файле настроек и создавать классы по этим описаниям.
Ага. Например, создание таким макаром результата функции получения ряда матрицы... Представляю
> Ты еще не забыл, что я тут в основном против твоего заялления о бесполезности дженериков спорю
Не о бесполезности, а об отсутствии у них достоинств шаблонов.
> Я где-то сдублировал код? Или выдавать желаемое за действительное начинает входить в привычку? Как в прочем и желание найти проблему даже там где ее нет. В примере дублируются только строчки "x + y". И понятно почему. Дженерики не макросы. <...>
Я отлично понимаю, почему именно так происходит. Тем не менее copy-paste остается. И чем сложнее будет generic функция (чем больше ей будет нужно операторов), тем больше этого дублирования будет.
> Не... я был бы только за если бы появились констрэйны типа "+" или "-". Но и без них особых проблем нет.
Это потому что ты математику на generics писать не пытался.
> Вот к С++ претензий хоть отбавляй. Попробуй ради хохмы передать ссылку на метод по сети. Получишь гору фрэймворков вроде КОМ или КОРБА и море геморроя.
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Да, естественно. Опосредованно шаблоны можно тоже из DLL экспортировать.
Да ну? А можно пример посмотреть?
ПК>Пока так и не было продемонстрировано, что позволяют сделать generics, чего нельзя сделать обычным классом, если не принимать во внимание необходимость приведений типов во втором случае.
Дык написать обобщенный алгоритм или контейнер. Или ты о том, что и обобщенное программирование и динамический полиморфизм суть проявления полиморфизма и с филосовской точки зрения обладают равными возможностями? Ну, так тогда и шаблоны не более чем средство борьбы с приведениями типов. Я на С++ писал еше когда компиляторы не знали что такое шаблоны. Вроде возможностей хватало. Не так удобно конечно, но жить можно. И как не странно копипэста тоже практически небыло. Да и на С. Не поверишь, но и на нем можно без копипэстов...
В общем, это несерьезно. Очевидно, что дженерики — это полноценное средство обобщенного программирования. Примеров которые невозможно реализовать ты так и не привел. Признаваться что не прав тоже не хочешь.
ПК>Ошибся. Подразумевалось: http://rsdn.ru/Forum/Message.aspx?mid=1016014&only=1
Вот это уже пример метапрограммирования. На макросах, кстати, делается еще проще. Тут уже на уровен типов ничего не сделашь. Хотя твое случай решается еще проще. Массив байтов и вперед. А уж абстрагироваться через методы.
MS>Производительность при динамической параметризации (переменными) сразу падает в несколько раз — на любом языке, хоть на ассемблере.
Дык, не ты ли говорил, что если что мы по бырому генератор кода сварганим? Ну, и вообще-то умный джит в данном случае мог бы обеспечить оптимизацию. Все же инварианты можно было бы вывести за пределы циклов.
MS> Тут уж ничего не поделаешь. А в C#-генериках параметризовать константами нельзя.
На то они и дженерики. Иначе пршлось бы код генерировать. Тут уже мсил был бы разный.
MS> Единственный выход для сохранения производительности — copy/paste. В минимальном варианте получаем: MS>2 варианта ValueT — uint8, uint16, MS>4 варианта Order MS>3 варианта BaseShift для случая uint16 (12, 14, 16)
MS>Итого 2*4 + 2*4*3 = 32 варианта одного и того же кода в виде банального Copy/Paste.
Сдается мне, что все несколько проще. Это ты своих тараканов размножаешь.
MS>На голом Си это можно хотя-бы дефайнами сделать (тяжело, некрасиво, но можно). Ни на Java, ни на C#, ни на Фортнане задача не решается в принципе.
О как. А значит препроцессор у нас религия для Явы или Шарпа запрещает использовать?
Возми тот же VC у него есть опция командной строки раскрывающая препроцессор. И будет тебе препроцессор для шарпа. Ну, и геморрой соотвествующий.
А по уму твоя проблема решается кодогенератором. Качаешь R# или КодСмит и через пять минут решение твоей неразрешимой проблемы. Причем чистое, красивое, и легко отлаживаемое.
... << RSDN@Home 1.1.4 beta 3 rev. 279>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Нужно ехать: нужно, чтобы клиент не копипэйстил x + y в своем коде, а это было сделано один раз в шаблоне.
Ну, себя ты уже явно убедил. Столь ужасный копипэст действительно является серьезным основанием чтобы возиться с полумакросными технолгиями, пялиться в найрен не нужные навороты и читать трехметровые сообщения об ошибках.
>> ПК>Теперь, пожалуйста, сделай generic вариант вот этих вот двух функций, чтоб не нужно было делать copy-paste для каждого нового типа. Что, не получается? То-то. Об этом и речь. Вот вариант в виде шаблона: >> ПК>
>> ПК>template<class T>
>> ПК>static T Add(T x, T y) { return x + y; }
>> ПК>
>> А у тебя получится?
ПК>С generics? Нет, и у меня не получится. Поэтому и говорю, что они этого не позволяют.
Зачем? С любым классом. Чтобы у него вот раз и сам по себе появился оператор сложения.
ПК>Не годится. Класс уже написан, не нами. Например, это int.
А если у класса вообще нет оператора сложения? Ой прийдется все же тебе копипэстить. И как ты через себя перешагнешь?
>> Ну, да ради искуства... напишу тебе универсальную функцию : >>
>> static Adder<T> GetAdditionOperator<T>()
>> {
>> return (Adder<T>)Delegate.CreateDelegate(
>> typeof(Adder<T>), typeof(T), "op_Addition");
>> }
>> ...
>> TimeSpan timeSpanValue = Accumulate<TimeSpan>(
>> GetAdditionOperator<TimeSpan>(),
>> new TimeSpan[]
>> {
>> new TimeSpan(10, 0, 0), new TimeSpan(10000),
>> new TimeSpan(1, 12, 10), new TimeSpan(20000)
>> });
>> Console.WriteLine("timeSpanValue is " + timeSpanValue);
>>
>> На жлабэйские операторы и вовсе доступны в виде методов.
ПК>Ерунда. Просто место copy-paste изменилось. Где само x + y, там и copy-paste.
А где "x + y"? Ты код то прочел? Ну, давай с коментариями, чтобы для танкистов:
// Процедура универсального получения делегата метода сложения.
// Если у типа реализован оператор сложения, то он обязательно
// содержит статический метод op_Addition.
// Таким образом мы создаем делегат для этого метода/типа.static Adder<T> GetAdditionOperator<T>()
{
return (Adder<T>)Delegate.CreateDelegate(
typeof(Adder<T>), typeof(T), "op_Addition");
}
...
TimeSpan timeSpanValue = Accumulate<TimeSpan>(
// Применяем универсальный метод. Вместо TimeSpan
// можно подставить любой тип реализующих оператор сложения.
GetAdditionOperator<TimeSpan>(),
new TimeSpan[]
{
new TimeSpan(10, 0, 0), new TimeSpan(10000),
new TimeSpan(1, 12, 10), new TimeSpan(20000)
});
Console.WriteLine("timeSpanValue is " + timeSpanValue);
Так яснее?
ПК>Это означает, что клиенты моего "generic" класса будут в своем коде делать copy-paste для каждого нового типа, с которым они мой "generic" класс захотят использовать. Или, если "по месту", то не для каждого типа, а в месте каждого вызова.
Это означет, что тебе болше придумать нечего. А ничего что ты операторы постоянно копипэстиш? Не думл на счет написания шаблона заменяющего их?
Не неси откровенню чушь. Если тип встречается один раз, то сделашь анонимный метод. Если он встречается часто, то опишешь метод. Если уж ты такой эстет, то возмешь метод описанный выше.
>> Да и это ты уж совсем из пальца проблемы высасывашь. На практике такие изыки встречаются крайне редко. А фабрики классов обычно делаются на базе активатора, так как в отличии от плюсов все компоненты и любой класс можно создать динамически. С точки зрения фабрики классов намного выгоднее прописать все что нужно в файле настроек и создавать классы по этим описаниям.
ПК>Ага. Например, создание таким макаром результата функции получения ряда матрицы... Представляю
Ряда? Хотя пофигу. Почему бы нет?
>> Ты еще не забыл, что я тут в основном против твоего заялления о бесполезности дженериков спорю
?
ПК>Не о бесполезности, а об отсутствии у них достоинств шаблонов.
Недостатков ты хотел скзать? Да пойими ты. Они просто другие. Да, операторы нужно абстрагировать. Но это не та проблема. За то прозрачная передача абстракции через любые границы. Можно даже тип на диск записать и потом считать. Компонентная архитектура при минимуме неудобств. Плсы идут обижаться на КОМ.
ПК>Я отлично понимаю, почему именно так происходит. Тем не менее copy-paste остается. И чем сложнее будет generic функция (чем больше ей будет нужно операторов), тем больше этого дублирования будет.
Блин, ты про абстракцию что-нибудь слышал? Дженерик-делегаты и дженерик-интерфейсы — это такая же абстракция как указатели на функцию или простые интерфейсы. Реализация абстракции тоже вольна состоять из обращения к абстракции. Про декомпозицию тоже надеюсь слышал?
Если правильно проектировать, то нет никакого дублирования кода в при использовании дженериков. Это ты тут из пальца проблемы высасывашь, чтобы не признавать своей не правоты.
ПК>Это потому что ты математику на generics писать не пытался.
А зачем? Она в System.Math валяется. И без всяких дженериков в лучшем виде обходится. Абстрагировать даблы — это уже маразм. В общем, мне лично хватает и System.Math. Появятся серьезные оптимизаторы и можно будет все на дженериках переписать не боясь потерять скорость. Вот только зачем?
>> Вот к С++ претензий хоть отбавляй. Попробуй ради хохмы передать ссылку на метод по сети. Получишь гору фрэймворков вроде КОМ или КОРБА и море геморроя.
ПК>Ерунда. Для этого, если будет нужно, можно и тот же .Net использовать. .Net — платформа, с тем же успехом доступная и из C++.
Не. На МС++ ты передашь тот же дерегат. Максиумут дженерик. А все твои бусты пойдут лесом.
Хотя прием красивый. В следующий раз буду давить на то, что на МСИЛ-ле можно черта лысого сварганить.
ПК>Предлагаю продемонстрировать пример на generics, который нельзя сделать обычным классом, если закрыть глаза на приведение типов.
А на шаблонах без метапрограммирование такое возможно? Что до демагогии спускаться то? Обобщенное программирование и подразумевает статически типизированное программировние на бзе абстрактных типов.
А уж генерация кода не связанная с типами или подключение релизаций — это просто еще одна схожая область автоматизации. В том, что плюсы позволяют делать многое за счет метапрограммных свойств (макросных можно сказать) никто и не спорит. Но без этого и шаблоны делают тоже самое. Да и предназначились они для того же.
... << RSDN@Home 1.1.4 beta 3 rev. 279>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.