Универсальный базовый класс
От: MTD https://github.com/mtrempoltsev
Дата: 27.07.13 19:56
Оценка: +5 -3
Здравствуйте, A13x, Вы писали:

A>В java и .NET есть базовый класс Object с определенным методом equals (Equals в C#) с сигнатурой:

A>Предположим, что мы делаем некоторый язык, скажем E, похожим насколько возможно на java/C#, в котором хотим описать каким-то образом типобезопасный equals.

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

03.08.13 10:56: Ветка выделена из темы типобезопасный equals
Автор: A13x
Дата: 27.07.13
— AndrewVK
Re: Универсальный базовый класс
От: lazy/cjow/rhrr Россия lj://_lcr_
Дата: 04.08.13 17:31
Оценка: 14 (4) +3
MTD,

A>>В java и .NET есть базовый класс Object с определенным методом equals (Equals в C#) с сигнатурой:

A>>Предположим, что мы делаем некоторый язык, скажем E, похожим насколько возможно на java/C#, в котором хотим описать каким-то образом типобезопасный equals.

MTD>В новом языке не надо делать общий базовый класс — это просто глупо. Пусть программист осознанно обогащает свои классы реализуя необходимые интерфейсы.


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

Когда ты определяешь класс X, мысли это как набор предположений обо всех объектах данного класса.
Тогда Object — это класс, об объектах которых нельзя сделать никаких, кроме самых общих, верных для данного рантайма, предположений.

И не забывай, что классы и объекты формируют модель, она совсем не обязана отражать объекты реального мира, тем более 1:1 или даже n:m. То есть всегда найдётся предметная область (и ты наверняка сталкивался), когда для реального объекта создаются множество взаимодействующих классов, для подавляющиего большинства реальных объектов классы не создаются вообще, и часто создаются синтетические классы, не имеющие никакого отражения в реальном мире, несмотря на то, что сама модель может иметь прямое отношения к реальным объектам.

В этом свете введение класса Object позволяет получить определённые выигрыши, причём недостатками можно пренебречь.
Среди выигрышей:
1. определение функций, которые выполняют общие трансформации кода работающие для любых объектов (рефлекшн, рантайм-макросы)
2. определение функций, принимающих любой объект или последовательность объектов (например, логгер, Runnable)
3. определение функций, возвращающих любой объект (например фабрики, ioc контейнеры)

При достаточно развитой системы типов, некоторые из определений возможно бывает написать без object, используя разные продвинутые конструкции (см. например опредление функции map в Scala), но в общем случае нет.

Также из-за перегрузки становится невозможным описать тип "функция, принимающая любое количество любых аргументов", вместо этого в библиотеках постоянно фигурируют fun(a1); fun(a1, a2); ... fun(a1, a2, ..., a100500), я нахожу этот момент крайне неудобным. Какое это имеет отношение к топику? А такое, что понятие "список аргументов функции" не является объектом, и это порождает определённые неудобства, которые вполне реальные, в отличие от эфемерных концептуальных вопросов "может ли объект Ворона1 с состоянием Сыр-в-клюве принимать сообщение Каркать?"
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[3]: Универсальный базовый класс
От: A13x США  
Дата: 29.07.13 07:25
Оценка: 1 (1) +5
Здравствуйте, MTD, Вы писали:

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


A>>я считаю, что базовый класс необходим


MTD>Ты уверен, что кастрюля и ворона имеют одного предка?


Ну это уже софистика. В определенных задачах — думаю да, в некоторых задачах это возможно вообще будет один и тот же объект.
В данном случае базовый класс не имеет отношения к предметной области, а скорее к объектной модели ядра языка. Мне кажется, проводить такие параллели не совсем корректно.
Re[2]: Универсальный базовый класс
От: MTD https://github.com/mtrempoltsev
Дата: 28.07.13 06:22
Оценка: +2 -3
Здравствуйте, A13x, Вы писали:

A>я считаю, что базовый класс необходим


Ты уверен, что кастрюля и ворона имеют одного предка?
Re[5]: Универсальный базовый класс
От: lazy/cjow/rhrr Россия lj://_lcr_
Дата: 05.08.13 05:35
Оценка: -1 :)))
Evgeny.Panasyuk,

EP>>>Где, например, в STL единый базовый класс?

LC>>STL написана в функциональном стиле.

EP>Что ты понимаешь под функциональным стилем (учитывая такие вещи как std::sort, std::vector и т.п.)?

EP>То что используются функции высших порядков?
EP>Или то что std::sort не засунута в класс и работает по чётным и нечётным?

EP>Какие именно свойства стиля, о котором ты говоришь, позволяют обходится без общего корня?

EP>И чем, по-твоему, такой стиль хуже стиля для которого общие корни нужны?

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

Функциональный стиль ничем не хуже ООП-шного стиля, однако я не берусь сейчас определять это отношение "хуже-лучше". Примем на данный момент, что такой стиль — просто другой, для написания программ в таком стиле C++ подходит довольно хреновенько, Java совсем уныло выглядит, C# несколько лучше.

Почему шаблоны C++ являются плохой эмуляцией параметрического полиморфизма? Очень легко:
template <typename T> T id(T x){ return x; }
template <typename T> T plus(T x){ return x + x; }

в C++ных терминах тип у id и plus одинкаовый. Однако в терминах языка с правильной системой типов типы этих функций кардинально различаются:
id :: a -> a
plus :: (Num a) => a -> a

И это только вершина айсберга...
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[2]: Универсальный базовый класс
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 05.08.13 16:05
Оценка: 1 (1) +2
Здравствуйте, A13x, Вы писали:

A>Отчасти я с ним согласен с точки зрения "обогащения" функционала, но все же я считаю, что базовый класс необходим, но только с одним методом — getClass()


Если там только один метод, то лучше его сделать оператором языка.
... << RSDN@Home 1.2.0 alpha 5 rev. 100 on Windows 8 6.2.9200.0>>
AVK Blog
Re[6]: Универсальный базовый класс
От: Jack128  
Дата: 09.08.13 10:58
Оценка: 10 (1) +1
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, Evgeny.Panasyuk, Вы писали:


EP>> Например dereference у shared_ptr производит код <b>идентичный</b> dereference обычного указателя.

E>Это как так? У s_p ведь дволйное разыменование должно быть? Там же ещё прокси-объект болтается?

дык указатель не в прокси сидит, а не посредственно полем у shared_ptr. Это увеличивает size_of(shared_ptr<>) зато ускоряет доступ к сырому указателю.
Re[7]: Универсальный базовый класс
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 05.08.13 19:15
Оценка: 1 (1) +1
Здравствуйте, AlexRK, Вы писали:

ARK>Мое сугубое ИМХО — лучше всего ограничиться compile-time рефлексией.


А мое — предлагать сейчас язык без рефлексии как то уже и неприлично.

ARK> Вообще, ИМХО, рефлексия это нечто находящееся вне границ системы, по теореме Геделя выразить это на языке самой системы нельзя.


Софистика.

ARK> Ну а если однозначно нужна runtime рефлексия


Нужна, иначе такой шмат функционала превращается в геморой ...

ARK>то выходов немного — либо встраивать прямо в язык каким-то образом (а-ля новые ключевые слова и т.п.)


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

ARK>либо таки делать этого пресловутого общего предка.


Итого: в любом современном безопасном языке без общего предка не обойтись
... << RSDN@Home 1.2.0 alpha 5 rev. 100 on Windows 8 6.2.9200.0>>
AVK Blog
Re[4]: Универсальный базовый класс
От: MTD https://github.com/mtrempoltsev
Дата: 29.07.13 07:53
Оценка: +1 -1
Здравствуйте, A13x, Вы писали:

MTD>>Ты уверен, что кастрюля и ворона имеют одного предка?


A>Ну это уже софистика. В определенных задачах — думаю да, в некоторых задачах это возможно вообще будет один и тот же объект.


void* в C, Object в Java — это просто дыра в безопасности, при отсутствии ощутимой выгоды. Ну вот зачем тебе возможность скастить кастрюлю в ворону? Какие такие "определенные" задачи?
Re[6]: Универсальный базовый класс
От: MTD https://github.com/mtrempoltsev
Дата: 29.07.13 08:16
Оценка: +1 :)
Здравствуйте, A13x, Вы писали:

A>Для С — согласен, для Java — не понимаю — почему сделан такой вывод. void* не хранит информации о типе и нет возможности выполнить safe cast, для Object это не так, что меняет дело, разве нет?


Любой каст — потенциальная ошибка. По мне так лучше во время компиляции будет проверен тип, нежели в рантайме полетит исключение.
Про "особые" случаи поделитесь?
Re[4]: Универсальный базовый класс
От: AlexRK  
Дата: 04.08.13 08:37
Оценка: +2
Здравствуйте, iLikeCookies, Вы писали:

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


MTD>>Ты уверен, что кастрюля и ворона имеют одного предка?


LC>Имеют, они оба материальные объекты реального мира. Они даже имеют общие атрибуты, такие как вес, плотность итд.


Тогда надо создавать предка "Материальный объект реального мира" и наследовать от него кастрюлю с вороной. А глобальный общий предок не нужен.
Re[2]: Универсальный базовый класс
От: AlexRK  
Дата: 04.08.13 08:42
Оценка: +2
Здравствуйте, iLikeCookies, Вы писали:

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


Я считаю, что это неправильное решение.

LC>Еще предлагаю подумать в качестве подсказки на тему, почему в C++, где нет единого общего корня, разные библиотеки так или иначе создают один базовый класс и какие недостатки у такого подхода.


Ну вот пусть и создают базовый класс там, где он нужен, а в язык его пихать зачем?
Re[2]: Универсальный базовый класс
От: Evgeny.Panasyuk Россия  
Дата: 04.08.13 16:41
Оценка: +2
Здравствуйте, iLikeCookies, Вы писали:

