Delphi vs C++ vs C#
, ну и Java немножко, где-то ближе к старшему байту номеров страниц
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
| [216.73.216.192] |
|
|
Правила раздела:
| Страницы: (495) « Первая ... 426 427 [428] 429 430 ... 494 495 ( Перейти к последнему сообщению ) |
Delphi vs C++ vs C#
, ну и Java немножко, где-то ближе к старшему байту номеров страниц
|
Сообщ.
#6406
,
|
|
|
|
Цитата D_KEY @ Она связана с остальным кодом тем, что ей нельзя воспользоваться в случае списков, полученных из разных мест. А на практике тебе понадобится именно это. Угу, в этом и есть ее смысл (как ты себе представляешь скалярное произведение векторов разной размерности?), нужно приводит вектора к единому типу. |
|
Сообщ.
#6407
,
|
|
|
|
Цитата korvin @ Цитата D_KEY @ Она связана с остальным кодом тем, что ей нельзя воспользоваться в случае списков, полученных из разных мест. А на практике тебе понадобится именно это. Угу, в этом и есть ее смысл (как ты себе представляешь скалярное произведение векторов разной размерности?), нужно приводит вектора к единому типу. В общем, мне сейчас неинтересен спор о практическом применении Я вроде уже сказал, что нужно для того, чтобы была польза, ты вроде согласился - на том и сойдемся |
|
Сообщ.
#6408
,
|
|
|
|
Пожалуй, согласен с D_KEY насчет практической пользы - для списков полученных в разных местах, вне Test, номер не пройдет.
|
|
Сообщ.
#6409
,
|
|
|
|
Нет, я ничего не понял =/ Цитата D_KEY @ Будет сгенерирован код для f<Nil> и для f<Cons[a]>, соответственно. В f<Nil> будут созданы объекты Cons[Nil], затем будет вызвана foo<Cons[a]>, а информация о том, что a - это именно Nil - уже будет не нужна, там будут созданы объекты Cons[Cons[a]](на самом деле просто Cons[b]) и т.д. Когда же дойдет дело до ScalarProduct, то будет осуществлено обращение к ScalarProduct<Cons[a]>(или к ScalarProduct<Nil>, если длина нулевая), что приведет к вызову нужной функции, которой не нужно знать является ли a Nil или Cons[b]. Сам ScalarProduct будет инстанцирован два раза: ScalarProduct<Nil> и ScalarProduct<Cons[a]>(ибо ему все-равно, что такое a и продолжение инстанцирования не требуется) Мне из этого совершенно непонятно, каким образом в определении ![]() ![]() instance ScalarProduct (Cons a) where scalarProduct (Cons h1 t1) (Cons h2 t2) = h1*h2 + scalarProduct t1 t2 внутренний вызов scalarProduct определяет какой тип у t1 и t2 (Cons или Nil), если это необходимо для выбора инстанса в рантайме, а типы, как ты говоришь, в рантайме не "строятся", хотя забываешь, что в тех же Delphi, Java и C# объекты имеют типы в рантайме. |
|
Сообщ.
#6410
,
|
|
|
|
Цитата korvin @ Мне из этого совершенно непонятно, каким образом в определении ![]() ![]() instance ScalarProduct (Cons a) where scalarProduct (Cons h1 t1) (Cons h2 t2) = h1*h2 + scalarProduct t1 t2 внутренний вызов scalarProduct определяет какой тип у t1 и t2 (Cons или Nil) Он знает тип на момент генерации кода для инстанса Ты там зря убрал кусок кода перед этим, откуда a берется. Т.е. в итоге компилятор из одного инстанса породит код, как будь-то для двух инстансов(для Cons<Nil> и для Cons<Cons<что-то>>).Цитата хотя забываешь, что в тех же Delphi, Java и C# объекты имеют типы в рантайме. Дженерики забывают тип. Там фактически Object. Правда .NET'овский JIT-компилятор генерирует код для типов-значений, подобно плюсовому компилятору, но только во время выполнения. |
|
Сообщ.
#6411
,
|
|
|
|
Цитата D_KEY @ Дженерики забывают тип. Там фактически Object. Что ты этим хотел сказать? |
|
Сообщ.
#6412
,
|
|
|
|
Цитата --Ins-- @ Цитата D_KEY @ Дженерики забывают тип. Там фактически Object. Что ты этим хотел сказать? ![]() А что не понятно? |
|
Сообщ.
#6413
,
|
|
|
|
Цитата D_KEY @ А что не понятно? Ничего не понятно. В каком смысле "забывает" и "там фактически Object"? |
|
Сообщ.
#6414
,
|
|
|
|
Кстати, тут вспомнил про С++/CLI, там же есть generic'и. Надо бы проверить генерацию дженериков шаблонами
Добавлено Цитата --Ins-- @ Ничего не понятно. В каком смысле "забывает" и "там фактически Object"? Благодаря этому и работает обсуждаемый пример, ибо компилятору достаточно проверить текущую итерацию рекурсии(и тут он проверяет параметры дженериков), а потом он переходит к следующей, "забыв" о параметре параметризованного типа предыдущей итерации. |
|
Сообщ.
#6415
,
|
|
|
|
Цитата D_KEY @ "забыв" о параметре параметризованного типа предыдущей итерации. Типы параметров предыдущей итерации - это входные параметры текущей, а прототип метода гарантирует что они одинаковы. Но причем тут типы в рантайм? Как ты думаешь, TCons<TCons<TNil>> и TCons<TNil> - в рантайм, это один и тот же тип или разные? |
|
Сообщ.
#6416
,
|
|
|
|
Цитата --Ins-- @ Типы параметров предыдущей итерации - это входные параметры текущей Не совсем. Когда функция будет вызвана для Cons<тип>, внутри функции тип будет уже неизвестен. Т.е. разницы между тем, будет ли тип=Cons<другой_тип> или тип=Nil для компилятора нет. Цитата а прототип метода гарантирует что они одинаковы Да. |
|
Сообщ.
#6417
,
|
|
|
|
Цитата D_KEY @ Когда функция будет вызвана для Cons<тип>, внутри функции тип будет уже неизвестен. Ровно на столько же, насколько внутри метода, скажем SaveToStream(Stream: TStream) неизвестно с каким именно стримом работает код - TFileStream, TMemoryStream и т.д. Цитата D_KEY @ Т.е. разницы между тем, будет ли тип=Cons<другой_тип> или тип=Nil для компилятора нет. Ну естественно, в этом же и суть параметрического полиморфизма Добавлено Цитата D_KEY @ Т.е. разницы между тем, будет ли тип=Cons<другой_тип> или тип=Nil для компилятора нет. Для компилятора - нет, для выполняющегося кода - есть |
|
Сообщ.
#6418
,
|
|
|
|
Цитата --Ins-- @ Цитата D_KEY @ Т.е. разницы между тем, будет ли тип=Cons<другой_тип> или тип=Nil для компилятора нет. Ну естественно, в этом же и суть параметрического полиморфизма Ну вот это и есть "забывает" Цитата Для компилятора - нет, для выполняющегося кода - есть ![]() Это уже рантайм |
|
Сообщ.
#6419
,
|
|
|
|
Цитата D_KEY @ Он не знает тип. Т.к. конкретный тип (Cons или Nil) будет известен только когда список будет построен из n, т.е. в рантайме.Он знает тип на момент генерации кода для инстанса Ты там зря убрал кусок кода перед этим, откуда a берется.![]() ![]() instance ScalarProduct a => ScalarProduct (Cons a) where ... "ScalarProduct a" -- это не тип. Цитата D_KEY @ Т.е. в итоге компилятор из одного инстанса породит код, как будь-то для двух инстансов(для Cons<Nil> и для Cons<Cons<что-то>>). Зачем? Ему все равно придется в рантайме выбирать между этими вариантами. Не будет он этого делать. У нас уже есть две перегрузки scalarProduct, которых достаточно для работы примера. Цитата D_KEY @ Дженерики забывают тип. Там фактически Object. Правда .NET'овский JIT-компилятор генерирует код для типов-значений, подобно плюсовому компилятору, но только во время выполнения. а instanceof через libastral работает? Добавлено Цитата D_KEY @ Благодаря этому и работает обсуждаемый пример, ибо компилятору достаточно проверить текущую итерацию рекурсии(и тут он проверяет параметры дженериков), а потом он переходит к следующей, "забыв" о параметре параметризованного типа предыдущей итерации. Ты путаешь стадию проверки типов и стадию диспетчеризации функции. В Хаскелле это разные стадии. Добавлено Цитата --Ins-- @ Цитата D_KEY @ Т.е. разницы между тем, будет ли тип=Cons<другой_тип> или тип=Nil для компилятора нет. Ну естественно, в этом же и суть параметрического полиморфизма Только параметрический полиморфизм тут практически не при чем. |
|
Сообщ.
#6420
,
|
|
|
|
Цитата korvin @ Цитата D_KEY @ Он не знает тип. Т.к. конкретный тип (Cons или Nil) будет известен только когда список будет построен из n, т.е. в рантайме.Он знает тип на момент генерации кода для инстанса Ты там зря убрал кусок кода перед этим, откуда a берется.Почему ты забываешь о генерации кода? Цитата ![]() ![]() instance ScalarProduct a => ScalarProduct (Cons a) where ... "ScalarProduct a" -- это не тип. a - тип. Цитата Нет, между этими не придется - он их вызовы сгенерирует сразу.Цитата D_KEY @ Т.е. в итоге компилятор из одного инстанса породит код, как будь-то для двух инстансов(для Cons<Nil> и для Cons<Cons<что-то>>). Зачем? Ему все равно придется в рантайме выбирать между этими вариантами. Цитата У нас уже есть две перегрузки scalarProduct, которых достаточно для работы примера. Ага, оно и видно по твоему желанию генерировать типы в рантайме. Haskell этим не занимается. Насколько я знаю. Цитата Цитата D_KEY @ Дженерики забывают тип. Там фактически Object. Правда .NET'овский JIT-компилятор генерирует код для типов-значений, подобно плюсовому компилятору, но только во время выполнения. а instanceof через libastral работает? Ты не понимаешь разницы между типом во время компиляции и ссылкой на класс во время выполнения? Цитата Цитата D_KEY @ Благодаря этому и работает обсуждаемый пример, ибо компилятору достаточно проверить текущую итерацию рекурсии(и тут он проверяет параметры дженериков), а потом он переходит к следующей, "забыв" о параметре параметризованного типа предыдущей итерации. Ты путаешь стадию проверки типов и стадию диспетчеризации функции. В Хаскелле это разные стадии. Это было про дженерики, а не Haskell. Добавлено Цитата korvin @ Он не знает тип. Т.к. конкретный тип (Cons или Nil) будет известен только когда список будет построен из n, т.е. в рантайме. ИМХО, ты путаешь с шаблонами. При параметрическом полиморфизме не нужно точно знать тип-параметр. |