Re[27]: Мифический Haskell
От: VoidEx  
Дата: 24.03.12 18:00
Оценка:
Здравствуйте, vdimas, Вы писали:

Скажите пожалуйста, а switch-case для enum в Си++ — это тоже динамическая типизация?

V>Ты мне покажи вот так:

V>main' :: Integer -> Integer -> a -> b -> Integer

V>Потом подай на a и b одинаковые типы извне. Вот это и будет настоящий ПП, а не тот, которым вы хотите незаслуженно обозвать систему типов Хаскеля.


Не понял. Что должна делать такая функция? Ругаться при компиляции на разные типы? Или молча жрать все? Тогда в чём замысел?
Re[27]: Мифический Haskell
От: Klapaucius  
Дата: 25.03.12 16:15
Оценка:
Здравствуйте, vdimas, Вы писали:

V>В каких разных? Продемонстрируй плиз разные пространства имен для конструктора АлгТД и для одноименного идентификатора метки типа в конструкции ПМ некоего значения, созданного с помощью этого конструктора.


Я говорил про имя типа и имя конструктора.

V>Эээ... колега, а что вообще могло бы означать "упаковка другого типа" для АлгТД?


Вот и мне интересно. Это ведь вы утверждаете, что конструкторы АлгТД — типы.

V>А если так перефразировать:

V>Матчинг АлгТД в Хаскеле аналогично проверяет в рантайм дискриминатор объединения, то бишь тип запакованного значения.

Дескриминатор-то он, разумеется, проверяет в рантайме. А тип "запакованного" значения — нет. О чем и весь этот разговор.

K>>Ну, может и можно сказать, что конструктор типа "упаковывает" типа по аналогии с тем, как конструктор "упаковывает" значение. Вот только конструкторы типов в рантайме не матчатся (в рантайме их нет).


V>А как конструкторы могут матчиться?


Ну вот, приехали. А что, что-то может матчиться кроме конструкторов?

V>Ведь конструктор — это ф-ия.


Совсем не обязательно. В ocaml, например, конструктор функцией не является. Но даже если всякий конструктор — функция, то все равно не всякая функция — конструктор.

V>Может матчиться лишь некое ID размеченного объединения, то бишь матч всегда идет по ЗНАЧЕНИЮ


Правильно. Имя конструктора и есть этот ID.

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


Это значение к метке типа не имеет никакого отношения. Т.е. так сказать нельзя.
-- так можно
data FooBar = Foo Int | Bar Int
-- так нельзя
data Foo = Foo Int | Foo Bool

т.е. в рантайме проверяются не типы. ч.т.д.

V>Угу, ты повторно налегаешь на подтипирование, хотя я его не упоминал.


Постоянно упоминаете, когда говорите о проверке метки типа в рантайме.

V>Я догадываюсь, что ты намекаешь на реализацию наподобие АлгТД в Немерле, но я-то здесь при чем?


Не намекаю. Я объясняю, что является типом в хаскеле, а что не является.

V>Размеченное объединение обязательно хранит метку обернутого в АлгТД типа. Почему именно типа? Потому что согласно определения, размеченное объединение хранит в себе не только сам элемент, но обязательно некий уникальный идентификатор мн-ва, к которому принадлежит хранимый элемент. Мн-во — это тип, элемент мн-ва — это значение типа.


Тип — это не всякое множество, а множество, пренадлежность к которому может проверить тайпчекер. Статически.

V>data List a = Nil | Cons a (List a)


V>Для значения дескриминатора Nil_tag хранится tuple(/*empty*/), для значения Cons_tag хранится tuple(a, List<a>). Оба тупла и есть хранимые значения. Но сии значения-туплы имеют тип, как ни крути.


Туплы имеют тип. Но этот тип не находится с алгтд в отношениях подтипирования.

V>И да, от техники подтипирования в том же Немерле такая схема по-сути не отличается. Хоть ты и додумал за меня малость, насчет подтипирования, но происходящие в обоих случаях проверки типов при паттерн-матчинге — это суть проверки значения некоей метки. Вся разница лишь в том, что в Хаскеле метка представлена "унутре" интегральным значением, а в Немерле — адресом (сылкой) на дескриптор типа. По идее, тоже интегральным значением (адреса).


В хаскеле (ghc) эта "метка" как раз и представлена ссылкой на дескриптор блока памяти и (в случае небольшого числа конструкторов) тегом в указателе на блок.

K>>Ну так boost::variant это не сумма, а объединение — чего вы от него хотите. variant< int, bool > это int или bool.


V>Не так, это еще хранимый признак типа, как и положено. Поэтому это или container<0, int> или container<1, bool>. Т.е. в плане хранения — дотягивают. Они недотягивают в момент диспетчеризации по конкретным хранимым типам, бо для одного и того же типа будет вызвана одна и та же ветка диспетчеризации


Вот вы и описываете разницу между сабтайпингом (boost::variant) и алгебраическим типом. Еще одно различие. Через параметр типа variant< int, bool > можно передать и int и bool. Потому, что любые значения этих типов являются также и значениями вариантного типа. Это и называется "отношение подтипирования". Между типами "упакованными" в сумму и суммой такого отношения нет. Через параметр типа Either Int Bool нельзя передать ни значение типа Int, ни значение типа Bool. Только Either Int Bool.

V>Да пофиг. Реализация инстансов классов на технике-аналоге vtable ничем по-сути от происхоящего с помощью АлгТД не отличается.


Вот только инстансы классов на технике-аналоге vtable не реализуются (если у нас полиморфизм ранга-1).

V>Тем более, что обсуждаемый пример можно переписать на АлгТД и обойтись без классов типов.


Нельзя. Потому, что нам нужны тайплевел вычисления, а не рантайм-проверка.

V>Для тега алгТД место в рантайме таки требуется.


Никакие "Теги" АлгТД в рантайме не хранятся. Есть ссылка на InfoTable. У каждого вида лайаута данных в памяти — своя таблица.

V>Или ты считаешь, что процедура сравнения тега размеченного объединения и распаковка затем хранимого значения чем-то отличается от динамической типизации? Это абсолютно такое же кол-во телодвижений за ту же стоимость.


То, является что-то типизацией или не является не определяется стоимостью. Типизация — это проверка типа. Если мы проверяем значения на совпадение с BoxInt, true или 0 — это не проверка типа потому, что все это не типы. Не всякая проверка — проверка типа.