LC>Еще предлагаю подумать в качестве подсказки на тему, почему в C++, где нет единого общего корня, разные библиотеки так или иначе создают один базовый класс и какие недостатки у такого подхода.


Где, например, в STL единый базовый класс?
Re[2]: Универсальный базовый класс
От: jazzer Россия Skype: enerjazzer
Дата: 04.08.13 19:56
Оценка: +2
Здравствуйте, iLikeCookies, Вы писали:

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


MTD>>В новом языке не надо делать общий базовый класс — это просто глупо. Пусть программист осознанно обогащает свои классы реализуя необходимые интерфейсы.


LC>Ага, конечно! Все кругом дураки, один MTD у нас самый умный, надо было у него спросить создателям Java/.NET. Как домашнее задание, предлагаю подумать на тему, почему все современные языки делают именно один общий базовый класс. Еще предлагаю подумать в качестве подсказки на тему, почему в C++, где нет единого общего корня, разные библиотеки так или иначе создают один базовый класс и какие недостатки у такого подхода.


С++, во-первых, появился после языков, в которых был общий предок для всего. Так что мимо.
Во-вторых, не считая уже упомянутой STL, вот есть коллекция из почти полутора сотен С++ библиотек — называется Boost. Покажи мне, где там библиотеки "так или иначе создают один базовый класс". (Подсказка 1 — в С++ есть шаблоны, так что общий базовый класс нафиг не нужен. Подсказка 2 — шаблоны обычно пишут так, чтоб они работали и со встроенными типами вроде int тоже.)
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[6]: Универсальный базовый класс
От: jazzer Россия Skype: enerjazzer
Дата: 06.08.13 05:00
Оценка: +2
Здравствуйте, lazy/cjow/rhrr, Вы писали:

LCR>Функциональный стиль ничем не хуже ООП-шного стиля, однако я не берусь сейчас определять это отношение "хуже-лучше". Примем на данный момент, что такой стиль — просто другой, для написания программ в таком стиле C++ подходит довольно хреновенько, Java совсем уныло выглядит, C# несколько лучше.


LCR>Почему шаблоны C++ являются плохой эмуляцией параметрического полиморфизма? Очень легко:

LCR>
LCR>template <typename T> T id(T x){ return x; }
LCR>template <typename T> T plus(T x){ return x + x; }
LCR>

LCR>в C++ных терминах тип у id и plus одинкаовый. Однако в терминах языка с правильной системой типов типы этих функций кардинально различаются:
LCR>
LCR>id :: a -> a
LCR>plus :: (Num a) => a -> a
LCR>

LCR>И это только вершина айсберга...

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

Зачем нам нужна система типов? Чтоб ловить ошибки, правильно? Ну так в случае с шаблоном ошибка будет выловлена в момент инстанцирования, если тип Т не поддерживает сложение. Т.е. если T plus(T x){ return x + x; } скомпилировалась с каким-то типом, то этот тип автоматически будет Num, просто по факту успешной компиляции x + x. И это работает сквозь всю цепочку инстанцирования, т.е. этот x + x может быть закопан на какой угодно глубине.

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

Так что в плюсах у тебя полная свобода — можешь не делать никаких проверок и тогда компилятор будет разбираться с ошибками инстанцирования по факту инстанцирования (и, соответственно, это всегда можно хакнуть при помощи специализации).
А можно всунуть явную проверку типа, чтоб код не компилировался независимо от того, используется внутри функции плюс или нет.
А можно устроить перегрузку по свойствам типа, т.е. если Num — то одно, а если только Ord — то другое. Не уверен, что в Хаскелле можно делать перегрузку по классам типов.
Причем когда в С++ примут концепции (concepts), то это можно будет выражать более явно (это по сути и есть классы типов). Но почти все можно сделать и сейчас.

Ну и в С++ ты можешь пользоваться любым полиморфизмом, и статическим, и динамическим, и проводить границу между ними там, где тебе удобно в данной ситуации — язык не заставляет тебя пользоваться только чем-то одним.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: Универсальный базовый класс
От: iLikeCookies  
Дата: 04.08.13 04:53
Оценка: 1 (1)
Здравствуйте, MTD, Вы писали:

MTD>В новом языке не надо делать общий базовый класс — это просто глупо. Пусть программист осознанно обогащает свои классы реализуя необходимые интерфейсы.


Ага, конечно! Все кругом дураки, один MTD у нас самый умный, надо было у него спросить создателям Java/.NET. Как домашнее задание, предлагаю подумать на тему, почему все современные языки делают именно один общий базовый класс. Еще предлагаю подумать в качестве подсказки на тему, почему в C++, где нет единого общего корня, разные библиотеки так или иначе создают один базовый класс и какие недостатки у такого подхода.
Re[5]: Универсальный базовый класс
От: maxkar  
Дата: 04.08.13 19:36
Оценка: +1
Здравствуйте, AlexRK, Вы писали:

LCR>>Опять попытка вытянуть информацию о поведении. Ложки нет!

ARK>И опять не понял. Так что все же функция будет делать с "любыми объектами"?

Биндинг она динамический будет делать, допустим.

Reactive.bind(someFunction,functionArg1, functionArg2, functionArgN). someFunction — функция с N аргументами. Аргументы — либо "аргументы" функции, либо "реактивные" значения (могут изменятсья) с типом Reactive<T>. Результат бинда — значение типа Reactive<ReturnTypeOf<someFunction>>. Функция bind — одна. Макросами реализовывать не предлагать — не интересно. Да и обходить плохую систему типов языка макросами — чит.

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

В конце концов функция может просто игнорировать свои аргументы. Это тоже периодически нужно (особенно если какой-нибудь сторонний фреймворк подсовывает ненужные аргументы).
Re[5]: Универсальный базовый класс
От: iLikeCookies  
Дата: 05.08.13 09:06
Оценка: +1
Здравствуйте, AlexRK, Вы писали:

MTD>>>Ты уверен, что кастрюля и ворона имеют одного предка?

LC>>Имеют, они оба материальные объекты реального мира. Они даже имеют общие атрибуты, такие как вес, плотность итд.
ARK>Тогда надо создавать предка "Материальный объект реального мира" и наследовать от него кастрюлю с вороной. А глобальный общий предок не нужен.

Это все словоблудие, мы ж тут вроде все инженеры собрались, тут вопрос другой, насколько удобен и наиболее подходит этот самый подход. Почему в каком либо языке или среде сделано так или иначе, нужно такой вопрос не отрываясь от исторических факторов, что повлияли на тот или иной выбор.
Re[2]: Универсальный базовый класс
От: MTD https://github.com/mtrempoltsev
Дата: 05.08.13 10:41
Оценка: +1
Здравствуйте, iLikeCookies, Вы писали:

LC>Ага, конечно! Все кругом дураки, один MTD у нас самый умный


Давай без эмоций?

LC>надо было у него спросить создателям Java/.NET.


Java вообще сконструирована не самым удачным образом, почему разработчики C# удачно улучшив во многих местах Java оставили косяк с общим предком не знаю

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


Это какие?

LC>Еще предлагаю подумать в качестве подсказки на тему, почему в C++, где нет единого общего корня, разные библиотеки так или иначе создают один базовый класс и какие недостатки у такого подхода.


Чаще всего эти библиотеки создавались тогда, когда на С++ еще не умели программировать (компиляторы были плохими) и тащили туда свои привычки из других языков.
Re[4]: Универсальный базовый класс
От: jazzer Россия Skype: enerjazzer
Дата: 05.08.13 11:03
Оценка: +1
Здравствуйте, iLikeCookies, Вы писали:

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


J>>С++, во-первых, появился после языков, в которых был общий предок для всего. Так что мимо.


LC>Да неужели? .NET/Java появились позже C++. Также, скорее всего тут нужно было сохранять обратную совместимость с языком С.


Smalltalk

Никакой обратной совместимости с Си в плане классов быть не может в принципе, потому что там классов нету. Не с чем совместимость обеспечивать. Так что можно было и с общим классом придумать, и без него. Спасибо, Бьярне, что избавил нас от этой напасти!

J>>Во-вторых, не считая уже упомянутой STL, вот есть коллекция из почти полутора сотен С++ библиотек — называется Boost. Покажи мне, где там библиотеки "так или иначе создают один базовый класс". (Подсказка 1 — в С++ есть шаблоны, так что общий базовый класс нафиг не нужен. Подсказка 2 — шаблоны обычно пишут так, чтоб они работали и со встроенными типами вроде int тоже.)


LC>Насчет Boost не знаю, но STL написана в функциональном стиле. Также я тут уже приводил примеры библиотек с общим предком: MFC — CObject, COM/ATL/WTL — IUnknown, Qt — QObject итд.


COM — это бинарный протокол, а не библиотека, так что мимо. А остальные (MFC, Qt) — ну да, целых две, по сравнению с полутораста библиотеками Boost.
Да даже и в MFC, например, CString не наследовался от CObject. Так что CObject не является универсальным базовым классом, в отличие от Java, в которой java.lang.String — наследница java.lang.Object.

LC>Также, вспоминая те годы, когда я работал C++ программистом занимался интеграцией разработок нескольких наших отделов, где в каждом отделе своя иерархия классов. Вот где действительно был трэш, угар и содомия. Я сам лично вообще противник наследования реализации, композиция — наше все!


Не, если ты работал на С++ в 90-х, когда под ООП в С++ подразумевали сплошную виртуальщину и развесистые иерархии в стиле Smalltalk (типа MFC), то да. Только вот мы уже не то что в следующем десятилетии — через десятилетие живем
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[5]: Универсальный базовый класс
От: lazy/cjow/rhrr Россия lj://_lcr_
Дата: 05.08.13 14:02
Оценка: +1
AlexRK,

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

