Здравствуйте, VladD2, Вы писали:
VD>Что до его неповоротливости, то скажи спасибо С++ программистам из МС, так как основные тормоза Януса — это джет.
Не хочу никого обидеть, но по опыту, основные тормоза неверные алгоритмы(про компоненты помолчим, я не уверен). Уже проходило, что для поиска — просто ничего не было сделано. Да и работу с БД там можно оптимизировать.
Здравствуйте, _vovin, Вы писали:
_>Здравствуйте, VladD2, Вы писали:
VD>>Здравствуйте, eao197, Вы писали:
E>>>Просто, исходя из смысла слов "отсылать" (send) и "вызывать" (call) не следует считать, что "отсылка" == "вызову". А в большинстве языков так и есть, причем изменить ничего нельзя.
VD>>Перечисли, пожалуйста, языки используещие ассинхронные механимы передачи сообщений.
VD>>Даю подсказку, Смолток, откуда ты выдрал эту терминалогию посылает сообщения синхронно.
_>Надо уточнять — Smalltalk-72 посылал сообщения асинхронно.
Всё возвращается на круги своя Осталось вернуть современным реализациям возможность классам определять собственную грамматику потока сообщений (которая исчезла в ST-76) и круг замкнётся
Здравствуйте, Cyberax, Вы писали:
E>>>Просто, исходя из смысла слов "отсылать" (send) и "вызывать" (call) не следует считать, что "отсылка" == "вызову". А в большинстве языков так и есть, причем изменить ничего нельзя. VD>>Перечисли, пожалуйста, языки используещие ассинхронные механимы передачи сообщений. C>Эрланг Общение между потоками там происходит с помощью посылки асинхронных сообщений.
Можно ли считать Эрланг объектно-ориентированным языком?
К тому же, как я понимаю, нас с Владом в первую очередь интересуют широко распространенные имперические объектно-ориентированные языки.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Nonterminals list element elements.
Terminals '(' ')' 'atom'.
Rootsymbol list.
list -> '(' ')' : nil.
list -> '(' elements ')' : '$2'.
elements -> element : {cons, '$1', nil}.
elements -> element elements : {cons, '$1', '$2'}.
element -> atom : '$1'.
element -> list : '$1'.
eao197 wrote:
> VD>>Перечисли, пожалуйста, языки используещие ассинхронные механимы > передачи сообщений. > C>Эрланг Общение между потоками там происходит с помощью посылки > асинхронных сообщений. > Можно ли считать Эрланг объектно-ориентированным языком?
Нет, это функциональный язык с упором на процессы.
> К тому же, как я понимаю, нас с Владом в первую очередь интересуют > широко распространенные имперические объектно-ориентированные языки.
Нечто подобное было в Inferno VM — там были специальные "каналы" для
передачи объектов между потоками.
Ну и на С++ можно такое при желании сделать — взять Spirit или xpressive
и вместо итераторов подсунуть ему междтредовые каналы. Надо будет
попробовать на досуге.
Здравствуйте, Cyberax, Вы писали:
>> Всё возвращается на круги своя >> <http://map1.squeakfoundation.org/sm/package/726464e5-f584-4433-b073-f5808c2b5442> >> Осталось вернуть современным реализациям возможность классам >> определять собственную грамматику потока сообщений (которая исчезла в >> ST-76) и круг замкнётся
C>Толпа скандирует: "Эрланг, Эрланг, Эрланг!"
Здравствуйте, eao197, Вы писали:
VD>>Перечисли, пожалуйста, языки используещие ассинхронные механимы передачи сообщений.
E>Я не знаю таких языков. E>Но в языках, где вызов метода рассматривается как отсылка сообщения (Ruby, может быть, Smalltalk) существует возможность перехвата вызова любого метода. А это делает возможным при перехвате сохранить параметры и передать их на выполнение в другой поток. Но сам, исходный вызов в коде не будет отличаться от вызова обычного метода.
E>Вот например: E> <поскипано>
Надо еще дописать код, что бы сразу, синхронно возвращать прокси, который при получении любого сообщения, будет блокировать thread до момента, когда значение будет действительно вычислено.
Здравствуйте, VladD2, Вы писали:
VD>Нда... тяжело было почитать приведенные ссылки? D>>Ладно, предлагаю конструктивно поговорить на тему, что мы привыкли называть полиморфизмом.
Не поверишь! И твою ссылку почитал и еще порыл и почитал. Собственно поэтому вопрос сформулирован как "привыкли называть". D>>Вот, например такой код: D>>
D>>Это есть пример использования полиморфизма, а именно использование метода containsPoint(Point). VD>Откуда видно, что он полиморфен?
Вот первый интересный момент. Если бы этот код был написан на Smalltalk то вопроса бы не возникло — любой объект потенциально может среагировать на любое собщение. Если бы он был написан на Java, то скорее всего бы тоже не возникло (хотя, конечно метод containsPoint мог бы быть объявлен final). С другой стороны, когда встречаются такие названия (имена переменных), то логично ожидать, что area — ссылается на абстратный интерфейс, а containsPoint имеет несколько реализаций.
Однако вернемся к определению. Является ли этот алгоритм полиморфным? Пусть он был написан на java (синтаксически все правильно и если дальше не пост не читать, то мог бы). Но тогда получается, что все дело в том объявлен containsPoint как final или нет. Если Area это abstract class, а не interface то мы можем скомпилить этот код против объявления containsPoint без final, отложить в сторонку, а потом решить, что все области у нас прямоугольные и сделать его final. И что мы получаем? Полиморфные алгоритмы в java бывают только в runtime? А в статике такого понятия не существует? Очень похоже на бред...
D>>
D>>class Area {
D>> virtual bool containsPoint(Point p) = 0;
D>>class Rectangle : public Area {
D>> virtual bool containsPoint(Point& p) {
D>>
VD>Вот теперь это можно утверждать. У нас есть два типа к которым может применяться один метод. VD>Формализуем сигнатуру этого метода, чтобы далее было проще рассуждать. VD>
VD>Area * Point -> bool
VD>Rectangle * Point -> bool
VD>
VD>Собственно данное описание подразумевает, чтом может существовать неограниченное множетсво методов с сигнатурой: VD>
VD>T * Point -> bool
VD>
VD>Где T тип являющийся наследником типа Area. VD>Второй метод как раз в него входит.
Т.е. и ты считаешь, что полиморфным алгоритм является только если ему могут достаться разные реализации (полиморфен или нет — понятие не локальное, а зависит от контекста в который включены детали объявления используемых методов).
D>>Это был полиморфизм динамический переходим к статическому. Перегрузку пропустим — imho не интересно. VD>Обрати внимание на выделенный фрагмент. Ниже мы к нему вернемся. D>>
D>>template<class T>
D>>T sum(iterator<T> begin, iterator<T> end) {
D>> T result = T();
D>> while (begin != end) {
D>> result = result + *begin;
D>> begin++;
D>> }
D>> return result;
D>>}
D>>
VD>Ага. Это пример перегрузки методов про которое ты сказал, что она не интересна. VD>Полморфен в данном случае сам опрератор "+". Но он и до этого был в С++ плиморфен, так как его можно было применять к типам int, char, double... Ты всего лишь добавил поддержку для еще одного типа, т.е. сделал еще дну перегрузку.
Твоя правда. Можно даже несколько расширить понятие перегрузки как полиморфизма, любые два метода с одинаковым именем можно считать полиморфными (даже если их классы никак не связаны иерарзией).
class A {
int f();
}
class B {
float f();
}
template<class T>
bool f_order(T x, T y) {
return x.f() < y.f();
}
Я тут не вижу приципиальной разницы между operator+ и f().
Если посмотреть на такую ситуацию в Smalltalk, то там будет тоже самое, если методы имеют одинаковое имя то они полиморфны и код типа f_order будет полиморфным (в смысле того определения). Разница только в том, что в Smalltalk это будет полиморфизм динамический.
D>>Теперь вернемся к факториалу: D>>>>
D>>Я предлагаю взгянуть на этот так: Здесь описан интерфейс D>>
D>>int factorial<int>();
D>>
D>>И две его имплементации. Для 0 и для всех остальных целых.
VD>Замечательно. Теперь опишим сигнатуру этой функции: VD>
VD>void -> int
VD>
Тут ты меня не понял. Я предлагал приписать фактириалу сигнатуру <int> -> int. Где "<int>" — целое значение на этапе компиляции, а просто "int" это обычный runtime int. Нотация такая же как и для параметров типа class (или typename) <T> -> int. Пример так такой функции ниже вторая версия факториала.
VD>Все! Больше сигнатур породить нельзя! Параметр шаблона в данном случае это константа! Значение этой константы у всех реализаций метода имеет динаковый тип. Причем этот тип вообще нельзя ипользовать для задания типов внутри метода!
Ну если тебя продолжает смущать <int> в сигнатуре, то вот еще (более извращенный) пример фактироила на классах, а не интах:
template<int N>
class Point {
int coordinate;
Point<N-1> otherCoordinates;
int dimension() { return N; }
Point<N-1> otherCoordinates() { return otherCoordinates; }
}
class Point<0> {
int dimension() { return 0; }
}
template<class T>
int factorial(T t) {
return t.dimension()*factorial(t.otherCoordinates());
}
int factorial(Point<0> nowhere) {
return 1;
}
int factorial_5 = factorial(Point<5>());
Тут хочу отметить, что сделано в точности тоже самое, что и в предыдущей версии, немного изменем способ добыть параметр N, т.к. цель — передать его через параметр типа <class>, а не <int>.
Вот еще один довод с пользу того, что не важно (с точки зрения полиморфизм есть или нет) какой тип у параметра шаблона тип или значение какого-то типа. Возьмен два варианта введения специализаций:
// Типы
class F {
void invokeF();
Object getImplementation(class) {
if (class == MyClass) return Type_SpecialImplementation();
return Type_CommonImplementation();
}
}
class Type_SpecialImplementation extends F {...}
class Type_CommonImplementation extends F {...}
// Значения
class G {
void invokeG();
Object getImplementation(value) {
if (value == 1) return Int_SpecialImplementation();
return Int_CommonImplementation();
}
}
class Int_SpecialImplementation extends G {...}
class Int_CommonImplementation extends G {...}
// Использование
F.getImplementation(XClass).invokeF();
G.getImplementation(4).invokeG();
И где теперь разница? Алгоритм переписывания одинаковый, по стилю — очень похоже на исходный C++.
Т.е. начать можно было вы с
// Здесь мы теряем упоминание параметров XClass и 4.
Type_CommonImplementation().invoke();
Int_CommonImplementation().invoke();
// Возможен вариант с if, но он тут странно смотреться будет. Т.к. результат этого if статически известен.
А потом, для улучшения сопровождаемости сделать replace-condition-with-polymorphism. В C++ компилятор делает это за нас (сопровождаемость улучшает)
А теперь переписываем исходный факториал на языке без типов вообще (типа Self или JavaScript, хотя на последнем так не получится):
Опять в точности исходный алгоритм, записан на другом языке. И теперь вроде полиморфный?
VD>Меня смущает, то что ты неверно трактуешь понятие полиморфизма.
Вот по-этому мне и охота разобраться что такое полиморфизм, так что бы это не было похоже на бред и так что бы один и тот же алгоритм, выраженная на разных языках был либо везде полиморфный, либо везде не полиморфный.
Здравствуйте, GlebZ, Вы писали:
VD>>Что до его неповоротливости, то скажи спасибо С++ программистам из МС, так как основные тормоза Януса — это джет.
GZ>Не хочу никого обидеть, но по опыту, основные тормоза неверные алгоритмы(про компоненты помолчим, я не уверен). Уже проходило, что для поиска — просто ничего не было сделано. Да и работу с БД там можно оптимизировать.
Влад об этом и говорит. Тормоза в джете — т.е. в аксессе. При переходе на SQL всё шевелится очень шустро, правда SQL сам по себе жрёт столько памяти сколько есть в системе. Перевоспитать его можно очень легко настройками использования памяти. Самый тормозной запрос был, когда выбирались оборванные ветки, там был запрос типа NOT IN и поднималась практически вся база. Оптимизацией БД это не решалось. AVK это недавно починил. Для пущей надёжности можно ещё после синхронизации насильственно запустить GC.Collect и понизить приоритет треда запроса. А в остальном там вроде как уже всё более менее.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, Dyoma, Вы писали:
D>Надо еще дописать код, что бы сразу, синхронно возвращать прокси, который при получении любого сообщения, будет блокировать thread до момента, когда значение будет действительно вычислено.
Для политики fire and forget (т.е. для настоящего механизма отсылки сообщений, когда нет результата обработки сообщения) это и не нужно.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Andrei N.Sobchuck wrote:
> C>Толпа скандирует: "Эрланг, Эрланг, Эрланг!" > Я об этом и говорю. Цитата > <http://lists.squeakfoundation.org/pipermail/squeak-dev/2002-February/034988.html>: > Erlang programming is very similar to Smalltalk-72 > programming, since message receiving is implemented in much the same > way > Alan Kay. > Хотя это, пожалуй, на "макро" уровне. На "микро" то сообщений нет.
То есть? В Эрланге используются именно явные сообщения, для которых
можно даже задавать грамматику (делать диалоги). Ну и еще Эрланг
является чисто функциональным (в нем нет деструктивного присваивания
вообще).
Здравствуйте, IT, Вы писали:
IT>Влад об этом и говорит. Тормоза в джете — т.е. в аксессе. При переходе на SQL всё шевелится очень шустро, правда SQL сам по себе жрёт столько памяти сколько есть в системе. Перевоспитать его можно очень легко настройками использования памяти. Самый тормозной запрос был, когда выбирались оборванные ветки, там был запрос типа NOT IN и поднималась практически вся база. Оптимизацией БД это не решалось. AVK это недавно починил. Для пущей надёжности можно ещё после синхронизации насильственно запустить GC.Collect и понизить приоритет треда запроса. А в остальном там вроде как уже всё более менее.
Лучше не стану на эту тему гнать. Лучше не лезть туда где не обладаешь всей информацией. Я смотрел только по той информации у меня была(поиск). И то что знаю(БД).
А БД всегда можно оптимизировать. Не стану ничего предполагать по конкретному продукту. Просто знаю что всегда можно.
Здравствуйте, GlebZ, Вы писали:
GZ>Не хочу никого обидеть,
Так не обижай.
GZ> но по опыту, основные тормоза неверные алгоритмы(про компоненты помолчим, я не уверен).
Странный у тебя опыт, однако. Ты в курсе, что с современными БД общение ведется не на уровне императивных алгоритмов, а на уровне декларативных запросов? Мы и так занимаемся полнейшими извращениями с джетом пытаясь заствить его работать немного разумнее, но и это не особо удается. Пень он тупой. И то что он на С++ написан ему никак не помогате.
GZ> Уже проходило, что для поиска — просто ничего не было сделано. Да и работу с БД там можно оптимизировать.
Видимо я как-то очень сложно выражадь, так как очень мноие читая мои сообщения стуи уловить не могут.
Итак, попробу так чтобы дошо до последнего рабочего с его колхозницей.
Итак, действительно скорость кода в большинстве случаев зависит от выбранны алгоритмов. И действительно скорость дотнетных приложений может оказаться несколько ниже аналогичных нэйтивных так как сам дотнет вносит в программу свои алготитмы которые порой понижают производительность. Если не брать кривые библиотечные методы, которые изредка но всречаются в дотнете, то общий процент ставляет от 0% до 30%.
Примерно такой же процент можно получить если сравнить разные компиляторы С++.
Бывают конечно и более серьзные провалы, но на практике они встречаются не часто.
К тому же тормоза встречаются не всегда, а в некоторых случаях которые с успехом можно оптимизировать разными способами (вплоть до ансэйфа и выноса некоторых частей кода в анменеджед-модули).
Естествнно, что при таких условиях реальные тормоза в приложения определяются не тем управляемое оно или нет, а качеством выбранных алгоритмов и библиотек. Причем библиотеки так же определяется качеством применяемых в них алогоритмов, но повлиять на них мы не в стостоянии.
Так вот в случае с Янусом, я отвественно заяляю, что видимые тормоза определяются используемыми библиотеками. Причем не просто библиотеками, а неуправляемыми библиотеками вроде джета или эксплорера.
Они же отедают немалый объем памяти. Но с памятью дотнет действительно работат очень не брежно, так что тут ничего не попишешь.
Так вот, теперь я могу объяснить свою фразу. Анменеджед код или нет не определят его производительность. В случае же Януса тормоза в основном сконцентрированы в анменеджед-библиотеках.
Что касается поиска, то его сразу делали без рассчета на великую скорость. Писать собственный индексирующий движок слишком тяжело. Бесплатных и вто же время качественных мы пока на горизонте не видим. А SQL-серверы, даже коммерческие еще пока что применяют те самые плохие алготимы которые приводят к тмоу, что простой запрос "%некий паттерн%" приводят поиску методом перебора, что приводит к тормозам на больших БД.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, eao197, Вы писали:
E>Здравствуйте, VladD2, Вы писали:
E>>>Про C# не скажу,
VD>>Но мы то про него в основном речь ведем! Ты же утверждашь, что именно он от С++ произошел.
E>Я сказал, что: E>
E>Так вот, имхо, Java/C# стали всего лишь дальнейшей эволюцией C++ времен 1990-1992 годов, а то и еще более раннего периода.
E>Ну и что тут не так?
Все. Они не являются эволюцией С++. Они заимствовали из него отдельные фичи. Иначе нам прийдется признать, что С++ является эволюцией Смолтока и т.п., так как С++ тоже заимствовал немало идей.
E> C++ добавил в C ООП. Затем, имхо, Java/C# пошли по этому пути дальше
А почему ты считашь, что Java/C# взяли ООП из С++, а не из Смолтока или скажем ОбжективС? Подходы к ООП Смолтока и C# куда ближе чем С++ и C#.
E>Ну да бог с ним. Меня ты не переубедил, а правду пускай историки ищут.
А ты и не дескутировал. Ты заранее во всем уверен. Никакими аргументами тебя не прошибить. Для меня очевидно, что C# является таким же наследником С++ как, скажем, Дельфи. У С++ и C# из общего в основном синтаксис и то что они являются оба императивными ООЯ. Языки разные идеологически и семантически.
E>Нашел кому этот вопрос задавать . По мне, так Java/C# -- must die! C++ forever!
ОК, в 2004. Дела это не меняет. Дженерики появились в конце 2004-го. И они только отдаленно напоминают С++-ные шаблоны. Так что вряд ли тут можно говорить том, что дело было втом, что авторы неуспели осознать. Приемущество шаблонов было очевидно еще в 1996-ом. И вряд ли стоило ждать 8 лет если это было просто упущение. Это был именно что идеологический выбор. В том виде в каком шаблоны были встроены в С++ они были не приемлемы для C# и Явы, так как невписывались в идеологию этих языков.
E>Нет, это значит: "Много 'C с классами' и много с шаблонами". Много, но не черезмерно (камень в огород boost-а)
Я бы сказал, так "и чуть-чуть ООП-а".
VD>>Сэр, вы меня пугаете. Вызов экземплярного метода == отсылке сообщений объекту.
E>Не-а.
Драссэ. Приехли. Дальше обсуждение мжно не вести. Это очередная попытка оспорить прописные исниы. Тебе не Руби надо было заняться, а Смолтоком. Там любят извращения.
E> Это распространенная догма.
Это факт. Можешь прогуляться до Википедии и освежить знания.
E> Главное противоречие в нем, что "отсылка" это асинхронное понятие, а "вызов" -- это синхронное.
Ты в свои СОбжектс (или как их там) переиграл. Ассинхронность ортогональное понятие к ООП. За исключением Эрлэнг, и с наряжкой дотнетных, я низнаю ни одного ЯП который поддерживал бы поддерживал посылку ассинхронных сообщений.
E> Когда мы приравниваем отсылку вызову, то для реализации асинхронного взаимодействия приходится придумывать грабли вроде BeginInvoke/EndInvoke или active в очередном прожекте Саттера.
Неповеришь, но в даже в Виндовс для посылки синхронного и ассинхронного сообщения используются разные методы, т.е. придумываются "грабли". Такие "грабли" назваются интерфейсом.
E>>> В Ruby, например, это так. Там можно вызовы методов (сообщения) перехватывать, сохранять, передавать другому или воспроизводить через какое-то время. В C# это возможно?
VD>>Издевашся?
E>Нет. Рассказываю о том, чего узнал.
И что, Руби вызвает все ассинхронно, или это ты так пылася зачмырить вызов метода?
E>Имхо, перехват методов и последующее их воспроизведение, или трансляция вызова в параллельный поток -- все это возможно и в статически типизированном языке.
Ага. Только псылка сообщений тут на фиг не упала. В том же дотнете есть такое понятие как RealProxy. С ее помощью можно подменить ссылку на реальный объект, на ссылку на прокси и перенаправлять вызовы куда хочешь. С помощью RealProxy сделаны такие вещи как Ремоутинг (межмашинное, межпроцессное и межпоточное взаимодействие).
Интересно, что внутри Ремоутинга как раз применяются сообщения. Только организованы они в виде объектов. Ну, и естественно, что для пользователя они невидны. Для него он использует ссылку на объект который находится где-то не в текущем домене приложения (хотя даже это он может не знать).
E>Мой поинт был в том, что если последовать твоему предложению и сделать деструкторы по умолчанию виртуальными, то придется сильно постараться, чтобы от этих 4-х байтов потом избавится.
А надо? Ты никогда не задумывался над тем, что эти 4 байта может устранить сам компилятор? Чтобы ему было проще можно ввести ключевое слово вроде sealed или final.
Поверь, компиляторы сопосбны на чудеса. Если уж возможна оптимизация таких на свквозь интерпретирвемых языков как Смолток и Лисп, то уж в С++ это можно было бы сделать точно!
В общем, подобные решения — это забота о текущем при полном наплевательстве на будущее. Помяни мое слово. Через некоторое время управляемые языки сначала догонят С++ по производительности, а потой выйдут вперд. Просто это непростая задача требующая времени. За управляемыми языками множество приемуществ вроде стройной мат.модели и отсуствия возможности влезть шаловливыми рученками программиста, а за С++ только одно — простота реализации.
E>Когда на C# будет написанно столько же, сколько на C++ и таким же количеством ламеров, тогда и можно будет сравнить, кто и сколько жрет памяти и насколько что тормозит.
Хм. На Яве уже пишется не меньше кода чем на С++. Тому свидетельством является сорсфордж. А если сложить C# и Яву, то пишется пожалуй по более. А уж про ламеров аргумент совсем "мимо кассы". Уж чего, чего, а в виду простоты на Яве и C# пишут куда больше ламеров.
E>Пока я, например, слышу от коллег, что IDEA на буке с 512Mb отъедает очередные 150Mb пямяти и тормозит.
И хрен с ними! За те возможности которые она предоставляет я бы доставил себе еще 512, а то и 1.5 гига!
Кстати, о птичках... На нашем сервере Перл отедает от 200 до 500 метров. При этом он только занимается фильтрацией почты. Для сравнения процесс в котором крутится сам сайт отедает приблизительно столько же, вот только делает он на порядки больше. И мне жалко помять под перл, но не жалко под АСП.НЭТ, так как я оцениваю что я получаю в результате их работы.
E>Я ожидал, что после моего примера такие упреки появятся -- мол дизайн должен быть правильный. А не правильный, так рефактори. Предсказуемо, скучно.
А чтобы не скучать не приводи примеры плохого дизайна.
E>А ситуация такая: deliver_sm_t и data_sm_t -- это инкапсуляция разных PDU. Между ними есть небольшие пересечения по функциональности. Оба они is-a PDU. Но deliver_sm_t не есть data_sm_t и наоборот.
Про интерфейсы или абстрактные классы слышал? Ну, вот введи интерфейс описывающий ту часть функциональности которая пересекается. Реализуй этот интерфейс в обоих классах... и глядишь тебе вообще уже не нужен будет шаблон.
E>сделать очередной рефакторинг и ввести интерфейс deliver_and_data_and_submit_multi_sm_base_t. Увлекательный путь, однако
Дык, в результате ты получишь грамоный дизайн который и читатья будет лучши, и рефакториться в дальнешем проще. А при наличии автоматизированного рефакторинга это вообще не проблема. У меня на выделение интерфесов уходит сегунд 10. Вот только я их не часто выделяю. Обычно я сразу делают продуманный дизайн, так что рефакторинг это палочка выручалочка на случая если кто ступит или некоторые предпосылки не будут известны заранее.
E>Вот только C++ шаблоны позволяют решать подобные задачи легко и без лишних усилий (со статической типизацией при этом).
Грязь в коде они позоляют намешивать. Ты привел пример который можно обосновать только ленью и кривым дизайном.
E>В контексте обсуждения главное как раз не different datatypes, а subtypes и signatures. Но я об этом уже говорил.
Извини, но обсуждение дальше вести нельзя. Ты неверно интерпретирушь базовые поняти.
E>Принципиальная: рефлексия для любого типа или рефлексия только для того, что я явно заказал.
Может пусть компиляторы и рантаймы думают об эффективности? Зачем мне еще одна головная боль?
E>Обязательно, т.к. ты переключаешься с C++ на COM.
Ислючитльно чтобы продемонстрировать неверность твоего утверждения о том, что для наличия возможности создать объект динамически нужен байткод.
E> Хотя COM -- к C++ не имеет никакого отношения.
Он позволяет на С++ создавать объекты динамически. Кстати, я даже зря КОМ привел в пример. КОМ использует паттерн фабрика классов. С помощью этого паттерна можно создавать объекты динамически и без КОМ-а. Разница с дотнетом и КОМ-мом будет только в том, что ты обязан будешь самостоятельно создать необходимый фрэймворк, а в КОМ и дотнете он уже встроен, т.е. разный объем работы.
E> В Java/C#/Ruby для рефлексии мне не нужны ни COM, ни CORBA. А в C++ -- нужны. И в этом разница. А доступна рефлексия в этих языках именно из-за того, что язык занимается метаинформацией, а не сторонняя библиотека или технология.
Так. Еще раз напомню почему появился КОМ. Ты сделал утверждение что без байткода нельзя создать динамически объект, потом ты такое же утверждение сделал про метаинформацию. Так вот это берд. И больше я его осбужать не намерен. Аргументов через край. Ты же уже разводишь демагогию пытаясь не прзнать очевидного.
E>>>А расскажи мне, как третий модуль возьмет два типа из двух других модулей? Просто по имени? Не зная даже, какие интерфейсы они поддерживают?
VD>>А это твоя проблема.
E>Это твоя проблема. Ты не полностью сформулировал задачу.
Задача сформулирована полность. Просто в С++ нет средств для ее реализации, так как это не компонентный язык. В компонетных языках такая возможность есть. Эта задача элементарно решаенся даже на Обероне.
E>Признаю, что не знал, что есть асинхронные делегаты.
Ну, тогда банальный логический вывод позволяет так же заключить, что раз ты считашь такую фичу прорывом, то только на этом основании дотнет и C# являются прорывом. А таких фич в них просто море. То что ты о них не знашь или незнашь как их применить — это твоя проблема. И именно по этому ты не считашь дотнет прорвом и перечисляешь довольно второстепенные вопросы как проры.
E>Но асинхронные делегаты и асинхронный вызов метода -- это, имхо, разные вещи.
А это не важно. Ассинхронный вызов вообще не может быть сделан напрямую. Для этого нужен некий фрэймворк. Такой фрэймворк можно сделать для любого языка. Даже для С++. Собственно такой фрэйморк уже делается. Индиго будет поддерживать очень красивую ассинхронную работу. Да и чесно говоря уже сегодня можно использовать МОМ (Message Oriented Midleware) чтобы получить необходимую функциональность. В конце концов MS MessageQueue (MSMQ) или IBM WebSphere MQ. В дотнете есть API для этих продуктов.
В общем, ты просто проспал этот "провры". Если уж и говорить о чем-то, то о встраивании параллелизма в ЯП. Собственно работы эти уже ведутся. В докладе Саттера как раз и говорилось об оных для С++. Уверен, что пареллельно это дело появится и для C#.
E>С делегатом я сохраняю куда-то ссылку на объект и ссылку на метод (создаю делегат) и вручную вызваю BeginInvoke. Все это вручную.
Какою еще ссылку? Получашь делегат от метода и вперед. Сахранея все дотнет. Вот то что нужно еще некоторый объем кода для синхронизации уже некрасиво. Но опять таки это если нужно получать возвращаемое значение.
E>Когда же я говорил про асинхронные методы, я подразумевал, что все эти вещи за меня сделает компилятор -- мне нужно только вызвать метод и все. Очень похоже на то, что Саттер предлагает в concurrent C++.
Для этого не нужен компилятор. В компилятор нужно встроивать некие паттенны для распараллеливания. В общем, ты снова прочел что-то и воспринял это не как того ожидал автор, а свозь призму своих догм полученных при разработке собственного продукта.
E>Если ты не видишь разницы между такими подходами, то вот аналогия: в С/Oberon виртуальные методы можно эмулировать вручную за счет ручного управления vtbl. А в ОО языках программисту это не нужно -- сам язык такими низкоуровневыми вещами занимается.
Я же понял к чему ты клонишь. Так вот твой С/Oberon — это фрэймворк вроде MSMQ, а Саттер говорил о встраивании в язык паттернов упращающих арспараллеливание кода. Это разные вещи хотя они используют и похожие механизмы.
E>Очень возможно. Мне так же кажется, что Ruby, как и C++ -- язык для небольших команд. Так же, как и Smalltalk.
Ага. То-то на С++ пишут самые большие проекты. А на С еще больше.
E>Ты говоришь про отладчик и про код, который был со специальной отладочной информацией скомпилирован.
И что? Он и с этой информацией будет куда быстрее Смолтока.
E>Я же говорю про production систему.
А кто будет в ней отладкой заниматься? И почему этот орел не может взять отладочную версию?
E>У Rubyist-ов sourceforge не в почете. Есть www.rubyforge.org и Ruby Application Archive. Основные проекты там хостятся.
Понятно. Такие же извращенцы как и Смолтокщики. Ну, у тех-то хоть особенности языка подталкивают. А Рубистам то зачем это? На этих левых серверах даже статистики нет.
VD>>Вот только одно "но". Встретить проект создающийся исключительно на руби трудно. Обычно Руби сочетается с Явой или С++. Так что язык явно не GPL.
E>Это тебе кажется. У тех, кто Ruby пользуется по этому поводу нет ни сомнений, ни комплексов.
Как и нет чисто Руби проектов на сорсфордже.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, eao197, Вы писали:
VD>>Перечисли, пожалуйста, языки используещие ассинхронные механимы передачи сообщений.
E>Я не знаю таких языков.
А я знаю один — Эрлэнг. Вот только применяется он очень узко. В основном Эриксоном в телекомуникации для распаралленивания процесса вычислений.
Правда классный список? Зачем тогда был разводить этот диспут? Ты еще помнишь о чем шла рчень. Для ООП посылка сообщения == мызову метода, так как это ничем не мешат написанию ООП программ.
E>Но в языках, где вызов метода рассматривается как отсылка сообщения (Ruby, может быть, Smalltalk)
Скорее Смолток, и может быть Руби.
E> существует возможность перехвата вызова любого метода. А это делает возможным при перехвате сохранить параметры и передать их на выполнение в другой поток. Но сам, исходный вызов в коде не будет отличаться от вызова обычного метода.
И как только такие неправилные языки как C# умудряются без проблем общаться с другими процессами?
В общем, описанный тобой механизм совершенно не нужен ни для организации ассинхронности вызова, ни для многопоточной обработки. Это паттерн. Причем один из возможных. Причем паттерн далего не бесплатный. Он делает Яву и Смолток принципиально медленее более традиционных языков, так как вызов метода выливается в банальную машинную инструкцию, а вот посылка и прием сообщений куда более затратный механизм если к нему подходить честно.
E>Эта реализация просто печатает сообщение о перехвате метода и тут же запускает метод на выполнение. А могла бы инициировать вызов метода на контексте другой нити. Но вызов hello для объекта t ничем не отличается от вызова любого другого метода.
На досуге поройся в этом списке. Думаю, поймешь, что тоже самое можно делать и в языках не пользующихся хитроумными методами передачи сообщеий.
ЗЫ
В общем, мы как всегда ушли от темы. Ты ничего не сказал ото, что помешает ООП если в языке будут использоваться методы, а не послка сообщений. И никак не опроверг утверждение, что с точки зреня ООП вызов метода == посылке сообщения. Вместо этого ты ударился в рассуждения о многопоточном взаимодействии.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Dyoma, Вы писали:
D>Т.е. и ты считаешь, что полиморфным алгоритм является только если ему могут достаться разные реализации (полиморфен или нет — понятие не локальное, а зависит от контекста в который включены детали объявления используемых методов).
Брр...
Я ничего не считаю. Есть определине "полиморфный" — зрачит может работать с разными типами. Реализации тут не причем. Реализация может быть и одна. Главное, что один метод/объект может обрабатывать информацию разных типов.
D>Твоя правда. Можно даже несколько расширить понятие перегрузки как полиморфизма, любые два метода с одинаковым именем можно считать полиморфными (даже если их классы никак не связаны иерарзией).
Это только если считать их одной и той же функцией. Но так считать не принято. Методы считаются полиморфными только в рамках иерархии некоторого класса. Хотя вопрос конечно сложный и спорный.
D>
D>class A {
D> int f();
D>}
D>class B {
D> float f();
D>}
D>template<class T>
D>bool f_order(T x, T y) {
D> return x.f() < y.f();
D>}
D>
D>Я тут не вижу приципиальной разницы между operator+ и f().
В общем-то — да. Но все же так считать не принято так как полиморфизм для методов обеспечивается и виртуализацией, а это создает путанницу. В общем, можно сказать, что перегрузка, параметрический полиморфизм и динамический полиморфизм отличаются друг от друга, а стло быть их имеет смысл рассматривать порознь.
D>Если посмотреть на такую ситуацию в Smalltalk, то там будет тоже самое, если методы имеют одинаковое имя то они полиморфны и код типа f_order будет полиморфным (в смысле того определения). Разница только в том, что в Smalltalk это будет полиморфизм динамический.
В Смолток все сложнее. Там нет декларации типов, так что все методы считаются полиморфными так как потенциально могут обрабатывать параметры любых типов. Собственно огядываясь на это в Яве решили сделать методы виртуальными по-умолчанию (хотя это был явняй перебор).
VD>>Замечательно. Теперь опишим сигнатуру этой функции: VD>>
VD>>void -> int
VD>>
D>Тут ты меня не понял. Я предлагал приписать фактириалу сигнатуру <int> -> int. Где "<int>" — целое значение на этапе компиляции, а просто "int" это обычный runtime int. Нотация такая же как и для параметров типа class (или typename) <T> -> int. Пример так такой функции ниже вторая версия факториала.
Нет у функции параметров. Нету! Это не посиделки бабок где можно предложить считать землю плоской и стоящей на трех слоках.
Ну, и даже если предположить (метафизически... типа она же выолняется в компайлтайме...), что функция получает параметр int и описывается как int -> int, то все равно функция не будет полиморфной, так как ее сигнатура все равно останется неизменной, какие бы значения ты бы не посдавлял.
D>Ну если тебя продолжает смущать <int> в сигнатуре, то вот еще (более извращенный) пример фактироила на классах, а не интах: D>
полиморфен, так как по правилам С++ шаблон с разными параметрами порождает новый тип. Хотя конечно не должен по логике. Ну, да это уже проблемы тех кто создал этот чудный язык. Намного умнее было бы ввести в язык typedef порождающий новый тип. Тогда и извращения были бы ненужны.
D> немного изменем способ добыть параметр N, т.к. цель — передать его через параметр типа <class>, а не <int>.
Ничего не понял.
D>Вот еще один довод с пользу того, что не важно (с точки зрения полиморфизм есть или нет) какой тип у параметра шаблона тип или значение какого-то типа.
Очень важно. И никаким доводом это не является. Это дурь языка. Не более. Просто тут от значения константы меняется тип самого класса пораждаемого на базе этого шаблона. Вот только тоже самое можно было бы сделать если сделать нармальный параметр типа и указать внем разные типы (пусть и созданные только для этого).
D> Возьмен два варианта введения специализаций: D>
И здесь опять нет полиморфизма. Здесь опять две разные функции созданные извращениями.
D>И перепишем на языке без шаблонов: D>
D>// Типы
D>class F {
D> void invokeF();
D> Object getImplementation(class) {
D> if (class == MyClass) return Type_SpecialImplementation();
D> return Type_CommonImplementation();
D> }
D>}
D>class Type_SpecialImplementation extends F {...}
D>class Type_CommonImplementation extends F {...}
D>// Значения
D>class G {
D> void invokeG();
D> Object getImplementation(value) {
D> if (value == 1) return Int_SpecialImplementation();
D> return Int_CommonImplementation();
D> }
D>}
D>class Int_SpecialImplementation extends G {...}
D>class Int_CommonImplementation extends G {...}
D>// Использование
D>F.getImplementation(XClass).invokeF();
D>G.getImplementation(4).invokeG();
D>
D>И где теперь разница?
1. Код вообще не на С++, и по этому его очень не просто понять.
2. На языке без шаблонов можно было бы так не извращаться:
calss A
{
pubic void f();
}
class B
{
pubic void f();
}
Короче, дальше читать уже совем не интересно. Приведенный тобой факториал и ему подобные извращения к полиморфизму никакого отношения не имеют. Согласен, что константный-параметр позволяет разные закрытые типы, но как ты понимашь, смысла в этом нет, так как тоже самое можно сделать куда более простыми и мнее извращенными методами.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Sinclair, Вы писали:
S>Ну как же? Вот, давеча, наш поборник эффективности Pavel Dvorkin наглядно продемонстрировал, как он собирается конкатенировать строки при помощи sprintf. При этом он заботливо вставил в этот код уязвимость к переполнению буфера.
А ссыдлчку можно?
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.