V>Именно. А приводимый пример фактически надуманный, т.к. что там проверять-то?, коль списки формируются параллельно.


Ну так то, что списки формируются параллельно и проверяется.

V>Да неполноценный это ПП ни разу. В любой точке примера используется один и тот же тип для обоих списков, а потом заявляется, что мы якобы проверяем что типы одинаковы. Хотя такими их объявили сами же.


Ну так смысл проверки типов в том, чтоб проверять соответствие функции типу, которым ее проаннотировали. Если функция не будет строить списки параллельно — будет ошибка компиляции.

V>Угу, как возражение, что при вызове ф-ий используется неявное ПМ привел явную реализацию на ПМ. Поздравляю.


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

V>Табличная диспетчеризация таки есть.


В обсуждаемом случае нет.

K>>Не верно. Все функции выбираются в компайл-тайм.

V>

Да, смешно читать, что человек может нафантазировать про тайпклассы, не зная, как они работают.

V>Каким образом? Чтобы выбор сделать, надо отказаться от боксированного представления, т.е. заранее знать, где конец списка.


Не нужно знать, где конец списка. Мы начинаем построение с Nil — это статически известно. выбираем одну функцию и подставляем ее вместо функции тайпкласса. Во всех остальных случаях будет функция для Cons — одна и та же — подставлем ее. Все, вся диспетчерезация закончилась на этапе компиляции.

K>>Но весь смысл этого куска кода в compile-time проверке!

V>Да нет там никакой проверки, не изобретай! Ограничение идет прямо в самой сигнатуре main':
V>main' :: ScalarProduct a => Integer -> Integer -> a -> a -> Integer

Правильно, это ограничение и проверяется.

V>Т.е. в самой сигнатуре main' черным по белому сказано, что a->a. Как можно было потом радоваться, что у нас скомпиллировалась строчка в теле main':

V>scalarProduct a1 a2
V>или
V>scalarProduct (Cons x a1) (Cons y a2)
V>если a1 и a2 имеют один и тот же тип по опредедению main'?

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

V>Ты мне покажи вот так:

V>main' :: Integer -> Integer -> a -> b -> Integer

Тут написано, что типы могут быть одинаковыми, а могут и раными — все равно. Что это проверяет-то?

V>Ну коль Cons a параметризируется типом Cons a', то у нас выходит, скажем, де-факто параметрический рекурсивный тип в примере.


Отличная шутка! А любая функция, у которой область определения — подмножество области значений — "де-факто рекурсивная"? А то ведь ее можно так применить f(f(х))

K>>Дескриминаторов типа в Хаскеле просто не существует

V>True, False, Cons, Nil — вот тебе существующие в рантайм дискриминаторы, хранимые вместе с данными.

Это и есть данные. Не типы.

V>Это конструкторы АлгТД в одном контексте и теги АлгТД, то бишь теги хранимого типа — в другом, например в конструкции ПМ.


Еще раз. Медленно. Теги конструктора и теги типа — разные вещи. И в конструкции ПМ никакие типы не проверяются. Тип там один — тип матчимого АлгТД. Проверяется статически.

V>А что, тебя смущает вырожденный случай размеченного объединения навроде Bool?


Ничем не смущает. Меня смущает, что вы True и False считаете типами.
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[40]: Мифический Haskell
От: samius Япония http://sams-tricks.blogspot.com
Дата: 25.03.12 21:22
Оценка:
Здравствуйте, Klapaucius, Вы писали:

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


K>>>Вот вы говорите можно, а из обсуждаемого здесь опыта известно, что нельзя. Как же так?

S>>Здесь обсуждается другой опыт. А опыт написать Succ<Succ<Succ<...>>> сколько ума хватит раз не обсуждается.

K>Да не написать Succ<Succ<Succ<...>>> а получить еще один из готового. Как тут:

K>
K>instance ScalarProduct a => ScalarProduct (Cons a)
K>

А причем тут наличие/отсутствие ПП?

S>>Вторая фича тут
Автор: Klapaucius
Дата: 09.03.12
— это импредикативность, верно?


K>Нет, не верно.

Прошу прощения. Но тогда я вообще не понимаю, как пункт 2 относится к полиморфизму.

S>>Вы доказывали что-то другое, причем я ответил по этому доказательству.


K>Вы по доказательству ответили, что оно не считается и все тут.

Я ответил что вы сделали слишком сильные выводы из определения. Это в том случае, если использовать определение с википедии. Ну а то, на которое вы ссылаетесь — я не знаю, откуда оно взялось.

K>>>Т.е. и 32-битный int — это тоже самое настоящее целое число?

S>>Нет. Я же согласился что это софистика.

K>И чем, по-вашему, это обоснование через "все возможные" программы отличается от вашего?

Это важно? Имеет какое-то отношение к ПП?

S>>Предикативный и импредикативный — это формы, а не определение ПП.


K>Точно. И что? Импредикативного никто и не требует.

Ок, пусть так.

S>>Вы дали ссылку и по ссылке вторым пунктом импредикативность. Что же вы обсуждаете, если не импредикативность?


K>Ок. Выкинте упоминание об импредикативности — оно там "для справки".

K>1) Возможность написать однородный (работающий одинаково для любого типа) код
Не возражаю.
K>2) Типизировать этот код обобщенным типом, содержащим переменные, которые конкретизируются применением обобщенного типа к конкретному.
Вот это откуда? И можно разжевать, что значит обобщенный тип, содержащий переменные?
Вот как это в TAPL (если я правильно понял, о чем речь):

Parametric polymorphism,the topic of this chapter, allows a single piece of
code to be typed “generically,” using variables in place of actual types, and
then instantiated with particular types as needed.

И в этом нет ничего такого, что не позволил бы шаблон в C++.

K>Типизировать шаблонный код в C++ нельзя вообще никак.

Вот как то же выглядит в переводе

... позволяет давать участку кода "обобщенный тип", используя переменные вместо настоящих типов, а затем конкретизировать, замещая переменные типами.

Что вы здесь подразумеваете под "типизировать"?

S>>У него не получилось кое-что другое, о чем я не говорю. А вот написать наперед заданное число раз Cons<Cons<... он не попробовал. А это помогло бы


K>Нда. Кто decl читал — тот в цирке не смеется.

Мну цирк и до decl-а не прикалывал.

K>>>В системе типов C# 2 и выше — есть.