ARK>>>Я считаю, что это неправильное решение.
LC>>А обосновать?
ARK>Бесполезная вещь, способствует понижению качества кода из-за необходимости кастов.

ARK> Лично я на практике особого удобства от этого не вижу. А вижу спроектированные через зад библиотеки, требующие во всех местах кастов от объекта к чему-то.


Я вижу тут явную ошибку в рассуждениях "общий предок object => необходимость даункастов". Необходимость даункастов — это прямое следствие сабтайпинг полиморфизма, а не наличия общего предка.
Даже если общего предка не будет, даункасты никуда не денутся:
Listener ==> CascadeListener
Runnable ==> TimerRunnable
FlowProcess ==> FlowProcessWrapper
Serializable ==> MyStruct1
и так далее. Всегда есть границы модулей, через которые информацию о типах передать невозможно, отсюда и необходимость даункастов. Если ты захочешь и последний тезис оспорить, дескать "всегда всё возможно, просто некоторым лень" — подумай, готов ли ты перекомпилировать весь проект, когда меняешь один div в Razor шаблоне?
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[7]: Универсальный базовый класс
От: maxkar  
Дата: 05.08.13 15:38
Оценка: +1
Здравствуйте, AlexRK, Вы писали:

ARK>О наличии каких-либо преимуществ у общего базового типа в языке с хорошими генериками мне неизвестно (по-моему, таких преимуществ нет).

