Delphi vs C++ vs C#
, ну и Java немножко, где-то ближе к старшему байту номеров страниц
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
| [216.73.216.192] |
|
|
Правила раздела:
| Страницы: (495) « Первая ... 358 359 [360] 361 362 ... 494 495 ( Перейти к последнему сообщению ) |
Delphi vs C++ vs C#
, ну и Java немножко, где-то ближе к старшему байту номеров страниц
|
Сообщ.
#5386
,
|
|
|
|
Цитата D_KEY @ Я немного не согласен с тем, чтобы смешивать абстрактные типы с типами данных. Как раз в Haskell есть типы данных(через алгебраические типы данных) и тайпклассы, которые позволяют описывать интерфейс объекта и абстрагироваться от конкретного типа(т.е. по сути являются средством описания абстрактных типов). Хотя допускаю, что я просто плохо "понял" Haskell. ты "плохо" понял хаскелл =) тайпклассы -- не типы и ни от чего абстрагироваться не дают сами по себе. абстрактные типы данных в хаскелле делаются с помощью обычных типов и модулей. вот так: ![]() ![]() module ConsCell ( Cons, cons, car, cdr ) where data Cons a b = Cell a b cons :: a -> b -> Cons a b cons x y = Cell x y car :: Cons a b -> a car (Cell x y) = x cdr :: Cons a b -> b cdr (Cell x y) = y а тайпклассы нужны для ad-hoc полиморфизма |
|
Сообщ.
#5387
,
|
|
|
|
Цитата korvin @ абстрактные типы данных в хаскелле делаются с помощью обычных типов и модулей. Это не абстрактные типы, это инкапсуляция. Добавлено Цитата korvin @ а тайпклассы нужны для ad-hoc полиморфизма А можно поподробнее, в чем все-таки разница? |
|
Сообщ.
#5388
,
|
|
|
|
ну и зачем такая каша? т.е. я такой, написал класс A с методом foo, а какой-то подлец взял и перекрыл _мой_ метод foo в _моем_ классе своим инстансом? =) Добавлено Цитата D_KEY @ Это не абстрактные типы отчего же? абстрактный тип, описаный только операциями Цитата An abstract data type is defined indirectly, only by the operations that may be performed on it все соответствует Добавлено Цитата D_KEY @ А можно поподробнее, в чем все-таки разница? разница с чем? с АТД? в том, что тайпклассы -- не типы, я же писал: ![]() ![]() instance C A instance C B xs :: C a => [a] xs = [A, B] -- не работает в общем случае в хаскелле вообще нет абстрактных типов, мой пример с модулями тоже не совсем корректен. вот интерфейсы -- это да, из-за суптипирования. впрочем, если перевести тайпклассы в динамику, тогда да, они будут АТД Добавлено хотя вообще интересный вопрос, является ли субтипирование необходимым. |
|
Сообщ.
#5389
,
|
|
|
|
Обсуждение вышло не за рамки возможностей C++, а за рамки ограничений, накладываемых статической типизацией.
|
|
Сообщ.
#5390
,
|
|
|
|
Цитата amk @ Обсуждение вышло не за рамки возможностей C++, а за рамки ограничений, накладываемых статической типизацией. почему? в хаскелле все статично типизировано, в Go -- тоже, в C++ тоже. где тут выход за рамки ограничений стат. типизации? Добавлено Цитата korvin @ хотя вообще интересный вопрос, является ли субтипирование необходимым. ага Цитата Different implementations of an ADT, having all the same properties and abilities, are equivalent and may be used somewhat interchangeably in code that uses the ADT. This gives a great deal of flexibility when using ADT objects in different situations. For example, different implementations of an ADT may be more efficient in different situations; it is possible to use each in the situation where they are preferable, thus increasing overall efficiency. т.е. как минимум субтипирование вида (Реализация <: АТД) должно быть, если я правильно понял, что тут имеют в виду в выделеной фразе. |
|
Сообщ.
#5391
,
|
|
|
|
Цитата korvin @ ну и зачем такая каша? т.е. я такой, написал класс A с методом foo, а какой-то подлец взял и перекрыл _мой_ метод foo в _моем_ классе своим инстансом? =) Опять ты боишься каких-то страшных программистов? Но почему тебя не смущает такое перекрытие во втором случае? Цитата Цитата D_KEY @ Это не абстрактные типы отчего же? абстрактный тип, описаный только операциями Цитата An abstract data type is defined indirectly, only by the operations that may be performed on it все соответствует А ты можешь на модулях сделать несколько реализаций одного АТД? Скажем, опиши стэк( ) и предоставь парочку его реализаций. Или таки ты воспользуешься тайпклассами?Цитата в том, что тайпклассы -- не типы Зачем это повторять еще раз? Интерфейсы так же не являются конкретными типами. И вообще могут ими не являться - они описывают контракт, точно так же, как и тайпклассы. По сути: ![]() ![]() void f1(IMyInterface obj); Тоже самое, что и(псевдокод, естественно): ![]() ![]() void f1(Object : IMyInterface obj); Т.е. мы просто требуем от объекта определенного интерфейса, какой у него будет при этом тип - не важно. Если же мы хотим проверить известный нам на момент компиляции тип(он не всегда совпадает с реальным его типом), то можем написать так: ![]() ![]() void f2<T : IMyInterface>(T obj); Цитата хотя вообще интересный вопрос, является ли субтипирование необходимым. Смотря что ты считаешь "субтипированием" и чем для тебя является тип Добавлено Цитата amk @ Обсуждение вышло не за рамки возможностей C++, а за рамки ограничений, накладываемых статической типизацией. Нет. С++, к сожалению, не полностью раскрывает эти возможности. Можно сравнить с той же scala, например. Добавлено Цитата korvin @ т.е. как минимум субтипирование вида (Реализация <: АТД) должно быть, если я правильно понял, что тут имеют в виду в выделеной фразе. Эм, то, что ты можешь использовать разные объекты разных типов, когда тебе нужен объект типа АТД - неотъемлемое свойство АТД, но из него не следует никакого "субтипирования". Вспомни систему "модулей" ML. Структуры, сигнатуры и функторы. Ты можешь описать одной сигнатурой некий АТД, а разными функторами создавать нужную сигнатуру из разных структур. И где тут, на твой взгляд, "субтипирование"? |
|
Сообщ.
#5392
,
|
|
|
|
Цитата D_KEY @ А ты можешь на модулях сделать несколько реализаций одного АТД? Скажем, опиши стэк( ) и предоставь парочку его реализаций.да могу, два модуля -- две реализации Добавлено Цитата D_KEY @ Скажем, опиши стэк( ) и предоставь парочку его реализаций. Или таки ты воспользуешься тайпклассами? вание"?тебя не смущает, что ни один из языков не представляет инструмента описания constraint (гарантий (семантики))? Добавлено Цитата D_KEY @ Зачем это повторять еще раз? Интерфейсы так же не являются конкретными типами. И вообще могут ими не являться - они описывают контракт, точно так же, как и тайпклассы. ирование"? затем, что ты не понял. интерфейсы _являются типами_ и покажи, где они могут не являться Добавлено Цитата D_KEY @ По сути: ![]() ![]() void f1(IMyInterface obj); Тоже самое, что и(псевдокод, естественно): ![]() ![]() void f1(Object : IMyInterface obj); Т.е. мы просто требуем от объекта определенного интерфейса, какой у него будет при этом тип - не важно. важно, ибо в случае субтипирования xs :: [I] = [A, B] работает, иначе -- нет Добавлено Цитата D_KEY @ Смотря что ты считаешь "субтипированием" и чем для тебя является тип ![]() то же, что и все Добавлено Цитата D_KEY @ Эм, то, что ты можешь использовать разные объекты разных типов, когда тебе нужен объект типа АТД - неотъемлемое свойство АТД, но из него не следует никакого "субтипирования". следует, прямо и безапеляционно. ибо если ![]() ![]() adt List impl List X where ... impl List Y where ... xs : List xs = X::Y::nil Добавлено Цитата D_KEY @ Вспомни систему "модулей" ML. Структуры, сигнатуры и функторы. Ты можешь описать одной сигнатурой некий АТД, а разными функторами создавать нужную сигнатуру из разных структур. И где тут, на твой взгляд, "субтипирование"? и где тут, на твой взгляд, АДТ? иначе вопрос такой: если принять твою правоту, то в хаскелле АТД -- это типы и модули, тайпклассы н при чем, о чем я и говорил, так с чем ты споришь? |
|
Сообщ.
#5393
,
|
|
|
|
Цитата korvin @ Цитата D_KEY @ А ты можешь на модулях сделать несколько реализаций одного АТД? Скажем, опиши стэк( ) и предоставь парочку его реализаций.да могу, два модуля -- две реализации И некий другой модуль сможет менять одну реализацию на другую, когда захочет? Цитата Цитата D_KEY @ Скажем, опиши стэк( ) и предоставь парочку его реализаций. Или таки ты воспользуешься тайпклассами? вание"?тебя не смущает, что ни один из языков не представляет инструмента описания constraint (гарантий (семантики))? Ты про инварианты(аксиомы), пред- и пост- условия? Eiffel предоставляет. С++ концепты тоже могли бы частично предоставить... Цитата затем, что ты не понял. интерфейсы _являются типами_ и покажи, где они могут не являться Все зависит от того, о каких "интерфейсах" ты говоришь. Как интерфейсы могут быть типами данных? Они могут являться абстрактными типами. Цитата важно, ибо в случае субтипирования xs :: [I] = [A, B] работает, иначе -- нет Причем тут субтипирование? xs::[I] = [A, B] работает потому, что и объект A и объект B удовлетворяют I. Но можно считать это типом(если тип для тебя - это некий предикат). Цитата то же, что и все У "всех" нет единого мнения даже о том, что является типом Цитата следует, прямо и безапеляционно. ибо если ![]() ![]() adt List impl List X where ... impl List Y where ... xs : List xs = X::Y::nil Следует, если ты в этом коде видишь "субтипирование". Цитата и где тут, на твой взгляд, АДТ? иначе вопрос такой: если принять твою правоту, то в хаскелле АТД -- это типы и модули, тайпклассы н при чем, о чем я и говорил, так с чем ты споришь? А что в Haskell'е выступает в роли функторов ML? Спорю не я, а ты. Я утверждал, что тайпклассы Haskell задают АТД, а ты почему-то с этим не согласен. |
|
Сообщ.
#5394
,
|
|
|
|
Цитата korvin @ Цитата D_KEY @ Т.е. мы просто требуем от объекта определенного интерфейса, какой у него будет при этом тип - не важно. важно, ибо в случае субтипирования xs :: [I] = [A, B] работает, иначе -- нет Собственно я уже говорил, но повторюсь. Тип это или нет, задача у него одна - описать контракт объекта. В случае интерфейса контракт относится к объекту(и мы имеем динамическое связывание) и потому интерфейс может считаться типом, в случае концептов/тайпклассов контракт относится к типу(и мы имеем статическое связывание) и считаться типом не может(хотя его можно отнести к метатипу). При этом мне не понятно, почему одна и та же сущность не может быть использована и как интерфейс, и как концепт/тайпкласс, в зависимости от контекста, ведь в обоих случаях описывается одно и тоже - контракт, т.е. операции(возможно с пред- и пост- условиями), а так же(если позволяет язык) вложенные типы и инварианты? |
|
Сообщ.
#5395
,
|
|
|
|
Цитата D_KEY @ И некий другой модуль сможет менять одну реализацию на другую, когда захочет? когда "когда захочет"? кроме рантайма -- да, может. Добавлено Цитата D_KEY @ Цитата затем, что ты не понял. интерфейсы _являются типами_ и покажи, где они могут не являться Все зависит от того, о каких "интерфейсах" ты говоришь. Как интерфейсы могут быть типами данных? Они могут являться абстрактными типами. мы тут о вполне определенных интерфейсах говорим. Цитата покажи, где они могут не являться Добавлено Цитата D_KEY @ Причем тут субтипирование? xs::[I] = [A, B] работает потому, что и объект A и объект B удовлетворяют I. Но можно считать это типом(если тип для тебя - это некий предикат). это и есть субтипирование. только при чем тут предикаты? Добавлено Цитата D_KEY @ Цитата следует, прямо и безапеляционно. ибо если ![]() ![]() adt List impl List X where ... impl List Y where ... xs : List xs = X::Y::nil Следует, если ты в этом коде видишь "субтипирование". а ты не видишь? тогда что ты тут видишь? Добавлено Цитата D_KEY @ А что в Haskell'е выступает в роли функторов ML? Спорю не я, а ты. Я утверждал, что тайпклассы Haskell задают АТД, а ты почему-то с этим не согласен. что такое "функторы ML"? а не согласен потому, что тайпклассы не задают типы. вообще никакие. |
|
Сообщ.
#5396
,
|
|
|
|
Цитата korvin @ Цитата D_KEY @ И некий другой модуль сможет менять одну реализацию на другую, когда захочет? когда "когда захочет"? кроме рантайма -- да, может. Ну тогда и объектный файл С++ можно другой подсунуть линкеру Цитата покажи, где они могут не являться Поясни, что тебе нужно. Чем не нравится пример с сигнатурами/структурами ML? И почему они обязаны являться типами? Цитата Может ты таки дашь его определение? Эти объекты могут считаться экземплярами типа top/object, а интерфейс позволяет указать их контракт, без указания типа.это и есть субтипирование. Цитата Не обязательно.а ты не видишь? Цитата тогда что ты тут видишь? Два объекта, помещенные в список объектов, удовлетворяющих некоторому интерфейсу. Цитата а не согласен потому, что тайпклассы не задают типы. вообще никакие. Сколько можно это повторять ?Они задают контракт, а это все, что требуется для АТД. Добавлено Скажи мне, вот тут объекты x и y могут считаться объектами, поддерживающими некоторый интерфейс, обеспечивающий работоспособность этого кода(т.е. интерфейс, который обязывает объекты иметь соответствующий оператор +)? ![]() ![]() def f(x, y): return x + y А обязаны ли являться типы объектов x и y наследниками какого-то типа(кстати вообще не существующего), говорящего о наличии такого оператора? |
|
Сообщ.
#5397
,
|
|
|
|
Цитата D_KEY @ Ну тогда и объектный файл С++ можно другой подсунуть линкеру ![]() ну Игорь тут уже писал, что это не так просто, когда я (да и ты, вроде) писал, что можно в хидере изменить спецификатор поля с private на public. + name mangling, насколько я знаю, также несколько усложняет такое подсовывание. а так да, можно. Добавлено Цитата D_KEY @ Может ты таки дашь его определение? Эти объекты могут считаться экземплярами типа top/object, а интерфейс позволяет указать их контракт, без указания типа. Два объекта, помещенные в список объектов, удовлетворяющих некоторому интерфейсу. Цитата TAPL Мы говорим, что S является подтипом T, имея в виду, что всякий терм типа S можно безопасно использовать в контексте, в котором ожидается тип T. интерфейс и есть тип. все типы, которые ему удовлетворяют, являются его субтипами. Добавлено Цитата D_KEY @ Скажи мне, вот тут объекты x и y могут считаться объектами, поддерживающими некоторый интерфейс, обеспечивающий работоспособность этого кода(т.е. интерфейс, который обязывает объекты иметь соответствующий оператор +)? ![]() ![]() def f(x, y): return x + y о, мы уже к динамической типизации перешли? учитывая, что функция f примет _любые_ два объекта, а ошибка может возникнуть только на +, то о чем речь? Добавлено Цитата D_KEY @ Поясни, что тебе нужно. Чем не нравится пример с сигнатурами/структурами ML? И почему они обязаны являться типами? ты имеешь в виду интерфейс модуля? Добавлено Цитата D_KEY @ А обязаны ли являться типы объектов x и y наследниками какого-то типа(кстати вообще не существующего), говорящего о наличии такого оператора? наследование != субтипировние. В случае как раз динамической утиной типизации наличие явных интерфейсов не обязательно, хотя и возможно. |
|
Сообщ.
#5398
,
|
|
|
|
Цитата korvin @ ну Игорь тут уже писал, что это не так просто, когда я (да и ты, вроде) писал, что можно в хидере изменить спецификатор поля с private на public Я тогда говорил про неопределённое поведение при нарушении ODR, к которому ведёт изменение заголовочника уже скомпилированного кода. В зависимости от, это может и привести к чему угодно - от ошибки линковки до не поддающемуся с точки зрения банальной эрудиции поведению программы при исполнении. Цитата korvin @ о, мы уже к динамической типизации перешли? учитывая, что функция f примет _любые_ два объекта, а ошибка может возникнуть только на +, то о чем речь? О том, что в случае кода ![]() ![]() template<class T> T f(T x, T y) { return x + y; } функция f тоже примет любые два объекта, и ошибка тоже может возникнуть на операторе +, только проверяется это статически. С помощью концептов это можно записать так ![]() ![]() auto concept Plus<class T> { T operator+ (T, T); } template<Plus T> T f(T x, T y) { return x + y; } и в случае отсутствия оператора + получить ошибку в духе "T не соответствует концепту Plus". Очень похоже на "T не реализует интерфейс Plus" При этом в данном случае концепт типом данных не является - он может использоваться только как ограничитель на параметр шаблона, эдакий шарповский where на стероидах.Возникает вопрос: а если соединить описание ограничений на параметр шаблона/дженерика и декларацию интерфейса (т.е. абстрактного типа данных) в одной сущности. И по аналогии с шаблонами/дженериками сделать утиную типизацию таких интерфейсов. Тогда можно написать как-то так ![]() ![]() auto concept Plus<class T> { T operator+ (T, T); } Plus f(Plus x, Plus y) { return x + y; } В этом случае функция f может использоваться для любых типов, имеющих оператор +, как и в случае шаблонов. |
|
Сообщ.
#5399
,
|
|
|
|
Цитата korvin @ ну Игорь тут уже писал, что это не так просто, когда я (да и ты, вроде) писал, что можно в хидере изменить спецификатор поля с private на public. + name mangling, насколько я знаю, также несколько усложняет такое подсовывание. а так да, можно. Там немного о другом речь шла. Теоретически ты можешь заменить объектный файл без нарушения ODR. Цитата Цитата TAPL Мы говорим, что S является подтипом T, имея в виду, что всякий терм типа S можно безопасно использовать в контексте, в котором ожидается тип T. Замечательно, почему ты не считаешь, что когда тип аргумента функции задается через тайпкласс мы не получаем ровно тоже самое? При этом сам тайпкласс типом не является - не надо это повторять Цитата У тебя понятие типа зависит от времени связывания и проверок?о, мы уже к динамической типизации перешли? Цитата ты имеешь в виду интерфейс модуля? Я имею в виду контракт. Введение в SML сигнатур позволило избавиться от абстрактных типов данных, которые изначально в нем были. Цитата Это, собственно то, ради чего я тебя просил привести определение наследование != субтипировние. Осталось согласовать позицию по тайпклассам. Добавлено Цитата MyNameIsIgor @ Возникает вопрос: а если соединить описание ограничений на параметр шаблона/дженерика и декларацию интерфейса (т.е. абстрактного типа данных) в одной сущности. И по аналогии с шаблонами/дженериками сделать утиную типизацию таких интерфейсов. Тогда можно написать как-то так ![]() ![]() auto concept Plus<class T> { T operator+ (T, T); } Plus f(Plus x, Plus y) { return x + y; } В этом случае функция f может использоваться для любых типов, имеющих оператор +, как и в случае шаблонов. Вот. Именно это я и пытался сказать |
|
Сообщ.
#5400
,
|
|
|
|
Qraizer
По мультиметодам, а порядок аргументов учитывается? |