S>>Аналога explicit forall в C# нет. Если бы был, можно было бы описать абстракцию функтора/монады и не пришлось бы жарить уток как в Query expression pattern.

K>1)explicit forall не обязателен для такого простого типа. Он тут для понятности. explicit forall, кстати, в Хаскеле без расширений нет.

K>2)В C# он наоборот есть — программист просто обязан писать его в сигнатуре:
K>
K>T foo<T>(Bar<T> a)
K>

K>что то же самое, что
K>
K>foo :: forall t. Bar t -> t
K>

K>В хаскеле же писать его не обязательно, там где он очевиден — это просто сахар.
Я об этом (http://en.wikibooks.org/wiki/Haskell/Polymorphism#Higher_rank_types). C# такое не умеет.

S>>Типы применяются во время выполнения


K>Нет, не применяются. Как выглядит применение во время выполнения в C# мы уже обсудили.

Нет, не обсудили. Вы не захотели обсуждать, на какую глубину применяются типы в компайл-тайме и чем занимается рантайм при введении значительной глубины структуры (например от 1000).

S>>, для каждого рекурсивного вызова _main выполняется докомпиляция JIT-ом.


K>Зачем его докомпилировать? Это же ссылочные типы, для них никакие специализации не нужны!



S>>Аргументы?


K>Аргументы ниже.


K>>>JIT-компилятора для C# не существует в природе. Допустим, что мы обсуждаем JIT-компиляцию CIL. Вы утверждаете, что в link-time, ngen-ом этот код полностью не скомпилировать?

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

K>Докажите, что он не будет там работать.

У меня нет под рукой сингулярити. Придется поверить так. Каждый new Cons<A>(...) согласно особенностям рантайма требует свой RuntimeType, а так же свои native реализации конструктора и метода scalarProduct. Хотя я не считаю себя специалистом по дотнет рантайму, но дотнет был моей основной специализацией с 2002-го года, и уверяю, мне неизвестно ни одного факта, позволяющего предполагать что Cons будет обходиться одной native реализацией своих методов и обходиться одним RuntimeType-ом во всех конкретизациях. Да, с List<T> одна реализация native методов прокатывает для всех reference типов T. Но это немного другое, там ни один метод List<T> не зависит от природы типа T (reference типа). А вот реализация scalarProduct — очень даже зависит.

Может в конце концов убедит то что у _main<A>, у scalarProduct от вызова к вызову разные MethodInfo?
        public int scalarProduct(Cons<A> second)
        {
            Func<Cons<A>, int> f = scalarProduct;
            return value * second.value + tail.scalarProduct(second.tail); //<-- set breakpoint here
        }

Вот такой трюк позволяет убедиться в том, что f при различных <A> совершенно разные объекты. Очевидно, что одна и та же нативная реализация метода не позволит получать разные объекты.

K>>>И как быть с Java у которой в байт-коде нет ПП и, следовательно, нет смысла о JIT говорить? Как быть с хаскелем?

S>>А никак не надо быть, мы ведь обсуждаем ПП ЯВУ а не байт-кода.

K>Так и я о том же. По вашему параметрические типы должны применятся в рантайме. Поэтому вы и обсуждаете компиляцию байткода в котором ПП есть. И только рантаймовую — возможность линктаймовой компиляции вы полностью игнорируете. В случае с C# лично для меня ситуация с рантаймом понятна, но вокруг нее столько всяких недопониманий и суеверий, что я просто сразу предлагаю: обсуждаем случаи, в которых никаких двусмысленностей нет: в Java и Haskell параметрические типы не могут применятся в рантайме в принципе потому, что в рантайме они не существуют.


K>>>Главный вопрос: как мы получаем ошибку компиляции C# за долго до того, как полиморфный код якобы скомпилируется в рантайме.

S>>О какой конкретно ошибке речь?

K>Об ошибке, когда код генерирует неравные списки. Она возникает в компайл-тайм.

А с чего им быть неравными? Да и это доказано во время компиляции C#, что они будут равными. Так что я не вижу никакой ошибки компиляции, на вопрос ответить затрудняюсь, т.к. не понял его.

S>>Вообще-говоря, С# проверяет ограничения при компиляции в IL и получает гарантии что они не будут нарушены в рантайме. Если такая проверка обламывается, мы получаем ошибку времени компиляции в IL. Если нет — то в JIT все будет как по рельсам.


K>Т.е. вы хотите сказать, что система типов второго C# unsound, статически проверить безопасность компилятор не может.

Я такого не хочу сказать. Проверить безопасность компилятор может, и делает это. А вот конкретизирует типы и JIT-ит код методов в рантайме. Это я хочу сказать.
K>Спорить с этим сложно, потому что благодаря таким мегафичам как ковариантность массивов и даункасты — так оно, собственно, и есть. С дженериками C# таких проблем, правда, нет, но мне проще обсудить полиморфизм на примере другого языка, чем вас в этом убедить.
В этом это в чем? В том что JIT не докомпиляет каждый вложенный вызов _main<A>/scalarProduct? Наверное на другом языке это будет сделать еще сложнее.

K>>>Нужно конкретизировать все до момента тайпчека, вы хотели сказать?

S>>наверное

K>Ну, тоесть параметрических типов в C++ нет, а параметрический полиморфизм, по вашему, есть? Оригинально.

А кто сказал что должны существовать параметрические типы? Определение касается вообще куска кода и способа сделать его обобщенным. Так что, что шаблон, что макрос, могут удовлетворять определению.
Re[41]: Мифический Haskell
От: Klapaucius  
Дата: 26.03.12 09:57
Оценка:
Здравствуйте, samius, Вы писали:

S>А причем тут наличие/отсутствие ПП?


Вот как раз это я тут и объясняю в 128-и сообщениях. Без всякого толка, как видно.

S>Но тогда я вообще не понимаю, как пункт 2 относится к полиморфизму.


Первый пункт говорит про код. Второй — про типизацию этого кода. Если не рассматривать типизацию, как вы вообюще отличите параметрический полиморфизм от полиморфизма через сабтайпинг? Код и там и там однородный, только способы его типизировать отличаются.

S>Я ответил что вы сделали слишком сильные выводы из определения.


И в чем слишкомсильность их? Что существует тип forall a. Succ a? Ну а какой полиморфный код вы типизируете, если даже такой тип не существует?

S>Это в том случае, если использовать определение с википедии. Ну а то, на которое вы ссылаетесь — я не знаю, откуда оно взялось.


Это пересказ обределения из TAPL своими словами.

K>>И чем, по-вашему, это обоснование через "все возможные" программы отличается от вашего?

S>Это важно? Имеет какое-то отношение к ПП?

Это имеет непосредственное отношение к обсуждаемой теме. Потому, что вы аргументируете таким способом (потенциальную) бесконечность типов. Если я применяю ваш способ неправильно — укажите мне в чем ошибка.

K>>2) Типизировать этот код обобщенным типом, содержащим переменные, которые конкретизируются применением обобщенного типа к конкретному.