А там динамика и reflection есть в тех языках? Я пока не представляю, как вы в системе с хорошими и строгими generic'ами сделаете reflection (о first-class types я пока ничего не слышал). Какой у него будет API? Хотя бы у банального lookup метода и вызова метода. Я вот предлагал вам реализовать DI-конейнер. Уточню — нужно делать DI-контейнер, который создает приложение по внешнему текстовому описанию. Т.е. не напрямую кодом (где типы живут и проверяются компилятором), а с использованием чего-то "обобщенного". Ну не хватит вам "языка с хорошими генериками" для выражения типов "из внешнего источника". Если, конечно, вы не говорите о языках с зависимыми типами и им подобной маргинальщине. У них минусы в большом объеме кода для "доказательства типов".
Re[7]: Универсальный базовый класс
От: MxMsk Португалия  
Дата: 09.08.13 20:18
Оценка: +1
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>То что тут пытаются засунуть все полезные вещи которые работают с универсальной ручкой (типа кастов, которые, afaik, и в Java и в C#, не то что подрожают синтаксису функции, а вообще — являются отдельной синтаксической конструкцией) в базовый класс — так это от бедности языка, были бы нормальные non-member functions — было бы попроще. Такие функции всё равно не будут, например, виртуальными (а-ля Object.getClass в Java), и всё равно реализуются средой, а не средствами языка.

А причем здесь non-member functions? Они же есть в виде статических методов статических классов. И потом, помимо GetType(), есть еще GetHashCode и ToString, которые вполне себе виртуальные.

EP>Более того, засовывая такие вещи в базовый класс — автоматом теряется возможность использования нормального синтаксиса для чего-то типа мультиметодов — например Object.equals(Object obj) это то ещё уродство.

EP>Каких-то убедительных доводов в пользу именно единого предка — я тут не видел
Да аргументы против тоже как-то больше сводятся к тому, как сделано в любимом языке.
Re[14]: Универсальный базовый класс
От: Evgeny.Panasyuk Россия  
Дата: 12.08.13 20:39
Оценка: +1
Здравствуйте, MxMsk, Вы писали:

MM>>>Хуже чем что?

EP>>Хуже чем то, как оно сделано сейчас.
MM>Я потерял нить. Мой первоначальный ответ был на:
MM>

были бы нормальные non-member functions — было бы попроще

MM>Такие функции есть. Что они могли бы упростить?

GetClass(object);

Зачем GetClass в едином базовом классе?
Автор: Evgeny.Panasyuk
Дата: 09.08.13


EP>>А сделать TotallyOrdered сравнение? Сделать swap и т.п.? Всё тащить в единый базовый класс?

MM>Конечно, любую идею можно довести до маразма.

А в чём маразм? В том что нужно TotallyOrdered сравнение для типов?
Или в том что нужен самый базовый permutation алгоритм — swap?

MM>>>Чем альтернатива будет лучше?

EP>>Например, явно указать какие интерфейсы наследовать (либо целые группы), какие default либо custom реализации использовать (через compile-time reflection например).
MM>Ну и станут эти интерфейсы такими же базовыми классами, только раскиданными по проекту от балды. Еще хуже, когда понадобиться положить в HashTable сторонний объект, разработчик которого не стал заморачиваться с хэш-кодом. Боюсь, обрастем костылями.

Нельзя каждую полезную штуку положить в базовый класс.
Где, например Total Order? Всё, "обрастаем костылями"?

EP>>Лучше тем что гибче, не засоряет виртуальные таблицы каждого класса сотнями "типа полезных" всемогутеров, которые далеко не всегда нужны.

MM>Так нет же этих сотен. Зачем приписывать разработчикам языков то, чего они не делают?

Тебе нужен GetHashCode, кому-то нужен Totall Order (для достижения лучшей worst case complexity, или например генерации перестановок), кому-то нужен foo, кому-то нужен bar — как выбрать то, что должно быть в едином базовом классе?
Re: Универсальный базовый класс
От: A13x США  
Дата: 27.07.13 20:03
Оценка:
Здравствуйте, MTD, Вы писали:

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


A>>...


MTD>В новом языке не надо делать общий базовый класс — это просто глупо. Пусть программист осознанно обогащает свои классы реализуя необходимые интерфейсы.


Это спорное утверждение

Отчасти я с ним согласен с точки зрения "обогащения" функционала, но все же я считаю, что базовый класс необходим, но только с одним методом — getClass() или getTypeMirror() — последнее это из альтернативной модели RTTI — Type Mirror.
Re[5]: Универсальный базовый класс
От: A13x США  
Дата: 29.07.13 07:58
Оценка:
Здравствуйте, MTD, Вы писали:

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


MTD>>>Ты уверен, что кастрюля и ворона имеют одного предка?


A>>Ну это уже софистика. В определенных задачах — думаю да, в некоторых задачах это возможно вообще будет один и тот же объект.


MTD>void* в C, Object в Java — это просто дыра в безопасности, при отсутствии ощутимой выгоды.


Для С — согласен, для Java — не понимаю — почему сделан такой вывод. void* не хранит информации о типе и нет возможности выполнить safe cast, для Object это не так, что меняет дело, разве нет?
Re[7]: Универсальный базовый класс
От: A13x США  
Дата: 29.07.13 08:44
Оценка:
Здравствуйте, MTD, Вы писали:

MTD>...


MTD>Любой каст — потенциальная ошибка. По мне так лучше во время компиляции будет проверен тип, нежели в рантайме полетит исключение.

MTD>Про "особые" случаи поделитесь?

Мне представляется, что это было бы полезным для AOP (см. например тут). Например аспект логирования — для описания обобщенного обработчика логгера удобно оперировать такой конструкцией:

    public void before(JoinPoint joinPoint) {
        final Object[] args = joinPoint.getArgs();
        //...
        if (args.length > 0) {
            boolean next = false;
            for (final Object arg : args) {
                if (next) {
                    stringifier.append(", ");
                } else {
                    next = true;
                }

                stringifier.append(arg);
            }
        }
        //...
    }
Re[8]: Универсальный базовый класс
От: MTD https://github.com/mtrempoltsev
Дата: 29.07.13 08:51
Оценка:
Здравствуйте, A13x, Вы писали:

A>Например аспект логирования — для описания обобщенного обработчика логгера удобно оперировать такой конструкцией:


Для этого случая Object совершенно не оправдан. Какие типы объектов можно передать в логгер? Очевидно, те которые можно напечатать. Поэтому логично работать с интерфейсом, скажем Printable.
Re[9]: Универсальный базовый класс
От: A13x США  
Дата: 29.07.13 08:59
Оценка:
Здравствуйте, MTD, Вы писали:

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


A>>Например аспект логирования — для описания обобщенного обработчика логгера удобно оперировать такой конструкцией:


MTD>Для этого случая Object совершенно не оправдан. Какие типы объектов можно передать в логгер? Очевидно, те которые можно напечатать. Поэтому логично работать с интерфейсом, скажем Printable.


А если сервис сторонний, а логировать хочется? Писать сервис-делегат с адаптерами поверх non-printable объектов?
Вообще, мы несколько отклонились от темы — предлагаю отделить ветку с названием вида — "Нужен ли единый базовый класс".
Re[10]: Универсальный базовый класс
От: MTD https://github.com/mtrempoltsev
Дата: 29.07.13 09:07
Оценка:
Здравствуйте, A13x, Вы писали:

MTD>>Для этого случая Object совершенно не оправдан. Какие типы объектов можно передать в логгер? Очевидно, те которые можно напечатать. Поэтому логично работать с интерфейсом, скажем Printable.


A>А если сервис сторонний, а логировать хочется? Писать сервис-делегат с адаптерами поверх non-printable объектов?


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

A>Вообще, мы несколько отклонились от темы — предлагаю отделить ветку с названием вида — "Нужен ли единый базовый класс".


Да.
Re[3]: Универсальный базовый класс
От: SV.  
Дата: 04.08.13 00:16
Оценка:
Здравствуйте, MTD, Вы писали:

A>>я считаю, что базовый класс необходим


MTD>Ты уверен, что кастрюля и ворона имеют одного предка?


Кастрюля — слово из восьми букв, ворона — слово из шести букв. А, вы на них не смотрите как на слова? Ну вот и на GetType() смотрите не как на реальное свойство вороны или, там, коровы, а как на чисто техническое, которое упихали туда же, куда и настоящие свойства. Испортили чистоту моделирования, но ведь в наших программах мы все еще имеем дело со словами, а не с реальными объектами. Куда деваться.
Re[3]: Универсальный базовый класс
От: iLikeCookies  
Дата: 04.08.13 04:44
Оценка:
Здравствуйте, MTD, Вы писали:

MTD>Ты уверен, что кастрюля и ворона имеют одного предка?


Имеют, они оба материальные объекты реального мира. Они даже имеют общие атрибуты, такие как вес, плотность итд.
Re[2]: Универсальный базовый класс
От: Ops Россия  
Дата: 04.08.13 14:02
Оценка:
Здравствуйте, iLikeCookies, Вы писали:

LC>Еще предлагаю подумать в качестве подсказки на тему, почему в C++, где нет единого общего корня, разные библиотеки так или иначе создают один базовый класс и какие недостатки у такого подхода.


А нет никаких недостатков. Зато есть преимущество, когда эти базовые классы из разных библиотек, и не имеющих между собой ничего общего, не скрещиваются насильно.
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re[2]: Универсальный базовый класс
От: minorlogic Украина  
Дата: 04.08.13 15:55
Оценка:
Здравствуйте, A13x, Вы писали:

A>Отчасти я с ним согласен с точки зрения "обогащения" функционала, но все же я считаю, что базовый класс необходим, но только с одним методом — getClass() или getTypeMirror() — последнее это из альтернативной модели RTTI — Type Mirror.


Чем это лучше , дать програмиств решать наследоваться от этого интерфейса или нет ?
... << RSDN@Home 1.2.0 alpha 5 rev. 1539>>
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[2]: Универсальный базовый класс
От: AlexRK  
Дата: 04.08.13 17:45
Оценка:
Здравствуйте, lazy/cjow/rhrr, Вы писали:

LCR>Среди выигрышей:

LCR>1. определение функций, которые выполняют общие трансформации кода работающие для любых объектов (рефлекшн, рантайм-макросы)

Generic-функции.

LCR>2. определение функций, принимающих любой объект или последовательность объектов (например, логгер, Runnable)


И чо они будут делать с "любым объектом"? А вот Runnable — это уже не любой объект.

LCR>3. определение функций, возвращающих любой объект (например фабрики, ioc контейнеры)


Возврат любого объекта также бессмысленен. Нужен хотя бы интерфейс.

LCR>При достаточно развитой системы типов, некоторые из определений возможно бывает написать без object, используя разные продвинутые конструкции (см. например опредление функции map в Scala), но в общем случае нет.


В общем случае базовый предок не нужен.

LCR>Также из-за перегрузки становится невозможным описать тип "функция, принимающая любое количество любых аргументов", вместо этого в библиотеках постоянно фигурируют fun(a1); fun(a1, a2); ... fun(a1, a2, ..., a100500), я нахожу этот момент крайне неудобным.


А что функция будет делать с любыми объектами? Вызывать для них метод ToString? ИМХО, натянутый пример, особенно если учесть, что объект может иметь несколько строковых представлений.

LCR>Какое это имеет отношение к топику? А такое, что понятие "список аргументов функции" не является объектом, и это порождает определённые неудобства, которые вполне реальные


Какие например?
Re[3]: Универсальный базовый класс
От: Философ Ад http://vk.com/id10256428
Дата: 04.08.13 17:51
Оценка:
Здравствуйте, MTD, Вы писали:

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


A>>я считаю, что базовый класс необходим


MTD>Ты уверен, что кастрюля и ворона имеют одного предка?


смотря что ты моделируешь.
Всё сказанное выше — личное мнение, если не указано обратное.
Re[2]: Универсальный базовый класс
От: Философ Ад http://vk.com/id10256428
Дата: 04.08.13 17:54
Оценка:
Здравствуйте, A13x, Вы писали:

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


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


A>>>...


MTD>>В новом языке не надо делать общий базовый класс — это просто глупо. Пусть программист осознанно обогащает свои классы реализуя необходимые интерфейсы.


A>Это спорное утверждение


A>.... но все же я считаю, что базовый класс необходим, но только с одним методом — getClass() или getTypeMirror()...


необходим метод Destroy() (деструктор)
зело полезен для написания всевозможных менеджеров/кэшей/IPC...
Всё сказанное выше — личное мнение, если не указано обратное.
Re[3]: Универсальный базовый класс
От: lazy/cjow/rhrr Россия lj://_lcr_
Дата: 04.08.13 18:20
Оценка:
AlexRK,

LCR>>Среди выигрышей:

LCR>>1. определение функций, которые выполняют общие трансформации кода работающие для любых объектов (рефлекшн, рантайм-макросы)
ARK>Generic-функции.
Определённые исследования ведутся в области typesafe макросов, конечно, но пока то, что я видел функции-трансформаторы имеют слишком дикую сигнатуру и делать так можно только в простых случаях. Generics слишком тощие, чтобы осилить Динамические прокси, АОП, сериализаторы/десериализаторы делаются и уж тем более кодогенерацию.

LCR>>2. определение функций, принимающих любой объект или последовательность объектов (например, логгер, Runnable)

ARK>И чо они будут делать с "любым объектом"? А вот Runnable — это уже не любой объект.
LCR>>3. определение функций, возвращающих любой объект (например фабрики, ioc контейнеры)
ARK>Возврат любого объекта также бессмысленен. Нужен хотя бы интерфейс.

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

Runnable — пример, когда можно сделать только одно, довольно слабое предполжение о поведении. Проблемы те же.

Если ты вернёшь "хотя бы интерфейс" из своего IOC контейнера, ты тем самым автоматически сделаешь невозможным работу с объектами, которые не реализуют этот интерфейс. Это породит ситуацию, что как только я захочу использовать твой контейнер, я должен все объекты пометить этим интерфейсом. Это неудобно, и поэтому я буду использовать другой.


LCR>>Также из-за перегрузки становится невозможным описать тип "функция, принимающая любое количество любых аргументов", вместо этого в библиотеках постоянно фигурируют fun(a1); fun(a1, a2); ... fun(a1, a2, ..., a100500), я нахожу этот момент крайне неудобным.

ARK>А что функция будет делать с любыми объектами? Вызывать для них метод ToString? ИМХО, натянутый пример, особенно если учесть, что объект может иметь несколько строковых представлений.

Опять попытка вытянуть информацию о поведении. Ложки нет!

LCR>>Какое это имеет отношение к топику? А такое, что понятие "список аргументов функции" не является объектом, и это порождает определённые неудобства, которые вполне реальные


ARK>Какие например?


Реализуй мне класс Tuple<..>
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[4]: Универсальный базовый класс
От: AlexRK  
Дата: 04.08.13 19:11
Оценка:
Здравствуйте, lazy/cjow/rhrr, Вы писали:

LCR>Generics слишком тощие, чтобы осилить Динамические прокси, АОП, сериализаторы/десериализаторы делаются и уж тем более кодогенерацию.


Эм... а что, общий базовый тип Object это все осиливает?
Вроде разговор был про другое...

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

LCR>Runnable — пример, когда можно сделать только одно, довольно слабое предполжение о поведении. Проблемы те же.

Прошу прощения, ничего не понял.

LCR>Если ты вернёшь "хотя бы интерфейс" из своего IOC контейнера, ты тем самым автоматически сделаешь невозможным работу с объектами, которые не реализуют этот интерфейс. Это породит ситуацию, что как только я захочу использовать твой контейнер, я должен все объекты пометить этим интерфейсом. Это неудобно, и поэтому я буду использовать другой.


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

LCR>Опять попытка вытянуть информацию о поведении. Ложки нет!


И опять не понял. Так что все же функция будет делать с "любыми объектами"?

LCR>Реализуй мне класс Tuple<..>


А может реализовать класс Class или класс Struct?
Тупл должен быть первоклассной сущностью, без поддержки компилятора он будет ужасно коряв. А раз так, нет необходимости иметь его описание на языке.
А других, более жизненных, примеров нет?
Re[6]: Универсальный базовый класс
От: AlexRK  
Дата: 04.08.13 20:27
Оценка:
Здравствуйте, maxkar, Вы писали:

ARK>>И опять не понял. Так что все же функция будет делать с "любыми объектами"?


M>Биндинг она динамический будет делать, допустим.


M>Reactive.bind(someFunction,functionArg1, functionArg2, functionArgN). someFunction — функция с N аргументами. Аргументы — либо "аргументы" функции, либо "реактивные" значения (могут изменятсья) с типом Reactive<T>. Результат бинда — значение типа Reactive<ReturnTypeOf<someFunction>>. Функция bind — одна. Макросами реализовывать не предлагать — не интересно. Да и обходить плохую систему типов языка макросами — чит.


Так все равно тут общий предок не нужен, просто это должна быть генерик-функция. Это если рассматривать только момент с "любыми объектами", не касаясь другого вопроса — произвольного количества аргументов, который, на мой взгляд, очень сомнителен сам по себе.
Re[3]: Универсальный базовый класс
От: iLikeCookies  
Дата: 05.08.13 02:05
Оценка:
Здравствуйте, AlexRK, Вы писали:

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

ARK>Я считаю, что это неправильное решение.

А обосновать?

LC>>Еще предлагаю подумать в качестве подсказки на тему, почему в C++, где нет единого общего корня, разные библиотеки так или иначе создают один базовый класс и какие недостатки у такого подхода.

ARK>Ну вот пусть и создают базовый класс там, где он нужен, а в язык его пихать зачем?

Короткий ответ, потому что на практике это очень удобно. Длинный ответ писать лень.
Re[3]: Универсальный базовый класс
От: iLikeCookies  
Дата: 05.08.13 02:42
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Где, например, в STL единый базовый класс?


STL написана в функциональном стиле. Посмотри например на MFC с его CObject, COM/ATL/WTL — с их IUnknown, Qt с его QObject итд.
Re[4]: Универсальный базовый класс
От: Evgeny.Panasyuk Россия  
Дата: 05.08.13 03:37
Оценка:
Здравствуйте, iLikeCookies, Вы писали:

EP>>Где, например, в STL единый базовый класс?

LC>STL написана в функциональном стиле.

Что ты понимаешь под функциональным стилем (учитывая такие вещи как std::sort, std::vector и т.п.)?
То что используются функции высших порядков?
Или то что std::sort не засунута в класс и работает по чётным и нечётным?

Какие именно свойства стиля, о котором ты говоришь, позволяют обходится без общего корня?
И чем, по-твоему, такой стиль хуже стиля для которого общие корни нужны?
Re[4]: Универсальный базовый класс
От: AlexRK  
Дата: 05.08.13 05:43
Оценка:
Здравствуйте, iLikeCookies, Вы писали:

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


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

ARK>>Я считаю, что это неправильное решение.

LC>А обосновать?


Бесполезная вещь, способствует понижению качества кода из-за необходимости кастов.

LC>>>Еще предлагаю подумать в качестве подсказки на тему, почему в C++, где нет единого общего корня, разные библиотеки так или иначе создают один базовый класс и какие недостатки у такого подхода.

ARK>>Ну вот пусть и создают базовый класс там, где он нужен, а в язык его пихать зачем?

LC>Короткий ответ, потому что на практике это очень удобно. Длинный ответ писать лень.


Лично я на практике особого удобства от этого не вижу. А вижу спроектированные через зад библиотеки, требующие во всех местах кастов от объекта к чему-то.
Re[3]: Универсальный базовый класс
От: iLikeCookies  
Дата: 05.08.13 09:20
Оценка:
Здравствуйте, jazzer, Вы писали:

J>С++, во-первых, появился после языков, в которых был общий предок для всего. Так что мимо.


Да неужели? .NET/Java появились позже C++. Также, скорее всего тут нужно было сохранять обратную совместимость с языком С.

J>Во-вторых, не считая уже упомянутой STL, вот есть коллекция из почти полутора сотен С++ библиотек — называется Boost. Покажи мне, где там библиотеки "так или иначе создают один базовый класс". (Подсказка 1 — в С++ есть шаблоны, так что общий базовый класс нафиг не нужен. Подсказка 2 — шаблоны обычно пишут так, чтоб они работали и со встроенными типами вроде int тоже.)


Насчет Boost не знаю, но STL написана в функциональном стиле. Также я тут уже приводил примеры библиотек с общим предком: MFC — CObject, COM/ATL/WTL — IUnknown, Qt — QObject итд.

Также, вспоминая те годы, когда я работал C++ программистом занимался интеграцией разработок нескольких наших отделов, где в каждом отделе своя иерархия классов. Вот где действительно был трэш, угар и содомия. Я сам лично вообще противник наследования реализации, композиция — наше все!
Re[6]: Универсальный базовый класс
От: Jack128  
Дата: 05.08.13 11:33
Оценка:
Здравствуйте, lazy/cjow/rhrr, Вы писали:


LCR>Почему шаблоны C++ являются плохой эмуляцией параметрического полиморфизма? Очень легко:

LCR>
LCR>template <typename T> T id(T x){ return x; }
LCR>template <typename T> T plus(T x){ return x + x; }
LCR>

LCR>в C++ных терминах тип у id и plus одинкаовый.
Разве в С++ у id и plus есть тип?? это же шаблоны.
Re[6]: Универсальный базовый класс
От: AlexRK  
Дата: 05.08.13 11:46
Оценка:
Здравствуйте, iLikeCookies, Вы писали:

LC>Это все словоблудие, мы ж тут вроде все инженеры собрались, тут вопрос другой, насколько удобен и наиболее подходит этот самый подход.


Вопрос удобства весьма субъективен. Кому-то и за типами следить неудобно.
А из измеряемых величин вполне можно выделить "число кастов от предка к потомку", которое общий базовый тип очевидно увеличивает, что плохо.
О наличии каких-либо преимуществ у общего базового типа в языке с хорошими генериками мне неизвестно (по-моему, таких преимуществ нет).

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


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

Если в языке нет функционального типа, то остается использовать указатели. Из этого не следует, что указатели на функции — это хорошо. Это просто неизбежное зло, если мы хотим программировать на таком языке. ИМХО, с базовым типом то же самое — это признак недодуманности дизайна языка, закрывающий либо какие-то дырки в этом самом дизайне, либо legacy-проблемы.
Re[7]: Универсальный базовый класс
От: lazy/cjow/rhrr Россия lj://_lcr_
Дата: 05.08.13 13:46
Оценка:
Jack128,

LCR>>Почему шаблоны C++ являются плохой эмуляцией параметрического полиморфизма? Очень легко:

LCR>>
LCR>>template <typename T> T id(T x){ return x; }
LCR>>template <typename T> T plus(T x){ return x + x; }
LCR>>

LCR>>в C++ных терминах тип у id и plus одинкаовый.
J>Разве в С++ у id и plus есть тип?? это же шаблоны.

А, я понял, что так развеселило MTD и jazzer-а. У шаблонных функций (и классов) C++-ного типа нет, пока он не инстанцирован — это безтиповая символьная конструкция. Просто чтобы показать кусок от параметрического полиморфизма, доступный в C++, мне нужно установить в соответствие между обобщённым типом в ML и его аналогом в определениях выше. Так что аналогом типа a->a является... ну штуковина T (*fn)(T) для шаблонов.
Может эта штуковина имеет какое-то устоявшееся название, я не в курсе.
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[8]: Универсальный базовый класс
От: MTD https://github.com/mtrempoltsev
Дата: 05.08.13 14:00
Оценка:
Здравствуйте, lazy/cjow/rhrr, Вы писали:

LCR>У шаблонных функций (и классов) C++-ного типа нет, пока он не инстанцирован — это безтиповая символьная конструкция.


А Java кода нет, пока он не написан. Какие выводы ты сделаешь из этого?
Re[6]: Универсальный базовый класс
От: AlexRK  
Дата: 05.08.13 15:15
Оценка:
Здравствуйте, lazy/cjow/rhrr, Вы писали:

LCR>Я вижу тут явную ошибку в рассуждениях "общий предок object => необходимость даункастов". Необходимость даункастов — это прямое следствие сабтайпинг полиморфизма, а не наличия общего предка.


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

LCR>Даже если общего предка не будет, даункасты никуда не денутся:


В целом их будет гораздо меньше.

А кое-где можно и обойти это полностью:

  public T GetListener<T>() where T : Listener, new()
  {
    ...
  }

  var cascadeListener = GetListener<CascadeListener>();


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


Эээ... почему это невозможно? Даже в веб-сервисах передается через генерацию прокси-объектов.

LCR>Если ты захочешь и последний тезис оспорить, дескать "всегда всё возможно, просто некоторым лень" — подумай, готов ли ты перекомпилировать весь проект, когда меняешь один div в Razor шаблоне?


А вы готовы перекомпилировать весь проект, когда меняете тип одного параметра одной функции с int на string?
Re[7]: Универсальный базовый класс
От: lazy/cjow/rhrr Россия lj://_lcr_
Дата: 05.08.13 15:33
Оценка:
AlexRK,

ARK>Тем не менее, наличие общего предка однозначно _поощряет_ даункасты и делает их возможными там, где без общего предка это невозможно.


Я всё что хотел донести — написал выше, а победить в споре у меня цели нет. Успехов в программировании.
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[2]: Универсальный базовый класс
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 05.08.13 16:05
Оценка:
Здравствуйте, iLikeCookies, Вы писали:

LC>Ага, конечно! Все кругом дураки, один MTD у нас самый умный, надо было у него спросить создателям Java/.NET.


В Java и .NET на общий базовый класс е5сть свои причины. В дотнете в первой версии не было дженериков, а в джаве нормальных дженериков нет до сих пор.

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


Все ли?
... << RSDN@Home 1.2.0 alpha 5 rev. 100 on Windows 8 6.2.9200.0>>
AVK Blog
Re[5]: Универсальный базовый класс
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 05.08.13 16:14
Оценка:
Здравствуйте, AlexRK, Вы писали:

ARK>Бесполезная вещь, способствует понижению качества кода из-за необходимости кастов.


Тут вроде бы уже задали вопрос — а как будет выглядеть вызов метода через рефлекшен? Сейчас это выглядит так:
public:
virtual Object^ Invoke(
    Object^ obj, 
    array<Object^>^ parameters
) sealed

void* в безопасных языках нет.
... << RSDN@Home 1.2.0 alpha 5 rev. 100 on Windows 8 6.2.9200.0>>
AVK Blog
Re[8]: Универсальный базовый класс
От: AlexRK  
Дата: 05.08.13 16:47
Оценка:
Здравствуйте, maxkar, Вы писали:

M>А там динамика и reflection есть в тех языках? Я пока не представляю, как вы в системе с хорошими и строгими generic'ами сделаете reflection (о first-class types я пока ничего не слышал).


Динамику и рефлекшен, конечно, никак. (Вообще лично я противник и того, и другого, но мнение свое никому не навязываю.) А нужен ли для этого общий предок? Чего-то типа rtti(myObj).GetFields не подойдет?
Re[6]: Универсальный базовый класс
От: AlexRK  
Дата: 05.08.13 16:55
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Тут вроде бы уже задали вопрос — а как будет выглядеть вызов метода через рефлекшен? Сейчас это выглядит так:


С рефлекшеном да, проблема. Мое сугубое ИМХО — лучше всего ограничиться compile-time рефлексией. Вообще, ИМХО, рефлексия это нечто находящееся вне границ системы, по теореме Геделя выразить это на языке самой системы нельзя. Ну а если однозначно нужна runtime рефлексия, то выходов немного — либо встраивать прямо в язык каким-то образом (а-ля новые ключевые слова и т.п.), либо таки делать этого пресловутого общего предка.
Re[3]: Универсальный базовый класс
От: Mystic Украина http://mystic2000.newmail.ru
Дата: 05.08.13 17:10
Оценка:
Здравствуйте, AlexRK, Вы писали:


LCR>>2. определение функций, принимающих любой объект или последовательность объектов (например, логгер, Runnable)

ARK>И чо они будут делать с "любым объектом"? А вот Runnable — это уже не любой объект.
Передавать обратно в callback-и или заполнять поля для хранения пользовательских данных.

LCR>>3. определение функций, возвращающих любой объект (например фабрики, ioc контейнеры)

ARK>Возврат любого объекта также бессмысленен. Нужен хотя бы интерфейс.
Угу, пустой интерфейс, который потом приводи к нужному и поддерживай в полном соответствии с объектом.
Re[4]: Универсальный базовый класс
От: AlexRK  
Дата: 05.08.13 17:17
Оценка:
Здравствуйте, Mystic, Вы писали:

M>Передавать обратно в callback-и или заполнять поля для хранения пользовательских данных.


Тогда это generic-функция:

  public void Function<T, U>(T param1, U param2, Func<U, U, U, T> callback) { ... }


M>Угу, пустой интерфейс, который потом приводи к нужному и поддерживай в полном соответствии с объектом.


Пустой интерфейс, очевидно, точно так же не нужен, как и пустой объект.
Re[3]: Универсальный базовый класс
От: maxkar  
Дата: 05.08.13 17:17
Оценка:
Здравствуйте, jazzer, Вы писали:

J> Подсказка 1 — в С++ есть шаблоны, так что общий базовый класс нафиг не нужен.

Не нужен? "Шаблонопаста" — наше все? Если я правильно помню, там на каждый новый инстанс шаблона новый код генерируется. Поэтому std::vector<std::smartptr<A>> и std::vector<std::smartptr<B>> будут сгенерированы оба и будут иметь ну очень много общего кода.

Ну и пару примеров еще:
v = config.haveTooMuchMemory ? new std::vector<A, HugeMemoryAllocator>() : new std::vector<A, SmallMemoryAllocator>();

Такое вообще можно? Т.е. в рантайме выбрать аллокатор? И какой тип будет у V?

Ну и еще более интересная разновидность:
v = new std::vector<A>(new SomeAllocator(config.getAllocationPageSize));

Т.е. в рантайме передать аллокатору параметры. Или шаблоны и отсутствие общего предка (top в системе типов) этому не очень способствуют?

P.S. Синтаксис C++ не знаю, так что примеры рассматривайте как концептуальные.
Re[4]: Универсальный базовый класс
От: Evgeny.Panasyuk Россия  
Дата: 05.08.13 19:38
Оценка:
Здравствуйте, maxkar, Вы писали:

J>> Подсказка 1 — в С++ есть шаблоны, так что общий базовый класс нафиг не нужен.

M>Не нужен? "Шаблонопаста" — наше все? Если я правильно помню, там на каждый новый инстанс шаблона новый код генерируется. Поэтому std::vector<std::smartptr<A>> и std::vector<std::smartptr<B>> будут сгенерированы оба и будут иметь ну очень много общего кода.

1. Очень много кода будет заинлайнено — объём кода может быть даже меньше чем при вызовах функций (особенно учитывая несколько уровней инлайнов). Например dereference у shared_ptr производит код <b>идентичный</b> dereference обычного указателя.
2. Если генерируется идентичный бинарный код (что не редкость если используются указатели) — то он может мёрджится компилятором и линкером.
3. При необходимости возможно применение специальных техник "вручную", которые помогают уменьшить объём кода (например vector может прятать void* реализацию за тонким слоем кастов).
4. Если скорость где-то не важна, то type-erasure позволяет преодолеть комбинаторный взрыв кода с O(m*n) на O(m+n).

M>Ну и пару примеров еще:

M>
M>v = config.haveTooMuchMemory ? new std::vector<A, HugeMemoryAllocator>() : new std::vector<A, SmallMemoryAllocator>();
M>

M>Такое вообще можно? Т.е. в рантайме выбрать аллокатор?

Конечно возможно:
#include <functional>

using namespace std;

int main()
{
    volatile bool runtime_flag = true;
    function<bool(int)> predicate;
    if(runtime_flag)
        predicate = [](int){ return false; };
    else
        predicate = [](int){ return true; };
}

Типы у лямбд разные — не имеют общего предка, но типо-безопасно сохраняются в function<bool(int)>, без всяких кастов

M>И какой тип будет у V?


type-erased вестимо.

M>Ну и еще более интересная разновидность:

M>
M>v = new std::vector<A>(new SomeAllocator(config.getAllocationPageSize));
M>

M>Т.е. в рантайме передать аллокатору параметры. Или шаблоны и отсутствие общего предка (top в системе типов) этому не очень способствуют?

А что смущает? В C++11 контейнеры поддерживают statefull allocator'ы. А в C++03 они доступны через Boost.Container
Re[6]: Универсальный базовый класс
От: MTD https://github.com/mtrempoltsev
Дата: 06.08.13 04:07
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>void* в безопасных языках нет.


Это тот же Object, только без проверки.
Re[4]: Универсальный базовый класс
От: jazzer Россия Skype: enerjazzer
Дата: 06.08.13 05:13
Оценка:
Здравствуйте, maxkar, Вы писали:

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


J>> Подсказка 1 — в С++ есть шаблоны, так что общий базовый класс нафиг не нужен.

M>Не нужен? "Шаблонопаста" — наше все? Если я правильно помню, там на каждый новый инстанс шаблона новый код генерируется. Поэтому std::vector<std::smartptr<A>> и std::vector<std::smartptr<B>> будут сгенерированы оба и будут иметь ну очень много общего кода.

От которого линкер потом избавится:
http://rsdn.ru/forum/cpp.applied/5247685.1
Автор: johny5
Дата: 01.08.13


так что да, шаблоны — наше все. Кроме случаев, когда нужен рантайм-полиморфизм. Но и для него всеобщий базовый класс не нужен.

Про остальное уже написали.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[5]: Универсальный базовый класс
От: Mystic Украина http://mystic2000.newmail.ru
Дата: 06.08.13 06:49
Оценка:
Здравствуйте, AlexRK, Вы писали:

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


M>>Передавать обратно в callback-и или заполнять поля для хранения пользовательских данных.


ARK>Тогда это generic-функция:


ARK>
ARK>  public void Function<T, U>(T param1, U param2, Func<U, U, U, T> callback) { ... }
ARK>


Потом эти шаблоны нарастают как снежный ком, так что разобраться с ними становится достаточно тяжело. "Понятные" сообщения об ошибках в С++ при работе в STL как следствие. Ну и каждый должен сам выбирать тот путь, который ему нравится больше. Мне более близко по духу использование какого-нить базового класса.
Re[3]: Универсальный базовый класс
От: A13x США  
Дата: 06.08.13 10:42
Оценка:
Здравствуйте, AndrewVK, Вы писали:

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


A>>Отчасти я с ним согласен с точки зрения "обогащения" функционала, но все же я считаю, что базовый класс необходим, но только с одним методом — getClass()


AVK>Если там только один метод, то лучше его сделать оператором языка.


А что это даст?
Re[3]: Универсальный базовый класс
От: A13x США  
Дата: 06.08.13 10:43
Оценка:
Здравствуйте, Философ, Вы писали:

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


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


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


A>>>>...


MTD>>>В новом языке не надо делать общий базовый класс — это просто глупо. Пусть программист осознанно обогащает свои классы реализуя необходимые интерфейсы.


A>>Это спорное утверждение


A>>.... но все же я считаю, что базовый класс необходим, но только с одним методом — getClass() или getTypeMirror()...


Ф>необходим метод Destroy() (деструктор)

Ф>зело полезен для написания всевозможных менеджеров/кэшей/IPC...

К сожалению ветка перенесена без контекста.
В оригинале предположение было о managed языке —

http://www.rsdn.ru/forum/philosophy/5243709.1
Автор: A13x
Дата: 27.07.13

Предположим, что мы делаем некоторый язык, скажем E, похожим насколько возможно на java/C#, в котором хотим описать каким-то образом типобезопасный equals.

Re[3]: Универсальный базовый класс
От: A13x США  
Дата: 06.08.13 10:45
Оценка:
Здравствуйте, minorlogic, Вы писали:

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


A>>Отчасти я с ним согласен с точки зрения "обогащения" функционала, но все же я считаю, что базовый класс необходим, но только с одним методом — getClass() или getTypeMirror() — последнее это из альтернативной модели RTTI — Type Mirror.


M>Чем это лучше , дать програмиств решать наследоваться от этого интерфейса или нет ?


Лучше чем тут
Автор: lazy/cjow/rhrr
Дата: 04.08.13
я пожалуй не отвечу.
Ну и здесь
Автор: A13x
Дата: 29.07.13
я предполагал сходный сценарий, где это может быть полезным.
Re[4]: Универсальный базовый класс
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 06.08.13 16:08
Оценка:
Здравствуйте, A13x, Вы писали:

A>А что это даст?


Мне кажется читаемость кода будет выше — оператор явно указывает на обращение к вшитой системе типов платформы, а не просто к ординарному методу. Тем более что оператор typeof во многих статических языках есть, хотя мог бы быть, к примеру, статический метод того же базового Object. Так что добавление к нему брата-близнеца gettype будет выглядеть вполне логично. Ну и если упереться рогом в плане отказа от общего базового класса, то это почти единственный вариант.
... << RSDN@Home 1.2.0 alpha 5 rev. 100 on Windows 8 6.2.9200.0>>
AVK Blog
Re[6]: Универсальный базовый класс
От: jazzer Россия Skype: enerjazzer
Дата: 06.08.13 16:14
Оценка:
Здравствуйте, Mystic, Вы писали:

M>Потом эти шаблоны нарастают как снежный ком, так что разобраться с ними становится достаточно тяжело.

Не сложнее, чем с обычными функциями и классами. Нужен навык, но он нужен везде.

M>"Понятные" сообщения об ошибках в С++ при работе в STL как следствие.

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

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

С этим не поспоришь.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[4]: Универсальный базовый класс
От: jazzer Россия Skype: enerjazzer
Дата: 06.08.13 16:18
Оценка:
Здравствуйте, lazy/cjow/rhrr, Вы писали:

LCR>Реализуй мне класс Tuple<..>


Если чё — в С++11 он есть и выглядит вот так: template< class... Types > class tuple;
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[2]: Универсальный базовый класс
От: dimgel Россия https://github.com/dimgel
Дата: 06.08.13 19:34
Оценка:
Здравствуйте, lazy/cjow/rhrr, Вы писали:

LCR>При достаточно развитой системы типов, некоторые из определений возможно бывает написать без object, используя разные продвинутые конструкции (см. например опредление функции map в Scala), но в общем случае нет.


Хм, вот уж не ожидал, что скалу приведут как пример иерархии без Object. Как раз в скале всё на свете, а уж тем более дженерики с ихней ко/контра-вариантностью (в том числе это определение Map), прочно завязано на факт существования общего супертипа (Any, подтипом которого является AnyRef == java Object) и общего подтипа (Nothing) для всех типов. И это чертовски удобно и красиво.
Re[3]: Универсальный базовый класс
От: VladD2 Российская Империя www.nemerle.org
Дата: 06.08.13 20:24
Оценка:
Здравствуйте, MTD, Вы писали:

MTD>Ты уверен, что кастрюля и ворона имеют одного предка?


Это философский вопрос.

Общий предок нужен для обобщения "это некая хрень". Не сказал бы что это такое уже необходимое обощение. Но хуже от него не становится. Так что с чем ты собрался бороться не ясно.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Универсальный базовый класс
От: lazy/cjow/rhrr Россия lj://_lcr_
Дата: 07.08.13 08:05
Оценка:
dimgel,

LCR>>При достаточно развитой системы типов, некоторые из определений возможно бывает написать без object, используя разные продвинутые конструкции (см. например опредление функции map в Scala), но в общем случае нет.


D>Хм, вот уж не ожидал, что скалу приведут как пример иерархии без Object. Как раз в скале всё на свете, а уж тем более дженерики с ихней ко/контра-вариантностью (в том числе это определение Map), прочно завязано на факт существования общего супертипа (Any, подтипом которого является AnyRef == java Object) и общего подтипа (Nothing) для всех типов. И это чертовски удобно и красиво.


Дружище, я подтверждал тезис о том, что с развитой системой типов в некоторых местах необязательно иметь общий предок. В определении map нигде не используется, что тип имеет общего предка. А так — да, ты прав.
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[4]: Универсальный базовый класс
От: dimgel Россия https://github.com/dimgel
Дата: 07.08.13 08:21
Оценка:
Здравствуйте, lazy/cjow/rhrr, Вы писали:

LCR>В определении map нигде не используется, что тип имеет общего предка.


Эм... какой именно тип и общего предка с кем?
Re[5]: Универсальный базовый класс
От: lazy/cjow/rhrr Россия lj://_lcr_
Дата: 07.08.13 10:14
Оценка:
dimgel,

LCR>>В определении map нигде не используется, что тип имеет общего предка.

D>Эм... какой именно тип и общего предка с кем?
Уфф, ты контекст беседы потерял. Просто не используется свойство, что типы имеют общего предка. Scala могла бы не иметь ни AnyRef, ни Any, и определение map выглядело совершенно так же. Не согласен?
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[6]: Универсальный базовый класс
От: dimgel Россия https://github.com/dimgel
Дата: 07.08.13 10:21
Оценка:
Здравствуйте, lazy/cjow/rhrr, Вы писали:

LCR>Уфф, ты контекст беседы потерял.


Не потерял.

LCR>Scala могла бы не иметь ни AnyRef, ни Any, и определение map выглядело совершенно так же. Не согласен?


Согласен. То, что я написал, — вообще на самом деле не в тему, т.к. касается деталей реализации, а не синтаксиса. Определение могло бы выглядеть совершенно так же в том числе на каком-нибудь C++-подобном языке, где не дженерики, которым общие супер/саб-типы подавай, а шаблоны, для каждого типа генерирующие отдельную реплику.
Re[5]: Универсальный базовый класс
От: Erop Россия  
Дата: 09.08.13 10:32
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP> Например dereference у shared_ptr производит код <b>идентичный</b> dereference обычного указателя.

Это как так? У s_p ведь дволйное разыменование должно быть? Там же ещё прокси-объект болтается?

EP>2. Если генерируется идентичный бинарный код (что не редкость если используются указатели) — то он может мёрджится компилятором и линкером.

Это ОЧЕНЬ удобно, при линковках, отладках, самогенерённых частях кода и т. д...

EP>3. При необходимости возможно применение специальных техник "вручную", которые помогают уменьшить объём кода (например vector может прятать void* реализацию за тонким слоем кастов).


Понимаю... В правильно спроектированном языке общий предок не нужен, нужен void* с шаблонами.
Ну я давно подозревал, что ты с С++ фанатеешь, но не настолько же
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[6]: Универсальный базовый класс
От: Evgeny.Panasyuk Россия  
Дата: 09.08.13 18:27
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, Evgeny.Panasyuk, Вы писали:


EP>> Например dereference у shared_ptr производит код <b>идентичный</b> dereference обычного указателя.

E>Это как так? У s_p ведь дволйное разыменование должно быть? Там же ещё прокси-объект болтается?

У boost::shared_ptr вот такой layout:
    element_type * px;                 // contained pointer
    boost::detail::shared_count pn;    // reference counter

Если бы было двойное разыменование, то доступ к объекту был бы в 1.5-2 раза дороже (в тех случаях, когда shared_ptr не от make_shared)

EP>>2. Если генерируется идентичный бинарный код (что не редкость если используются указатели) — то он может мёрджится компилятором и линкером.

E>Это ОЧЕНЬ удобно, при линковках, отладках, самогенерённых частях кода и т. д...

А, допустим, что с самогенерёнными частями кода?

EP>>3. При необходимости возможно применение специальных техник "вручную", которые помогают уменьшить объём кода (например vector может прятать void* реализацию за тонким слоем кастов).

E>Понимаю... В правильно спроектированном языке

Без набора требований, "правильно спроектированный язык" — это демагогия

E>общий предок не нужен, нужен void* с шаблонами.


То что бывают случаи где нужна "универсальная ручка" — не означает что её нужно обязательно реализовывать с помощью общего предка.
В C++ указатель на объект можно положить в универсальную ручку — void* — причём это было ещё со времён C (в том время как например в Java, в языке с единым базовым классом — afaik, до недавнего времени не было реально универсальной ручки, либо нет нормальной ручки до сих пор), можно положить сам объект в union, либо вообще в char[], можно использовать шаблоны функций, которые тоже работают над своего рода универсальными ручками — и всё это без всяких базовых классов.
То что тут пытаются засунуть все полезные вещи которые работают с универсальной ручкой (типа кастов, которые, afaik, и в Java и в C#, не то что подрожают синтаксису функции, а вообще — являются отдельной синтаксической конструкцией) в базовый класс — так это от бедности языка, были бы нормальные non-member functions — было бы попроще. Такие функции всё равно не будут, например, виртуальными (а-ля Object.getClass в Java), и всё равно реализуются средой, а не средствами языка.
Более того, засовывая такие вещи в базовый класс — автоматом теряется возможность использования нормального синтаксиса для чего-то типа мультиметодов — например Object.equals(Object obj) это то ещё уродство.
Каких-то убедительных доводов в пользу именно единого предка — я тут не видел

E>Ну я давно подозревал, что ты с С++ фанатеешь, но не настолько же


Так, давай не будем строить догадки кто, от чего и насколько фанатеет, ок?
Намного интересней и конструктивней аргументы vs аргументы.
Re: Универсальный базовый класс
От: hi_octane Беларусь  
Дата: 09.08.13 21:03
Оценка:
MTD>В новом языке не надо делать общий базовый класс — это просто глупо. Пусть программист осознанно обогащает свои классы реализуя необходимые интерфейсы.

А как будет в такой системе работать например dynamic из C#?
Re[8]: Универсальный базовый класс
От: Evgeny.Panasyuk Россия  
Дата: 12.08.13 16:16
Оценка:
Здравствуйте, MxMsk, Вы писали:

EP>>То что тут пытаются засунуть все полезные вещи которые работают с универсальной ручкой (типа кастов, которые, afaik, и в Java и в C#, не то что подрожают синтаксису функции, а вообще — являются отдельной синтаксической конструкцией) в базовый класс — так это от бедности языка, были бы нормальные non-member functions — было бы попроще. Такие функции всё равно не будут, например, виртуальными (а-ля Object.getClass в Java), и всё равно реализуются средой, а не средствами языка.

MM>А причем здесь non-member functions? Они же есть в виде статических методов статических классов.

Покажи синтаксис вызова getClass (или вызов каста) был бы он статическим методом статического класса.

MM>И потом, помимо GetType(), есть еще GetHashCode и ToString, которые вполне себе виртуальные.


Необходимость наличия которых в едином базовом классе не была продемонстрирована (обсуждалось выше).
Re[9]: Универсальный базовый класс
От: MxMsk Португалия  
Дата: 12.08.13 18:57
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Покажи синтаксис вызова getClass (или вызов каста) был бы он статическим методом статического класса.

Да вроде очевидно. Что-нибудь вроде RuntimeUtils.GetClass(object)

Но это на самом деле вопрос не ко мне, а к тебе. Ты написал, что проблема в отсутствии non-member functions. Это меня удивило, потому что такие функции по факту есть. Ну да, к ним прибавляется название класса. Так можно его считать за пространство имен и дело с концом

MM>>И потом, помимо GetType(), есть еще GetHashCode и ToString, которые вполне себе виртуальные.

EP>Необходимость наличия которых в едином базовом классе не была продемонстрирована (обсуждалось выше).
Как это не была? Как будем хэш-таблицу делать?
Re[10]: Универсальный базовый класс
От: Evgeny.Panasyuk Россия  
Дата: 12.08.13 19:23
Оценка:
Здравствуйте, MxMsk, Вы писали:

EP>>То что тут пытаются засунуть все полезные вещи которые работают с универсальной ручкой (типа кастов, которые, afaik, и в Java и в C#, не то что подрожают синтаксису функции, а вообще — являются отдельной синтаксической конструкцией) в базовый класс — так это от бедности языка, были бы нормальные non-member functions — было бы попроще. Такие функции всё равно не будут, например, виртуальными (а-ля Object.getClass в Java), и всё равно реализуются средой, а не средствами языка.

MM>А причем здесь non-member functions? Они же есть в виде статических методов статических классов.
EP>>Покажи синтаксис вызова getClass (или вызов каста) был бы он статическим методом статического класса.
MM>Да вроде очевидно. Что-нибудь вроде RuntimeUtils.GetClass(object)
MM>Но это на самом деле вопрос не ко мне, а к тебе. Ты написал, что проблема в отсутствии non-member functions. Это меня удивило, потому что такие функции по факту есть.

Так я же не сказал, что нельзя, см. выделенное

MM>Ну да, к ним прибавляется название класса. Так можно его считать за пространство имен и дело с концом


А по факту в языке сделано так как сделано, ибо то что ты показал — очевидно хуже, в чём собственно и был мой поинт

MM>>>И потом, помимо GetType(), есть еще GetHashCode и ToString, которые вполне себе виртуальные.

EP>>Необходимость наличия которых в едином базовом классе не была продемонстрирована (обсуждалось выше).
MM>Как это не была? Как будем хэш-таблицу делать?

То есть без GetHashCode в едином базовом классе хэш-таблицу уже не сделать?
Re[11]: Универсальный базовый класс
От: MxMsk Португалия  
Дата: 12.08.13 19:35
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

MM>>Ну да, к ним прибавляется название класса. Так можно его считать за пространство имен и дело с концом

EP>А по факту в языке сделано так как сделано, ибо то что ты показал — очевидно хуже, в чём собственно и был мой поинт
Хуже чем что?

MM>>Как это не была? Как будем хэш-таблицу делать?

EP>То есть без GetHashCode в едином базовом классе хэш-таблицу уже не сделать?
Сделать. Вопрос в удобстве. Сейчас я могу использовать любой объект, как ключ. Чем альтернатива будет лучше?
Re[12]: Универсальный базовый класс
От: Evgeny.Panasyuk Россия  
Дата: 12.08.13 19:57
Оценка:
Здравствуйте, MxMsk, Вы писали:

MM>Хуже чем что?


Хуже чем то, как оно сделано сейчас.

MM>>>Как это не была? Как будем хэш-таблицу делать?

EP>>То есть без GetHashCode в едином базовом классе хэш-таблицу уже не сделать?
MM>Сделать. Вопрос в удобстве. Сейчас я могу использовать любой объект, как ключ.

А сделать TotallyOrdered сравнение? Сделать swap и т.п.? Всё тащить в единый базовый класс?

MM>Чем альтернатива будет лучше?


Например, явно указать какие интерфейсы наследовать (либо целые группы), какие default либо custom реализации использовать (через compile-time reflection например).
Лучше тем что гибче, не засоряет виртуальные таблицы каждого класса сотнями "типа полезных" всемогутеров, которые далеко не всегда нужны.
Re[13]: Универсальный базовый класс
От: MxMsk Португалия  
Дата: 12.08.13 20:13
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

MM>>Хуже чем что?

EP>Хуже чем то, как оно сделано сейчас.
Я потерял нить. Мой первоначальный ответ был на:

были бы нормальные non-member functions — было бы попроще

Такие функции есть. Что они могли бы упростить?

EP>А сделать TotallyOrdered сравнение? Сделать swap и т.п.? Всё тащить в единый базовый класс?

Конечно, любую идею можно довести до маразма.

MM>>Чем альтернатива будет лучше?

EP>Например, явно указать какие интерфейсы наследовать (либо целые группы), какие default либо custom реализации использовать (через compile-time reflection например).
Ну и станут эти интерфейсы такими же базовыми классами, только раскиданными по проекту от балды. Еще хуже, когда понадобиться положить в HashTable сторонний объект, разработчик которого не стал заморачиваться с хэш-кодом. Боюсь, обрастем костылями.

EP>Лучше тем что гибче, не засоряет виртуальные таблицы каждого класса сотнями "типа полезных" всемогутеров, которые далеко не всегда нужны.

Так нет же этих сотен. Зачем приписывать разработчикам языков то, чего они не делают?
Re[13]: Универсальный базовый класс
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 21.08.13 22:25
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

MM>>Хуже чем что?

EP>Хуже чем то, как оно сделано сейчас.

Конкретно в C# нет никаких проблем сделать синтаксис вызова GetType() для статической функции абсолютно идентичным вызову метода базового класса. Статические методы, с учетом extension методов, намного лучше в плане синтаксиса, чем свободные функции.
... << RSDN@Home 1.2.0 alpha 5 rev. 100 on Windows 8 6.2.9200.0>>
AVK Blog
Re[2]: Универсальный базовый класс
От: __kot2  
Дата: 21.08.13 23:06
Оценка:
Здравствуйте, lazy/cjow/rhrr, Вы писали:
LCR>В этом свете введение класса Object позволяет получить определённые выигрыши, причём недостатками можно пренебречь.
LCR>Среди выигрышей:
LCR>1. определение функций, которые выполняют общие трансформации кода работающие для любых объектов (рефлекшн, рантайм-макросы)
LCR>2. определение функций, принимающих любой объект или последовательность объектов (например, логгер, Runnable)
LCR>3. определение функций, возвращающих любой объект (например фабрики, ioc контейнеры)

LCR>При достаточно развитой системы типов, некоторые из определений возможно бывает написать без object, используя разные продвинутые конструкции (см. например опредление функции map в Scala), но в общем случае нет.

да все это уже было
разрулили появлением шаблонов. общий Object это древний костыль
Re[14]: Универсальный базовый класс
От: _NN_ www.nemerleweb.com
Дата: 22.08.13 07:43
Оценка:
Здравствуйте, AndrewVK, Вы писали:

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


MM>>>Хуже чем что?

EP>>Хуже чем то, как оно сделано сейчас.

AVK>Конкретно в C# нет никаких проблем сделать синтаксис вызова GetType() для статической функции абсолютно идентичным вызову метода базового класса. Статические методы, с учетом extension методов, намного лучше в плане синтаксиса, чем свободные функции.


А можно и со свободными функциями если есть Uniform Function Call Syntax (UFCS).
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[15]: Универсальный базовый класс
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 22.08.13 11:10
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>А можно и со свободными функциями если есть Uniform Function Call Syntax (UFCS).


Это примерно тоже самое, что и extension методы в шарпе.
... << RSDN@Home 1.2.0 alpha 5 rev. 100 on Windows 8 6.2.9200.0>>
AVK Blog
Re[13]: Универсальный базовый класс
От: A13x США  
Дата: 23.08.13 09:11
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>...

EP>Например, явно указать какие интерфейсы наследовать (либо целые группы), какие default либо custom реализации использовать (через compile-time reflection например).
EP>Лучше тем что гибче, не засоряет виртуальные таблицы каждого класса сотнями "типа полезных" всемогутеров, которые далеко не всегда нужны.

Можно рассмотреть очень простой
Автор: A13x
Дата: 28.07.13
базовый класс без виртуальных функций вообще, только с возможностью получить в runtime описание типа.

Естественно, можно обойтись без базового класса вообще, как в С++, но есть подозрение, что это заставит прикладного программиста писать больше кода чем нужно.
Многие библиотеки для С++ (Qt, GTK, MFC) и многие языки (из управляемых наверное подавляющее множество — все для JVM, все для .NET, python, ruby, javascript, common lisp ...) вводят базовый класс как мне кажется из за простоты, т.к. с этим проще реализовать
1 AOP
2 DI container
3 printf-alike функции печати c переменным числом аргументов
4 вещи типа dynamic в C#

насколько я понимаю почти все проблемы решаемы и без базового класса, но это требует
1. наличия довольно продвинутой системы типов вместе с compile-time макросами, генерирующими код.
2. написания бОльшего объема кода при разработке.

список проблем можно продолжить, но в основном он упирается в те вещи, которые сейчас реализованы опираясь на механизм RTTI.
В подобного рода библиотеках удобно наличие базового класса, чтобы уметь писать код, который принимает любой объект.
Его можно описать на шаблонах, с генерацией кода в compile time, но это, скорее всего, составит существенную сложность для управляемых языков (напр. для JVM/.NET).

Попробую описать на примере java. Предположим, что у нас есть jar (читай dll) с некоторыми обобщенными функциями — например логирование вида
log(String message, ? ... arguments) { <разворачивание кода в зависимости от типа argument> }.
На этапе компиляции jvm сможет проверить типы, но сгенерировать (развернуть) код — нет, т.к. допускается подмена jar в поставке приложения. Таким образом генерировать такой код придется каждый раз при загрузке приложения, что может сильно увеличить время загрузки приложения.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.