Здравствуйте, AndreiF, Вы писали:
AF>Здравствуйте, FR, Вы писали:
FR>>Не решена. Там хардкорно все. А хочется самому задавать эти правила, это и обсуждалось
AF>Иметь такую возмоность — это конечно плюс. Что-то подобное кажется сделано в Хаскелле.
В Хаскелле есть типы Int, Integer, Float, Double (ну и пользовательские, конечно), а есть классы типов (штука похожая на интерфейсы). Наследование происходит на уровне классов типов, а сами типы просто воплощают классы типов, перегружая (при необходимости) их методы.
Есть базовый класс типа Num для всех чисел, в котором определены сложение, вычитание, умножение, кое-что ещё и, в том числе, функция fromInteger с такой сигнатурой типа
fromInteger :: Num a => Integer -> a
Здесь Num a => — это контекст, задающий класс типа Num обобщённой переменной a. Функция принимает Integer, а возвращает переменную типа a.
Целочисленные литералы, вроде 1, 2, 3, в Хаскелле трактуются как применение fromInteger к соответствующей величине типа Integer. Таким образом, 1 :: Num a => a, если словами, то 1 имеет произвольный тип a, ограниченный контекстом (классом типа) Num.
Аналогично 2.5 :: Fractional a => a, то есть 2.5 имеет произвольный тип a, ограниченный классом типа Fractional. (Fractional — наследник Num, поддерживающий деление.)
Теперь про min. Его сигнатура типа
min :: Ord a => a -> a -> a
Класс типа Ord задаёт методы сравнения (больше, меньше и т.д.)
Ну а дальше компилятор выводит наиболее общий допустимый тип выражения применения min к двум своим аргументам
min 1 2.5 :: (Ord a, Fractional a) => a
Вычисление вернёт значение 1.0 (которое имеет класс типа Fractional ). Конечно, само вычисление происходит над конкретными типами. Для разрешения возникающей неоднозначности числовых типов в Хаскелле имеется ключевое слово default (умолчание по умолчанию в данном случае задаёт тип Double.)
По теме обсуждения: без наследования здесь, похоже не обойтись, но, пользуясь классами типов, мы можем не выбирать наследует ли Int Float или наоборот (и то, и другое — плохо), а воплотить для каждого из них правильный набор интерфейсов. А вот уж этих интерфейсов довольно много (см. здесь), и наследуют они друг другу, причём в Хаскелле — множественным образом. Только так можно воплотить весь зверинец чисел, придуманных человеком. Например, комплексные числа не должны поддерживать сравнения
Re[42]: Как скрестить ужа и ежа или статическую и утиные тип
Здравствуйте, alexeiz, Вы писали:
A>В данном конкретном коде контракт гарантируется тем, что параметры напрямую передаются в конструктор.
Какая же это гарантия?
>>А нам требуется соблюдать контракт введенный абстрактной фабрикой.
A>В каком-то приближении и этого можно добиться, если например задать параметры к конструктору класса в самом классе: A>
A>struct Soldier {
A> typedef TYPELIST_2(int, tuple<int, double>)
A> creation_params;
A> Soldier(int);
A> Soldier(tuple<int, double>);
A>};
A>
A>Шаблон, генерирующий фабрику, посмотрит, какие у классов creation_params и создаст соответствующий интерфейс.
Это уже работа ради работы, что есть бред. Весь смысл в автоматическом создании фабрики. А если мне нужно все задавать, то не так уж сложно польностью реализовать абстрактную фабрику в виде класса.
В общем, понято что С++ и Ди что-то могут. Вопрос в гибкости того что они могут. В случае полноценных макросовм мы имеем полный контроль над компилятором и процессом кодогенерации. Мы может выдвать осмысленные ошибки. Вычирать подходящий синтаксис. Использовать библиотеки и внешние источники данных. В общем, мы может почти все!
Подходы же Ди и С++ — это поптыка использовать механизм обобщенного программироания для целей метапрограммирования. Мне кожется это заведомо ущербный подход. Получается запутано, медленно, не функционально и не выразительно.
VD>>Да и есть еще одна проблема. Сечас я ее постараюсь продемонстрировать: VD>>http://rsdn.ru/File/73/Nemerle/Nemerle-MethodHint-ForAbstractFactory.png VD>>Это сркриншот снят из реально работающей интеграции со студией. Мы в реальном времени имеем полное описание фабрики и даже автодополнение при вводе. VD>>Такое точно ни Ди ни С++ 0x недоступно.
A>Доступно. На основе информации получаемой после компиляции. Откомпилировал шаблон фабрики один раз, и студии должна быть доступна полная информация об интерфейсе фабрики. То, что VS не делает этого для C++, не значит, что это недоступно в принципе.
Ты выдаешь желаемое за действительное. В С++ вообще нет возможности скомпилировать шаблоны. В С++ шаблоны не более чем тексовая подстановка (ну, чуть по навороченее, но не суть). Учитывая, что мы вынуждены передавать функции Create тип создаваемого объекта в качестве аргумента типа, то получить что либо компилировнное вообще не представляется возможным. Да и подсунуть мы туда можем что угодно. Компилятор конечно может ругнуться на неверно подсунутый тип в некоторых случаях, но будет это при воплошении этого метада.
Что до интелисенса в С++, то это еще очень долго не будет возможно. Производительность современных процессоров не просто недостаточно. Ее катастрофически нехватает. А оптимизировать там что-то будет очень не прсото. В Ди наверно будет по проще, но и у него будут проблемы с данным примером. А более сложные вещи вообще будут недоступны для этих языков.
В общем, С++ уже 21 год, а для него так и не сделано полноценного автодополенения при вооде. И это при том, что над этим работали самые багатые и креативные фирмы всего мира, плюс многие одаренные одиночки. А для Немерла все это практически есть хотя язык даже не зарелизен. И сделали это не какие-то мега-корпорации, а два программиста с РСДН и два поляка в свободное от работы время. Вот такие пироги с катятами.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[43]: Как скрестить ужа и ежа или статическую и утиные тип
VladD2 wrote: > Что до интелисенса в С++, то это еще очень долго не будет возможно. > Производительность современных процессоров не просто недостаточно. Ее > катастрофически нехватает. А оптимизировать там что-то будет очень не > прсото. В Ди наверно будет по проще, но и у него будут проблемы с данным > примером. А более сложные вещи вообще будут недоступны для этих языков.
Рекомендую посмотреть XRefactory. Автокомплит оно делает почти 100%
надежный, даже с Бустом справляется. Простые рефакторинги там тоже есть.
Posted via RSDN NNTP Server 2.0
Sapienti sat!
Re[18]: Как скрестить ужа и ежа или статическую и утиные тип
VladD2 wrote: > C>А Влад тут говорит, что Mono — это rulez > Можно ссылку? Или ты о каком Владе говоришь?
О тебе, о ком же еще. Кто-то тут же хвалился портабельностью Nemerle.
Вот сделали бы Nemerle для LLVM — было бы круто.
Posted via RSDN NNTP Server 2.0
Sapienti sat!
Re[40]: Как скрестить ужа и ежа или статическую и утиные тип
VD>Согласен, это более гибкий подход чем в С++, но мне кажется ты решил другую задачу. Ты создал обобщенный метод транслирующий вызовы с переменным количеством параметров. Это здорово, но не то что нужно. А нужно сгенерировать набор конкретных методов имеющий вточности такой набор параметров как набор параметров конструкторов. Причем методы должны быть виртуальными. Иначе в уточненной фабрике вызовется конструктор котый не существовал ранее. А это уже не фабрика.
VD>Так что мне по прежнему очень интересно поглядить на полноценную реализацию фабрики класса на Ди. Ну, если кто-то на С++ извернется, то будет вообще супер. Но в это верится еще меньше.
Угу тебе хорошо а я сегодня полдня вместо работы в D копался
В общем держи фабрику, конечно все в статике, но просто.
Теперь убежден что программировать шаблоны в D на порядок проще чем в C++.
import std.stdio;
import std.typetuple;
// фабрикаtemplate absract(Base...)
{
template concrete(Concrete...)
{
template create(T)
{
T args(A...)(A args)
{
const i = IndexOf!(T, Base);
alias Concrete[i] TR;
return new TR(args);
}
}
}
}
// тестовые классы и интерфейсы
// базовые интерфейсы
interface Soldier { char[] info(); };
interface Monster { char[] info(); };
interface SuperMonster { char[] info(); };
// конкретные классыclass SillySoldier : public Soldier {this(int x) {} char[] info() {return"SillySoldier";}};
class SillyMonster : public Monster {char[] info() {return"SillyMonster";}};
class SillySuperMonster : public SuperMonster {char[] info() {return"SillySuperMonster";}};
class BadSoldier : public Soldier {this(int x, int z) {} char[] info() {return"BadSoldier";}};
class BadMonster : public Monster {char[] info() {return"BadMonster";}};
class BadSuperMonster : public SuperMonster {char[] info() {return"BadSuperMonster";}};
// вспомогательная печатьvoid info(T)(T t)
{
writefln(typeid(typeof(t)));
writefln(t.info());
writefln();
}
void main()
{
// абстрактная фабрика
alias absract!(Soldier, Monster) abstract_enemy;
// конкретизации
alias abstract_enemy.concrete!(SillySoldier, SillyMonster) silly_enemy;
alias abstract_enemy.concrete!(BadSoldier, BadMonster) bad_enemy;
// создание конкретных объектов с помощью фабрикиauto x = silly_enemy.create!(Monster).args();
info(x);
auto y = silly_enemy.create!(Soldier).args(1);
info(y);
auto z = bad_enemy.create!(Soldier).args(1, 2);
info(z);
}
Re[18]: Как скрестить ужа и ежа или статическую и утиные тип
VD>А выведение реализаций методов в отдельный cpp-файл дает только возможность обойти дурацкое окграничение С++ на то что нельзя создавать экземпляров еще не определенных типов. Можно только создавать указатели и то для этого тоже требуется предварительная декларациях.
VD>Вот с этим недоразумение и борится вынос разделение класса в С++.
Ну, не только с этим. Вообще-то вынос реализации в отдельные файлы — это наследие C, и изначально сделан скорее для обыкновенного ускорения компиляции — я запросто могу написать всю программу любой сложности в одном файле (либо реализовать всё исключительно через h-файлы c одним-единственным c/cpp), но при минимальных изменениях перекомпилироваться будет всё. А вот реально средством (хоть и примитивным) для создания модульных программ это разбиение стало с появлением ключевого слова static (которое позволяло скрыть внутренние переменные от линкера) — а оно появилось в C ЕМНИП далеко не сразу.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[41]: Как скрестить ужа и ежа или статическую и утиные тип
>> Хотя конечно AndreiF перегибает палку. Небольшой рынок есть у Сембиан с >> кастрированным С++. C>Там уже полный С++ (обычный GCC). Проблемы там были из-за их C>самопального механизма возвратов (найти бы урода, который его придумал...).
Да? Насчёт полного очень интересно — что там поменялось? А то когда я последний раз на него смотрел (на версию 7.0), там не было ни исключений, ни STL, ни RTTI (хотя как раз без последнего прожить-то можно...). И с глобальными переменными были серьёзные проблемы.
А того урода который придумал механизм возвратов... Согласен на 100% что с ним нужно что-то сделать — но не могу придумать достойного наказания. Я даже не могу вспомнить ни одного настолько же неудачного проектного решения.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[24]: Как скрестить ужа и ежа или статическую и утиные тип
C>>Вот-вот. Все сколь-либо сложное пишется на неуправляемых языках. K>А вот это ты фигню сказал. Сколько-нибудь сложное это что? Этот примитивный декодер MP3, состоящий из сдвигов и сложений? Не смеши!
Если лично тебе декодер mp3 кажется примитивным — напиши в порядке развлечения свой. Их всего-то два штуки — фраунгоффер и лама. Потому что написать ещё один — надо иметь очень много знаний, времени и денег.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[28]: Как скрестить ужа и ежа или статическую и утиные тип
>>> C>Ты представь, что у тебя оффисный пакет. >>> Вот и прекрасно. Ну и на чём же проще написать офисный пакет? C>>"Проще" это сюда не относится. Его может проще на интерпретируемом C>>Питоне написать, но если результат не будет нравится пользователям — C>>пакет пошлют "фтопку". АХ>Питон — это еще сравнительно быстро (особенно если Psyco использовать). АХ>Но это уже прошлый век. АХ>Сейчас модно делать офисные пакеты на AJAX (т.е. HTML + JavaScript) :
Мне кажется что принципиальной разницы между Python и JavaScript нет. То есть, оба языка из одной ниши — интерпретируемые языки с duck-typing и т.п.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[40]: Как скрестить ужа и ежа или статическую и утиные тип
Угу автор D взял именно эту идею, я впервые о не читал в книге Вандевурда, в разделе "Мечты"
А так все это идет от Александреску и от его списков типов.
Вообще уже вот эти туплы и static if очень здорово упрощают программирование шаблонов.
A>Ну а пока что задача решается перегрузкой create для всевозможного количества аргументов.
K>>А вот это неправда. Для проигрывателя быдут написан MP3-декодер на неуправляемом языке.
VD>Акстись. Такие вещи сто лет назад в железо зашиты. У меня плеер без какой либо ОС работает. Софт в них нужен исключительно для GUI.
Что-то меня грызут сомнения насчёт полностью аппаратного декодинга MP3. Откуда такое чудо?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[20]: Как скрестить ужа и ежа или статическую и утиные тип
Left2 wrote: > Да? Насчёт полного очень интересно — что там поменялось? А то когда я > последний раз на него смотрел (на версию 7.0), там не было ни > исключений, ни STL, ни RTTI (хотя как раз без последнего прожить-то > можно...). И с глобальными переменными были серьёзные проблемы.
Там все было плохо из-за механизма возвратов. Они, фактически,
дублировали механизм исключений:
CMyCompoundClass* self=new (ELeave) CMyCompoundClass;
CleanupStack::PushL(self); //Повбывав бы
self->ConstructL();
...
Вроде бы в восьмерке это поменяли — стали использовать настоящий EH. С
глобальными переменными, вроде бы, все осталось как и было.
Posted via RSDN NNTP Server 2.0
Sapienti sat!
Re[21]: Как скрестить ужа и ежа или статическую и утиные тип
C>Там все было плохо из-за механизма возвратов. Они, фактически, C>дублировали механизм исключений:
Это я знаю, сенкс. Жуткая гадость.
C>Вроде бы в восьмерке это поменяли — стали использовать настоящий EH. С C>глобальными переменными, вроде бы, все осталось как и было.
Восьмёрка вроде бы толком и не жила — насколько я понял, на 8-ке был всего один телефон. Совеременный Симбиан это вроде как 9-ка. Они там вроде бы много чего поменяли в плане бинарной совместимости, секьюрити и т.п. — но я не нашёл ничего насчёт кардинального изменения API. Ну и опять же — не нашёл никаких упоминаний о том что "STL (Boost, ACE) is now available on new Symbian platform".
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[25]: Как скрестить ужа и ежа или статическую и утиные тип
Здравствуйте, Left2, Вы писали:
L>Если лично тебе декодер mp3 кажется примитивным — напиши в порядке развлечения свой. Их всего-то два штуки — фраунгоффер и лама. Потому что написать ещё один — надо иметь очень много знаний, времени и денег.
Это каких таких знаний нужно иметь? Математику знать нужно? Ну, это тогда к математикам вопрос. На самом деле, там кроме математике очень много эвристики, с эти надо долго возиться и экспериментировать. С точки зрения программирования (а под словом "программирование" не понимается битовыжимание с обсчётом тактов процессора) там ничего такого нет. Вот сложно — это написать тот же Ворд. В Ворде (и офисе вообще) математики никакой нет, но его нужно спроектировать и хорошо реализовать.
Кстати, я так понимаю, речь идёт о MP3-енкодере? А мы тут говорим об MP3-декодере, который штука действительно примитивная. И MP3 декодеров куча понаписана.
PS: по поводу математики. Что сложнее написать: yacc или MP3-енкодер? Вот насчёт MP3-енкодера точно сказать не могу, а вот yacc гораздо проще писать на C#, чем на C. А на Nemerle раз в 10 проще, чем на C#. Зачем же писать современный yacc на asm'е, раз это не такая критичная штуковина.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[31]: Как скрестить ужа и ежа или статическую и утиные тип
Здравствуйте, Klapaucius, Вы писали:
K>Здравствуйте, FR, Вы писали:
VD>>>Лямбда без лексического замыкания — это нонсенс! FR>>Угу. Но все равно вещь вкусная и полезная.
K>Это без замыкания-то? Ну-ну.
Так я тоже двумя ногами за нормальные замыкания.
Но ты не прав с своими хиханьками и хаханьками, даже без замыканяия лямбда полезна и вкусна, особенно если пользуешся как в D как блоками кода.
Re[26]: Как скрестить ужа и ежа или статическую и утиные тип
Здравствуйте, konsoletyper, Вы писали:
K>а вот yacc гораздо проще писать на C#, чем на C. А на Nemerle раз в 10 проще, чем на C#.
У вас есть реальный опыт, подтверждающий выделенное утверждение (на счет 10-ти кратного упрощения в Nemerle по сравнению с C#)?
Или это такая же гипербола, как здесь
Здравствуйте, Cyberax, Вы писали:
C>VladD2 wrote: >> Что до интелисенса в С++, то это еще очень долго не будет возможно. >> Производительность современных процессоров не просто недостаточно. Ее >> катастрофически нехватает. А оптимизировать там что-то будет очень не >> прсото. В Ди наверно будет по проще, но и у него будут проблемы с данным >> примером. А более сложные вещи вообще будут недоступны для этих языков. C>Рекомендую посмотреть XRefactory. Автокомплит оно делает почти 100%
Ага. "Почти" это замечательное русское слово которое можно применять всегда когда что-то не сделано, но хочется считать, что сделано.
В общем, прмер я привел. Повторяешь его на С++ и показываешь мне скриншот с чем-то похожим на то что привел я в этом письме
. Тогда продолжаем разговор. А перемывать в сотый раз кости дохлого енота нет никакого желания.
C>надежный, даже с Бустом справляется. Простые рефакторинги там тоже есть.
Ну, да Солтоковцы тоже хвастаются рефакторингом. Только там гарантии близкие к замене по контексту.
А потом в рефакторинге важна скорость. Если переименование переменной идет пол минуты, то это уже для работ не принодно.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[41]: Как скрестить ужа и ежа или статическую и утиные тип
Здравствуйте, FR, Вы писали:
FR>Угу тебе хорошо а я сегодня полдня вместо работы в D копался
А сколько народа ты еще при этом отвлекаешь от работы...
FR>В общем держи фабрику, конечно все в статике, но просто. FR>Теперь убежден что программировать шаблоны в D на порядок проще чем в C++.
Под "все в статике" я правильно понимаю, что реално использовать ее как именно фабрику не удастся?
Ну, то есть, можн ли создать перменную которая сначала будет содержать ссылку на одну фабрику, а потом на другую. Так чтобы при ее изменении один и тот же вызов приводил к созданию другого типа объектов?