S>Вот это откуда? И можно разжевать, что значит обобщенный тип, содержащий переменные?

Вы же прямо из TAPL сюда куски текста копируете, значит доступ к тексту у вас есть. А там все разжевано.

S>

S>Parametric polymorphism,the topic of this chapter, allows a single piece of
S>code to be typed “generically,” using variables in place of actual types, and
S>then instantiated with particular types as needed.

S>И в этом нет ничего такого, что не позволил бы шаблон в C++.

Проще сказать, что из описаного шаблон бы позволил. Видите, тут написано, что обобщенный код сначала типизируется обобщенным типом. Шаблонный код не типизируется. И типизировать его нельзя — тогда часть выразительных возможностей шаблонов будет недоступна. Типизируемый код получается только после инстанциации.

S>Что вы здесь подразумеваете под "типизировать"?


Под "типизировать терм" я понимаю "классифицировать терм, задать (проверить) его принадлежность к какому-то определенному типу".

S>Я об этом (http://en.wikibooks.org/wiki/Haskell/Polymorphism#Higher_rank_types).


Это и явный forall — не одно и то же. Мы вообще обсуждаем самый упрощенный вариант полиморфизма (ML-like) там возможен только полиморфизм ранга 1.

S>C# такое не умеет.


Haskell 98 на котором написан обсуждаемый код — тоже не умеет.

S>Нет, не обсудили. Вы не захотели обсуждать, на какую глубину применяются типы в компайл-тайме и чем занимается рантайм при введении значительной глубины структуры (например от 1000).


Я просто не вижу какое отношение это обсуждение деталей реализации к основной теме треда. И каким образом оно может быть продолжено. Допустим даже, что в C# все применяется в рантайме и т.д. — вывод-то какой из этого? Что для ПП нужна поддержка рантайма? Нет. Приведены примеры реализаций ПП без всякой рантайм-кодогенерации. Что в C++ есть ПП? Нет, эти два вопроса вообще никак не связаны.

K>>Так и я о том же. По вашему параметрические типы должны применятся в рантайме. Поэтому вы и обсуждаете компиляцию байткода в котором ПП есть. И только рантаймовую — возможность линктаймовой компиляции вы полностью игнорируете. В случае с C# лично для меня ситуация с рантаймом понятна, но вокруг нее столько всяких недопониманий и суеверий, что я просто сразу предлагаю: обсуждаем случаи, в которых никаких двусмысленностей нет: в Java и Haskell параметрические типы не могут применятся в рантайме в принципе потому, что в рантайме они не существуют.


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

K>>Об ошибке, когда код генерирует неравные списки. Она возникает в компайл-тайм.

S>А с чего им быть неравными?

Ну, перепишите код функции так, чтоб она генерировала неравные списки. С того и будут. И будет ошибка компиляции.

K>>Т.е. вы хотите сказать, что система типов второго C# unsound, статически проверить безопасность компилятор не может.

S>Я такого не хочу сказать. Проверить безопасность компилятор может, и делает это. А вот конкретизирует типы и JIT-ит код методов в рантайме. Это я хочу сказать.

Т.е. вы не утверждаете как остальные мои оппоненты тут, что проверка рантаймовая? В чем тогда суть вашего возражения?

S>В этом это в чем? В том что JIT не докомпиляет каждый вложенный вызов _main<A>/scalarProduct?


Нет, в том, что типобезопасность дженериков проверяется статически, а не в рантайме. К счастью, вас в этом убеждать и не требуется.

K>>Ну, тоесть параметрических типов в C++ нет, а параметрический полиморфизм, по вашему, есть? Оригинально.

S>А кто сказал что должны существовать параметрические типы?

Я сказал. В определении параметрического полиморфизма так написано. Поэтому он и "параметрический" и отличается от других видов полиморфизма.

S>Определение касается вообще куска кода и способа сделать его обобщенным. Так что, что шаблон, что макрос, могут удовлетворять определению.


Не могут. Если вы определяете "параметрический полиморфизм" просто как однородный код, тогда под него подпадают и другие виды полиморфизма. Но не шаблоны и не макросы, потому что с их помощью писать однородный код нельзя.
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[42]: Мифический Haskell
От: samius Япония http://sams-tricks.blogspot.com
Дата: 26.03.12 14:50
Оценка:
Здравствуйте, Klapaucius, Вы писали:

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


S>>А причем тут наличие/отсутствие ПП?


K>Вот как раз это я тут и объясняю в 128-и сообщениях. Без всякого толка, как видно.

Да, заметно.

S>>Но тогда я вообще не понимаю, как пункт 2 относится к полиморфизму.


K>Первый пункт говорит про код. Второй — про типизацию этого кода. Если не рассматривать типизацию, как вы вообюще отличите параметрический полиморфизм от полиморфизма через сабтайпинг? Код и там и там однородный, только способы его типизировать отличаются.

ПП от СП я отличаю по определению (одного, другого). Ни то ни другое определение (в википедии, по крайней мере) не используют термин "типизация".
К вам, собственно встречный вопрос. Как вы их отличаете? Подод к вопросу тоже есть. Вы берете пример migmit-а, в котором задействованы bounded и subtype полиморфизмы, и утверждаете что ПП там нет в случае С++ и есть в случае C#.

S>>Я ответил что вы сделали слишком сильные выводы из определения.


K>И в чем слишкомсильность их? Что существует тип forall a. Succ a? Ну а какой полиморфный код вы типизируете, если даже такой тип не существует?

Я же не утверждаю что он не существует. Я утвреждаю что существование такого типа не связано с определением. Тем более, не очевидно существование такого типа в конкретной программе. А существование его в какой-то абстрактной программе — такая же софистика, как и существование бесконечного числа типов в бесконечном числе программ.

S>>Это в том случае, если использовать определение с википедии. Ну а то, на которое вы ссылаетесь — я не знаю, откуда оно взялось.


K>Это пересказ обределения из TAPL своими словами.

Обращу внимание, что в TAPL нет упоминания о типе, содержащем переменные.

K>>>И чем, по-вашему, это обоснование через "все возможные" программы отличается от вашего?

S>>Это важно? Имеет какое-то отношение к ПП?

K>Это имеет непосредственное отношение к обсуждаемой теме. Потому, что вы аргументируете таким способом (потенциальную) бесконечность типов. Если я применяю ваш способ неправильно — укажите мне в чем ошибка.

Мой основной довод — это то, что бесконечность типов не требуется. Попытку представить бесконечность типов в бесконечности программ предлагаю игнорировать. Точно так же как и существование типа forall a. Succ a.

K>>>2) Типизировать этот код обобщенным типом, содержащим переменные, которые конкретизируются применением обобщенного типа к конкретному.

S>>Вот это откуда? И можно разжевать, что значит обобщенный тип, содержащий переменные?

K>Вы же прямо из TAPL сюда куски текста копируете, значит доступ к тексту у вас есть. А там все разжевано.

А там об этом ничего нет. Там говорится об использовании переменных вместо actual types, а вовсе не о типах, содержащих переменные.

S>>

S>>Parametric polymorphism,the topic of this chapter, allows a single piece of
S>>code to be typed “generically,” using variables in place of actual types, and
S>>then instantiated with particular types as needed.

S>>И в этом нет ничего такого, что не позволил бы шаблон в C++.

K>Проще сказать, что из описаного шаблон бы позволил. Видите, тут написано, что обобщенный код сначала типизируется обобщенным типом. Шаблонный код не типизируется. И типизировать его нельзя — тогда часть выразительных возможностей шаблонов будет недоступна. Типизируемый код получается только после инстанциации.

Не согласен. Там написано что кусок кода типизируется "обобщенно", используя переменные вместо типов. И ничего о параметрических типах, кстати.

S>>Что вы здесь подразумеваете под "типизировать"?


K>Под "типизировать терм" я понимаю "классифицировать терм, задать (проверить) его принадлежность к какому-то определенному типу".

Я думаю, что если бы трактовка "typed generically" была бы именно такой, то в переводе это было бы как-то отражено. В переводе же "типизация" вообще куда-то пропала.

S>>C# такое не умеет.


K>Haskell 98 на котором написан обсуждаемый код — тоже не умеет.

Согласен. Тогда мы в с++ и C# имеем forall, который непонятно чем отличается от forall H98

S>>Нет, не обсудили. Вы не захотели обсуждать, на какую глубину применяются типы в компайл-тайме и чем занимается рантайм при введении значительной глубины структуры (например от 1000).


K>Я просто не вижу какое отношение это обсуждение деталей реализации к основной теме треда. И каким образом оно может быть продолжено. Допустим даже, что в C# все применяется в рантайме и т.д. — вывод-то какой из этого?

Я влез в эту тему что бы выяснить вашу позицию по поводу разграничения C++ и C# на тему присутствия в них ПП. Вы глядя на примеры migmit-а утверждаете что в С# ПП есть, а в С++ — нет. Вот мне и захотелось уточнить, почему вы так считаете. Аргументами была бесконечность типов. Теперь же выяснилось (или как минимум, допустилось), что C# своей потенциальной бесконечности типов обязан особенностям рантайма и без них пример migmit-а работать не будет.

K>Что для ПП нужна поддержка рантайма? Нет.

Согласен, в общем случае не нужна и для C# не нужна тоже. Поддержка рантайма нужна для работы примера migmit-а, связь которого с определением ПП туманна. Там ПП присутствует в форме bounded полиморфизма с замесом на subtype полиморфизм.

K>Приведены примеры реализаций ПП без всякой рантайм-кодогенерации. Что в C++ есть ПП? Нет, эти два вопроса вообще никак не связаны.

Да, приведены. В С++ ПП есть, но это действительно не связано с примерами ПП без рантайм-кодогенерации. Тем более, что в C++ этот ПП присутствует без всякой рантайм-кодогенерации.

K>>>Так и я о том же. По вашему параметрические типы должны применятся в рантайме. Поэтому вы и обсуждаете компиляцию байткода в котором ПП есть. И только рантаймовую — возможность линктаймовой компиляции вы полностью игнорируете. В случае с C# лично для меня ситуация с рантаймом понятна, но вокруг нее столько всяких недопониманий и суеверий, что я просто сразу предлагаю: обсуждаем случаи, в которых никаких двусмысленностей нет: в Java и Haskell параметрические типы не могут применятся в рантайме в принципе потому, что в рантайме они не существуют.


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

А что мне на них отвечать? Они есть, я с этим спорить не собирался. Да, то что ПП должны применяться в рантайме — я такого не утвреждал, если что. Утверждал я лишь то, что в примере migmit-а (и в моем тоже) типы в C# применяются в рантайме. Ни в коей мере это не является необходимым условием ПП.


S>>А с чего им быть неравными?


K>Ну, перепишите код функции так, чтоб она генерировала неравные списки. С того и будут. И будет ошибка компиляции.

А, без проблем. Только к какому выводу это приведет? В C++ тоже ведь будет ошибка компиляции.

K>>>Т.е. вы хотите сказать, что система типов второго C# unsound, статически проверить безопасность компилятор не может.

S>>Я такого не хочу сказать. Проверить безопасность компилятор может, и делает это. А вот конкретизирует типы и JIT-ит код методов в рантайме. Это я хочу сказать.

K>Т.е. вы не утверждаете как остальные мои оппоненты тут, что проверка рантаймовая? В чем тогда суть вашего возражения?

Нет, не утверждаю. Но утверждать то, что в рантайме никаких проверок совсем нет — тоже не берусь. Наверняка есть.
Суть возражения была в том, что обсуждаемая фича в C# работает за счет рантайм конкретизации и кодогенерации. Без этих фич C# в отношении обсуждаемых примеров будет столь же бесполезен, как и C++. Разве что в C# мы сможем написать typeof(Cons<>), а в C++ нет.

S>>В этом это в чем? В том что JIT не докомпиляет каждый вложенный вызов _main<A>/scalarProduct?


K>Нет, в том, что типобезопасность дженериков проверяется статически, а не в рантайме. К счастью, вас в этом убеждать и не требуется.

Верно, не требуется. В обсуждаемых примерах она проверяется статически (как минимум, в том числе статически).

K>>>Ну, тоесть параметрических типов в C++ нет, а параметрический полиморфизм, по вашему, есть? Оригинально.

S>>А кто сказал что должны существовать параметрические типы?

K>Я сказал. В определении параметрического полиморфизма так написано. Поэтому он и "параметрический" и отличается от других видов полиморфизма.

Нет, в определении такого не написано. Ни в википедии, ни в TAPL. "Параметрический" он потому, что параметризуется код (single piece of code), а не тип.

S>>Определение касается вообще куска кода и способа сделать его обобщенным. Так что, что шаблон, что макрос, могут удовлетворять определению.


K>Не могут. Если вы определяете "параметрический полиморфизм" просто как однородный код, тогда под него подпадают и другие виды полиморфизма.

Нет, другие виды полиморфизма отличаются своими определениями. Ключевые отличия:
ad-hoc — используется специальная информация о типах (специализация)
subtyping — тут есть 2 определения. а) работает для всех подтипов автоматически; б) для ООП полиморфизма — с возможностью специализации кода для некоторых типов за счет override.
bounded — гибрид ПП и subtyping-а, где на типы накладываютя ограничения в виде обещаний о присутствии каких-то атрибутов(конструкторов/методов/и даже полей).

K>Но не шаблоны и не макросы, потому что с их помощью писать однородный код нельзя.

как это?
#define ID x = (x)
template <class T> T id(const T& v) { return v; }

Разве такие определения не позволяют использовать их однородно для различных типов?
Re[43]: Мифический Haskell
От: VoidEx  
Дата: 26.03.12 15:00
Оценка:
Здравствуйте, samius, Вы писали:

S>Не согласен. Там написано что кусок кода типизируется "обобщенно", используя переменные вместо типов. И ничего о параметрических типах, кстати.


Ну и как такое протипизировать:
template <class C, class T>
void foo(int x)
{
  C<T>::template Foo<T>::typename Bar y;
  y.Baz = x;
}


Можно потом SFINAE ещё подкрутить и попробовать протипизировать. Не инстанцированную конкретную функцию, а обобщённый шаблон.
Re[44]: Мифический Haskell
От: VoidEx  
Дата: 26.03.12 15:05
Оценка:
Здравствуйте, VoidEx, Вы писали:

Надо было мне только всю эту ересь в аргументы и возвращаемое значение запихнуть, ну да ладно.
Re[44]: Мифический Haskell
От: samius Япония http://sams-tricks.blogspot.com
Дата: 26.03.12 15:14
Оценка:
Здравствуйте, VoidEx, Вы писали:

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


S>>Не согласен. Там написано что кусок кода типизируется "обобщенно", используя переменные вместо типов. И ничего о параметрических типах, кстати.


VE>Ну и как такое протипизировать:

В TAPL написано "using variables in place of actual types".

VE>
VE>template <class C, class T>
VE>void foo(int x)
VE>{
VE>  C<T>::template Foo<T>::typename Bar y;
VE>  y.Baz = x;
VE>}
VE>

Т.е. оно уже typed "generically" согласно TAPL. Осталось лишь "and then instantiated with particular types as needed".

VE>Можно потом SFINAE ещё подкрутить и попробовать протипизировать. Не инстанцированную конкретную функцию, а обобщённый шаблон.


Не понятно, что значит попробовать протипизировать. Определение говорит о двух вещах:
1) использовать переменные вместо типов
2) инстанциировать с конкретными типами (подставить их вместо переменных).

А вы о чем?
Re[45]: Мифический Haskell
От: VoidEx  
Дата: 26.03.12 15:19
Оценка:
Здравствуйте, samius, Вы писали:

S>А вы о чем?


Об этом же. Ставим C = int, T = float. Какой тип получился?
Re[46]: Мифический Haskell
От: VoidEx  
Дата: 26.03.12 15:21
Оценка:
Здравствуйте, VoidEx, Вы писали:

VE>Об этом же. Ставим C = int, T = float. Какой тип получился?


Для определённости мы возвращаем y.
Re[46]: Мифический Haskell
От: samius Япония http://sams-tricks.blogspot.com
Дата: 26.03.12 15:21
Оценка:
Здравствуйте, VoidEx, Вы писали:

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


S>>А вы о чем?


VE>Об этом же. Ставим C = int, T = float. Какой тип получился?


Фиговый какой-то. Но это же не повод обвинять C++ в отсутствии ПП! Мы ведь можем написать шаблон, который будет себе вполне соответствовать ПП.
Re[47]: Мифический Haskell
От: VoidEx  
Дата: 26.03.12 15:23
Оценка:
Здравствуйте, samius, Вы писали:

VE>>Об этом же. Ставим C = int, T = float. Какой тип получился?


S>Фиговый какой-то. Но это же не повод обвинять C++ в отсутствии ПП! Мы ведь можем написать шаблон, который будет себе вполне соответствовать ПП.


Не фиговый, а нет такого типа, ошибка типизации, типизация не прошла. Типизация происходит только после подстановки. О чём и речь. Вы, конечно, можете написать такой шаблон, который при любом подставляемом типе таки стипизируется, но стипизируется он уже после.
Re[48]: Мифический Haskell
От: samius Япония http://sams-tricks.blogspot.com
Дата: 26.03.12 15:50
Оценка:
Здравствуйте, VoidEx, Вы писали:

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


VE>>>Об этом же. Ставим C = int, T = float. Какой тип получился?


S>>Фиговый какой-то. Но это же не повод обвинять C++ в отсутствии ПП! Мы ведь можем написать шаблон, который будет себе вполне соответствовать ПП.


VE>Не фиговый, а нет такого типа, ошибка типизации, типизация не прошла. Типизация происходит только после подстановки. О чём и речь. Вы, конечно, можете написать такой шаблон, который при любом подставляемом типе таки стипизируется, но стипизируется он уже после.


Что за "стипизируется"?
Пункт 1 — объявить переменные типов. Можно? Да. Язык C++ позволяет. Я не говорю о вашем примере. Я говорю о возможности.
Пункт 2 — подставить вместо переменных конкретные типы. Можно? Да.

А всякие там "до", "после", "стипизируется", "потенциальная бесконечность" — это уже спекуляции.
Re[49]: Мифический Haskell
От: VoidEx  
Дата: 26.03.12 16:13
Оценка:
Здравствуйте, samius, Вы писали:

S>Что за "стипизируется"?


typed

S>Пункт 1 — объявить переменные типов. Можно? Да. Язык C++ позволяет. Я не говорю о вашем примере. Я говорю о возможности.


Не объявить, а be typed “generically,” using variables in place of actual types

S>Пункт 2 — подставить вместо переменных конкретные типы. Можно? Да.


Можно, но не всегда, ибо typed будет уже после подстановки, и может не сработать.
Re[50]: Мифический Haskell
От: samius Япония http://sams-tricks.blogspot.com
Дата: 26.03.12 16:23
Оценка:
Здравствуйте, VoidEx, Вы писали:

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


S>>Что за "стипизируется"?


VE>typed


S>>Пункт 1 — объявить переменные типов. Можно? Да. Язык C++ позволяет. Я не говорю о вашем примере. Я говорю о возможности.


VE>Не объявить, а be typed “generically,” using variables in place of actual types

Окей. В русской версии это выглядит как "давать участку кода “обобщенный” тип, используя переменные вместо настоящих типов".

S>>Пункт 2 — подставить вместо переменных конкретные типы. Можно? Да.


VE>Можно, но не всегда, ибо typed будет уже после подстановки, и может не сработать.


Никто же не утверждает что всегда, что любое использование шаблона есть ПП. Речь лишь о том, что ПП в C++ присутствует и _могут_ быть приведены примеры, где шаблон вполне соответствует определению ПП (которое не требует параметрических типов или бесконечностей типов в одной программе).
Re[51]: Мифический Haskell
От: VoidEx  
Дата: 26.03.12 16:58
Оценка:
Здравствуйте, samius, Вы писали:

VE>>Не объявить, а be typed “generically,” using variables in place of actual types

S>Окей. В русской версии это выглядит как "давать участку кода “обобщенный” тип, используя переменные вместо настоящих типов".

Но там нет типа. Там шаблон, а тип появляется после подстановки. И это ужасное C<T>::template Foo<T>::typename Bar превращается в MyStruct. А может и не превращается, и тогда получаем ошибку типизации.

VE>>Можно, но не всегда, ибо typed будет уже после подстановки, и может не сработать.


S>Никто же не утверждает что всегда, что любое использование шаблона есть ПП. Речь лишь о том, что ПП в C++ присутствует и _могут_ быть приведены примеры, где шаблон вполне соответствует определению ПП (которое не требует параметрических типов или бесконечностей типов в одной программе).


В таком смысле и в Си есть ПП
#define ID(x) x
Re[52]: Мифический Haskell
От: samius Япония http://sams-tricks.blogspot.com
Дата: 26.03.12 17:32
Оценка:
Здравствуйте, VoidEx, Вы писали:

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


VE>>>Не объявить, а be typed “generically,” using variables in place of actual types

S>>Окей. В русской версии это выглядит как "давать участку кода “обобщенный” тип, используя переменные вместо настоящих типов".

VE>Но там нет типа. Там шаблон, а тип появляется после подстановки. И это ужасное C<T>::template Foo<T>::typename Bar превращается в MyStruct. А может и не превращается, и тогда получаем ошибку типизации.

Если может превращается, а может и не превращается, то о каком ПП речь? ПП должен работать одинаково для всех типов. И если там для какого-то типа заложены знания что нечто ужасное превратится в MyStruct, а для другого не превратится, то это уже не ПП.

VE>>>Можно, но не всегда, ибо typed будет уже после подстановки, и может не сработать.


S>>Никто же не утверждает что всегда, что любое использование шаблона есть ПП. Речь лишь о том, что ПП в C++ присутствует и _могут_ быть приведены примеры, где шаблон вполне соответствует определению ПП (которое не требует параметрических типов или бесконечностей типов в одной программе).


VE>В таком смысле и в Си есть ПП

VE>
VE>#define ID(x) x
VE>

В общем, кроме того что переменной типа не видно, других претензий в отношении определения ПП не могу предъявить. И сам уже писал что это является примером ПП, только скобочки забыл вокруг первого x.
Re[43]: Мифический Haskell
От: Klapaucius  
Дата: 27.03.12 08:45
Оценка:
Здравствуйте, samius, Вы писали:

S>ПП от СП я отличаю по определению (одного, другого). Ни то ни другое определение (в википедии, по крайней мере) не используют термин "типизация".


Но они только способом типизации однородного кода и отличаются.

S>К вам, собственно встречный вопрос. Как вы их отличаете?


Отличаю по способу типизации однородного кода. Другого-то способа нет.

S>Подод к вопросу тоже есть. Вы берете пример migmit-а, в котором задействованы bounded и subtype полиморфизмы, и утверждаете что ПП там нет в случае С++ и есть в случае C#.


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

S>Я же не утверждаю что он не существует. Я утвреждаю что существование такого типа не связано с определением. Тем более, не очевидно существование такого типа в конкретной программе.


Ну так тип объявлен в конкретной программе.

S>Обращу внимание, что в TAPL нет упоминания о типе, содержащем переменные.


Ну разумеется есть. Он процентов на 80 состоит из упоминаний "типа, содержащем переменные"

S>Мой основной довод — это то, что бесконечность типов не требуется. Попытку представить бесконечность типов в бесконечности программ предлагаю игнорировать.


Отлично.

S>Точно так же как и существование типа forall a. Succ a.


Т.е. в вашем определении ПП типизировать полиморфный код нельзя?

K>>Вы же прямо из TAPL сюда куски текста копируете, значит доступ к тексту у вас есть. А там все разжевано.

S>А там об этом ничего нет.

Ну, это неправда.

S>Там говорится об использовании переменных вместо actual types, а вовсе не о типах, содержащих переменные.


Да ну, в главе о "типах, содержащих переменные" не говорится о "типах, содержащих переменные"?

S>Не согласен. Там написано что кусок кода типизируется "обобщенно", используя переменные вместо типов. И ничего о параметрических типах, кстати.


А что такое параметрические типы, по-вашему? Ну, скажу тогда, что шаблонный код "обобщенно, используя переменные вместо(?) типов". "Вместо типов" — вообще анекдот. не вместо типов вообще, а вместо конкретных типов. Переменная типа — это тип. Посмотрите, где семантика расписана переменные типа справа от ( — операции типизации.

S>Я думаю, что если бы трактовка "typed generically" была бы именно такой, то в переводе это было бы как-то отражено. В переводе же "типизация" вообще куда-то пропала.


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

S>Тогда мы в с++ и C# имеем forall, который непонятно чем отличается от forall H98


Нету в C++ квантора всеобности, о чем и разговор.

S>Я влез в эту тему что бы выяснить вашу позицию по поводу разграничения C++ и C# на тему присутствия в них ПП. Вы глядя на примеры migmit-а утверждаете что в С# ПП есть, а в С++ — нет. Вот мне и захотелось уточнить, почему вы так считаете.


Потому, что код, написанный, исходя из предположения, что полиморфизм в C# параметрический работает так же, как и в других языках с параметрическим полиморфизмом и в соотвествии с теорией, построеной на свойствах параметрического полиморфизма. С другой стороны, код, написанный, исходя из предположения, что полиморфизм в C++ параметрический не работает так же, как и в других языках с параметрическим полиморфизмом и не соотвествует теории, построеной на свойствах параметрического полиморфизма.

S>Аргументами была бесконечность типов. Теперь же выяснилось (или как минимум, допустилось), что C# своей потенциальной бесконечности типов обязан особенностям рантайма и без них пример migmit-а работать не будет.


Т.е. в каком-то гипотетическом рантайме гипотетического языка (который C# не является потому, что у него другая система типов и семантика) может не быть параметрического полиморфизма. Какой из этого следует вывод?

S>Согласен, в общем случае не нужна и для C# не нужна тоже. Поддержка рантайма нужна для работы примера migmit-а, связь которого с определением ПП туманна. Там ПП присутствует в форме bounded полиморфизма с замесом на subtype полиморфизм.


Ну а на Хаскеле пример работает без поддержки рантайма. Ну так что, нужна поддержка рантайма для этого или нет?

K>>Приведены примеры реализаций ПП без всякой рантайм-кодогенерации. Что в C++ есть ПП? Нет, эти два вопроса вообще никак не связаны.

S>Да, приведены. В С++ ПП есть, но это действительно не связано с примерами ПП без рантайм-кодогенерации. Тем более, что в C++ этот ПП присутствует без всякой рантайм-кодогенерации.

Ну, если определять ПП как "что-то, что есть в C++" тогда да.

S>А что мне на них отвечать? Они есть, я с этим спорить не собирался. Да, то что ПП должны применяться в рантайме — я такого не утвреждал, если что. Утверждал я лишь то, что в примере migmit-а (и в моем тоже) типы в C# применяются в рантайме.


Применение типов в рантайме в C# отличается от применения в компайл-тайме синтаксически:
typeof(Foo<>).MakeGenericType(new[]{typeof(Bar)})
Foo<Bar>

Перепутать их никак невозможно. Кроме того, если бы типы применялись в рантайме — тайпчекер не смог бы проверить их. "Код генерируется в рантайме" — это не то же самое, что и "Типы применяются в рантайме".

K>>Ну, перепишите код функции так, чтоб она генерировала неравные списки. С того и будут. И будет ошибка компиляции.

S>А, без проблем. Только к какому выводу это приведет? В C++ тоже ведь будет ошибка компиляции.

На C++ не написать код, который правильно работает.

S>Суть возражения была в том, что обсуждаемая фича в C# работает за счет рантайм конкретизации и кодогенерации. Без этих фич C# в отношении обсуждаемых примеров будет столь же бесполезен, как и C++.


Именно в C# фича работает, потому что он компилируется в байткод с ПП. Что и где там потом генерируется из совсем другого языка к делу отношения не имеет.

K>>Я сказал. В определении параметрического полиморфизма так написано. Поэтому он и "параметрический" и отличается от других видов полиморфизма.

S>Нет, в определении такого не написано. Ни в википедии, ни в TAPL.

В TAPL совершенно точно написано. Определение в википедии не читал.

S>"Параметрический" он потому, что параметризуется код (single piece of code), а не тип.


Чем код-то параметризуется?

S>>>Определение касается вообще куска кода и способа сделать его обобщенным. Так что, что шаблон, что макрос, могут удовлетворять определению.


S>Нет, другие виды полиморфизма отличаются своими определениями. Ключевые отличия:

S>subtyping — тут есть 2 определения. а) работает для всех подтипов автоматически;

Ну я и говорю. Типизацией.

Вот вам две length без сигнатур типа:
length [] = 0
length (_:xs) = 1 + length xs

length [] = 0
length (_:xs) = 1 + length xs


Где здесь параметрический полиморфизм, а где полиморфизм через сабтайпинг?

S>как это?

S>
S>#define ID x = (x)
S>template <class T> T id(const T& v) { return v; }
S>

S>Разве такие определения не позволяют использовать их однородно для различных типов?

Сравнивать разновидности полиморфизма — свойства системы типов — без обсуждения типизации я вообще считаю бессмысленным.
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[53]: Мифический Haskell
От: VoidEx  
Дата: 27.03.12 10:30
Оценка:
Здравствуйте, samius, Вы писали:

VE>>Но там нет типа. Там шаблон, а тип появляется после подстановки. И это ужасное C<T>::template Foo<T>::typename Bar превращается в MyStruct. А может и не превращается, и тогда получаем ошибку типизации.

S>Если может превращается, а может и не превращается, то о каком ПП речь? ПП должен работать одинаково для всех типов. И если там для какого-то типа заложены знания что нечто ужасное превратится в MyStruct, а для другого не превратится, то это уже не ПП.

template <class C>
void foo(C const & x)
{
  x.Foo();
}

template <class T>
class Error
{
public:
  void Foo() { Bar<T>::template Foo<T>::typename Bar ... }  
};


Это ПП?
Re[44]: Мифический Haskell
От: MigMit Россия http://migmit.vox.com
Дата: 27.03.12 12:58
Оценка:
Здравствуйте, Klapaucius, Вы писали:

K>То, что квантификация во всех примерах ограниченная я с самого начала говорил. Это ничего не меняет — кол-во "ограниченных" типов все равно бесконечно. Bounded-полиморфизм — это сочетание параметрического полиморфизма и сабтайпинга, т.е. наличие полноценного параметрического полиморфизма подразумевается. Никаких работающих примеров без ПП, например только subtype среди обсуждаемых нет.


А наоборот — есть: http://migmit.livejournal.com/32688.html?thread=85168#t85168
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.