Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Nick_, Вы писали:
А>>>"Динамически типизированный" и бестиповый — это одно и то же. N_>>Сомнительное утверждение. Не мог бы ты это обосновать? А>Некоторая сущность (в данном случае тип) присутствует в языке, если в нем имеются средства для её выражения. В противном случае все эти "типы" существуют только в нашем сознании, но никак ни в программах, ни в языке.
Плохо ищете типы в языке. Если бы типы отсутствовали, например, в языке Erlang, а существовали только в моем сознании, то и паттерн-матчинг я мог бы выполнять только в своем сознании. Однако то, что с этим вполне справляется Erlang runtime — это факт, причем этот факт доказан многочисленными независимыми экспериментами. Из которых большинство людей, которые представляют себе устройство компилятора и рантайма, делают вывод о наличии информации о типах (каждое значение в динамически типизированном языке сопровождается информацией о его типе, JFYI, иначе динамическая типизация работать не будет), и о происходящих во время выполнения проверках типов.
Вывод об отсутствии типов (sic!) в динамически типизированных языках экстравагантен, и, гхм, экспериментально не подтверждается, как, впрочем, и априорно — достаточно прочесть любой мануал по любому динамически типизированному языку.
Термин же "бестиповый" в специализированной литературе не распространен, а встречается исключительно в форумах и мэйллистах. Где его часто берут в кавычки, и сразу же поясняют "в том смысле, что...". Единственно где видал "бестиповый" в литературе — это у Дяхтеренко на софткрафте. Его труд, впрочем, во многих аспектах не отличается научной точностью, хоть и в целом там все в порядке. И вообще, посчитайте количество ссылок в гугле по сочетанию "бестиповый язык", прежде чем говорить о распространенности термина (десятки страниц).
И это неспроста. Сложно называть "бестиповыми" языки, к которым существуют системы типов, это нонсенс (soft type system — не меняющая семантики динамически типизированного языка система типов, которая используется для выведения типов и статической их проверки). Для лиспа их целых три (реализованных в ряде тулзов), для эрланга несколько штук (статической проверкой типов занимается т. н. Dyalizer), для JScript автор ее описал подробно в своем блоге — еще бы, компилятор JScript, как и многие современные компляторы динамически типизированных языков, выполняет type inference — как здесь без системы типов? Так что у кого-то типы может и существуют в сознании, но только не у людей, занимающихся компиляторами.
А>>>Полиморфизм нужен чтобы обходить ограничения, накладываемые системой типов. Если никаких А>>>ограничений нет, значит нет и типов и полиморфизм ни к чему. N_>>Разные системы типов, естественно, накладывают разные ограничения на программу. Но полиморфизм — это не сбоку приделка к простой системе типов, а ее обобщение. А>Ну правильно, обобщение. Но вот зачем понадобилось это обобщение? Очевидно, как раз потому, что ограничения, накладываемые мономорфной системой типов слишком серьезные.
Не правильно, не обобщение. И никто его специально не придумывал, это элементарное наблюдение. Полиморфной функцией называется функция, способная принимать аргументы разных типов. А все остальное существует только в вашем сознании. Можете верить, можете нет, но именно это, не зависящее от языка программирования определение используется или подразумевается в специализированной литературе.
Кстати, нам понадобится определение типа. Нестрого, но по существу верно: тип определяется множеством значений + правилами преобразования из/в другие типы. Абстрактные типы данных — это более специальный случай — они определяются только набором допустимых операций над ними (не структурой, но при этом у ADT все равно есть множество значений). Определение "подтипа" нам не понадобится — полиморфизм в общем случае не завязан на подтипы.
Функция в Visual Basic, принимающая значение типа вариант — полиморфна. Функция printf из стандарной либы C — полиморфна. Виртуальная функция (метод) класса — полиморфна, так как объект является неявным параметром (а с точки зрения вызывающего эта функция выглядит как одна функция, и неважно, что ее определение раскидано по разным классам). Шаблонная функция в языке С++ полиморфна. Любой метод в языке Smalltalk полиморфен по всем аргументам. Любой вызов в динамически типизированном языке полиморфен по определению, так как любое значение несет информацию о типе. То, как реализуется полиморфизм — дело десятое, это вопрос синтаксиса и семантики языка.
Полиморфизм подразделяется на исскуственный (если программист явно передает функции информацию о типе, как например в printf; в этом случае говорят, что полиморфизм языком не поддерживается, но это не мешает определить полиморфную функцию, используя специальные соглашения о передаче информации о типе. Полиморфизм не поддерживается языками С, Forth, Pascal) и естественный (если информация о типе передается неявно, т. е. средствами языка — это виртуальные функции, вызовы в динамически типизированных языках, итд).
Также, полиморфизм подразделяется на ad-hoc (разное действие для аргумента разного типа — printf, виртуальные функции) и параметрический (одинаковое действие для аргументов разных типов — например функция append для объекта "очередь" в языках Erlang, Java, Smalltalk).
Можно также выделить полиморфизм времени выполнения и компиляции, но для динамически типизированных языков смысловой разницы нет (вот оно, единственное место, где полиморфизм пересекается с динамической типизацией).
И все. Вот эта "теория" не противоречит здравому смыслу, не приводит к парадоксальным выводам "по определению", и реально описывает то общее, что есть в системах типов и полиморфизме разных языков программирования. Примерно в таком виде она преподается на ВМиК МГУ. Разумеется, прекрасно согласуясь с практикой. И с печатными работами .
Здравствуйте, VladD2, Вы писали:
VD>А, ну, то есть я не понял. Так что же ты вместо того чтобы сказать, что я тебя не понял, и ты говоришь про патерн-матчинг, начал доказывать, что мултиметода — это норенная особенность ФЯ?
На всякий случай, когда тебе кажется, что кто-то написал глупость, вместо этого считай, что ты человека не понял. Неплохой индикатор непонимания, сильно не ошибешься. Не придется разводить флейм, упираться, и пытаться потом сохранить лицо. Потому как убедить тебя, что ты не понял, как показывает опыт, практически невозможно. Это первый на моей памяти случай.
VD>А у меня к тебе пробсьба общественно характера. Смени стиль общения. Прекрати постоянно пытаться задевать других людей.
Я постоянно это делать и не пытаюсь. Так скажем, я вообще не пытаюсь задевать других людей. Я реагирую на их посты. В чем может убедится каждый, посмотрев историю моих постов. И в чем ты можешь убедиться лично, выполнив мою просьбу и последовав предыдущему совету. Если тебя это сильно не затруднит, конечно.
VD>ЗЫ VD>В общем, редлагаю не разводить здесь флэйм.
Нивапрос.
Таким образом, я вполне согласен с Gaperton'ом, когда он относит использование pattern matching при описании параметров функции к разновидности полиморфизма, т.к. в итоге будет выбрана соответствующая функция на основании типа аргумента (в общем смысле).
ПК>Ты, действительно, считаешь эти два предложения семантически эквивалентными?
Я считаю, что ты выкручиваешся.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
ПК>>Главное, что об этом не было бы известно в точке использования определенных таким образом функций. В случае pattern matching в параметрах это так, в случае if это не так. Наличие явных определений всех функций просто означает, что это форма ближе к ad-hoc полиморфизму, наравне с перегрузкой, а не к параметрическому полиморфизму, как это имеет место, когда одна и та же функция может работать с данными разных типов. VD>Извини, но это чушь. Эдакий полиморфизм можно сделать зи ифа написав один макрос.
Это все языком. ((с) Ты)
>>> И вообще, ОО-теории хреново воспринимаются функциональщиками. ПК>>Полиморфизм не требует ООП. Более того, понятие полиморфизма "родилось" именно в одном из функциональных языков, в ML, в 1976 г. Так что ОО в данном случае — переход на другую тему. VD>А я и не утрверждал, что с полиморфизмом в ФЯ есть какие-то проблемы. Пробелмы имеются с инкапсуляцией и вообще с восприятием ООП как идиомы.
Извини, но это чушь. ((с) Тоже из тебя. Причем очень к месту, так как чушь редкостная, такую не каждый день услышишь)
VD>Нет никаких типов по значению. Есть типы и есть экземляры этих типов. Значения могут быть только в экземплярах. Иначе это уже вакханалия. Тип затем и был придуман, чтобы работать с ним как с доменом, а не как с набором значений. Большинство языки о которых идет речь реализуют совершенно обыкновенную систему типов. Тот же Окамл даже классы поддерживает. В них есть понятие перегрузки. И оно четко отделяется от понятия паттерн-матчинга.
Да ладно, Влад, хватит ломать комедию. Ну не знаешь ты что такое паттерн-матчинг ("аналог операции ветвления" — гы! ), и ни одного ФЯ (какой окамл, ты даже элементарный tuple в моих примерах распознать не смог), и ни "совершенно обыкновенной системы типов" Хиндли-Милнера. И теории типа тоже. Сейчас уже можешь ничего не говорить, поздно — ты в постах своих уже все сказал и во всем расписался. Уже весь форум в курсе, а ты тут продолжаешь изображать знатока .
Скромнее надо быть, Влад. Смешно и грустно твои посты читать. Неудобно прям за тебя становится.
VD> Я исхожу из классического определения типов, полиморфизма и т.п. Так что в разговорах со мной лучше избегать терминов из области управления сферическми конями в вакууме.
Лучше разговоров с тобой избегать, как и чтения твоих постов. Для верности. Чем я и собираюсь заняться с этого момента. Все мои просьбы ты проигнорировал, так что мое время для тебя кончилось.
Здравствуйте, VladD2, Вы писали: VD>Речь шала о средствах поддержки полиморфизма в языках программирования. И если начать причислять к таковым средства ветвления логики вроде if-ов, то получится "плодотвореное" обсуждение сферического коня в вакуме.
Влад, не парь моск. Ничего страшного, что косвенная адресация может использоваться для обемпечения полиморфизма, причем также, как и для switch? Или уже начался вакуум? Главное отличие полиморфизма от конструкций ветвления в том, что выбор делается не явно клиентом, а средой. Ну вот паттерн-матчинг, так же как и выбор метода по типу аргумента в плюсах, делается средой.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Курилка, Вы писали:
К>Вот возник вопрос: К>в ФЯ есть полиморфизм типов, что имхо есть очень близко к шаблонам C++. Наряду с шаблонами C++ есть generics Java и C#, но там используются несколько иные механизмы. Так вот — какой из подходов будет ближе к тому, как это работает в ФЯ? К>Заранее сенкс за любую инфу!
Когда речь идет о полиморфизме, обыкновенно речь идет о полиморфном вызове функции (метода). Поговорим об этом подробнее. Можно выделить два вида полиморфных функций.
1) Функция ведет себя одинаково с аргументами всех допустимых типов (пример: тип аргумента — абстрактный базовый класс/интерфейс, или функция шаблонная).
2) Функция ведет себя по разному для аргументов разных типов (пример — виртуальная функция/метод перекрытая в подклассах полиморфна по неявному аргументу — объекту класса).
Поговорим об обоих видах полиморфных вызовов для ФЯ с системой типов Хиндли-Милнера/Майкрофта, на примере языков Хаскель и Clean.
1) Существует два способа. Первый — параметрические типы (аналог шаблонов), и второй — АДТ (абстрактные типы данных, ближе всего к интерфейсам). Вроде как все знакомо.
2) А вот здесь начинается самое интересное. Во-первых, для каждого типа (класса), соответствующего АДТ (реализующего интерфейс) надо явно указать набор функций, которые реализуют АДТ. Функции могут быть совершенно произвольными, в частности две разных реализации АДТ могут вообще говоря иметь пересекающийся набор функций. Что прикольно.
А во вторых, при разрешении полиморфного вызова учитываются не только типы, но и значения аргументов (в "обычных" языках — только типы). Причем, в разрешении вызова принимаются во внимание все аргументы (а не только тип неявного аргумента виртуальной функции — объект). Это самое главное отличие полиморфизма ФЯ от обычных языков.
Что это дает? Помните double dispatch? В ФЯ нет такого понятия, так как любой вызов диспетчеризуется по всем аргументам, это предоставляется средой. То, что значения могут быть частью сигнатуры, позволяет избежать создания новых типов (классов) в тех случаях, когда требуется полиморфный вызов. В результате, целый ряд паттернов, известных в ООП, становится тривиальными или просто нивидимыми в ФЯ (http://c2.com/cgi/wiki?DesignPatternsInDynamicProgramming). Наиболее наглядный пример — реализация КА. Примеры я приведу на Erlang, на Хаскеле с Clean будет примерно то же самое.
Функция switch будет полиморфна по двум аргументам (c маленькой буквы — значения, с большой — переменные).
switch( { state_A, Data }, msg_to_B ) -> { state_B, a_to_b( Data ) };
switch( { state_A, Data }, msg_to_C ) -> { state_C, a_to_C( Data ) };
Более натурально то же самое записать так, группируя функции перехода из одного состояния в одну (применяя pattern matching — основной инструмент полиморфизма ФЯ, отсутствующий в ИЯ). Т. е. мы получим по одному определению функции на каждое состояние:
switch( { state_A, Data }, Message ) ->
case Message of
msg_to_B -> { state_B, a_to_b( Data ) };
msg_to_C -> { state_C, a_to_C( Data ) };
end;
В чем здесь отличие от реализации КА на С++ или Java? То, что самая прямолинейная реализация КА будет самой правильной, т. е. соответствующий паттерн невидим. Запись КА в таком виде близка к определению КА, т. е. меньше семантическая разница между задачей и реализацией. С другой стороны, мы не обязаны привязывать "методы" switch и a_to_b к классу состояния, что дает нам гораздо больше свободы — система не так сильно связна и менее хрупка. Часть функций вида a_to_b может оперировать с объектом Data одного типа, часть состояний могут иметь данные разных типов — и мы не будем иметь никаких проблем с постоением грамотной объектной модели. Здесь это просто не нужно — вызовы и так полиморфны, причем во время выполнения.
Итак, К>Наряду с шаблонами C++ есть generics Java и C#, но там используются несколько иные механизмы. Так вот — какой из подходов будет ближе к тому, как это работает в ФЯ?
В свете вышесказанного — никакой. Все одинаково далеки.
VladD2:
> ПК> if здесь совершенно ни при чем, т.к. он строится так, что ему "известно" об используемых "типах" (явный выбор ветвлением), в то время как полиморфизм требует отсутствия этого знания у полиморфного кода.
> Гы. Патерн-матчингу тоже извесно об используемых типах.
Главное, что об этом не было бы известно в точке использования определенных таким образом функций. В случае pattern matching в параметрах это так, в случае if это не так. Наличие явных определений всех функций просто означает, что это форма ближе к ad-hoc полиморфизму, наравне с перегрузкой, а не к параметрическому полиморфизму, как это имеет место, когда одна и та же функция может работать с данными разных типов.
> И вообще, ОО-теории хреново воспринимаются функциональщиками.
Полиморфизм не требует ООП. Более того, понятие полиморфизма "родилось" именно в одном из функциональных языков, в ML, в 1976 г. Так что ОО в данном случае — переход на другую тему.
> ПК>Давай лучше рассмотрим несколько более близкий пример. Вот как, например, в языке Ада можно определять подтипы целого: > ПК>
> ПК>subtype NonNegativeInt is INTEGER range 0 .. INTEGER'LAST;
> ПК>subtype NegativeInt is INTEGER range INTEGER'FIRST .. -1;
> ПК>
> ПК>Плюс можно представить наличие двух перегруженных функций (не помню, поддерживает ли Ада перегрузку по диапазонам, но в данном случае это не важно):... > ПК>Это был бы полиморфизм? > > Гы. Это полиморфизм. Так как есть разные четко различимыетипы и способность намерянно скрывать разницу между ними. А вот если типы не вводить, а делать проверки при определении функций или при их вызове, то это уже управление ветвлением. <...>
Все зависит от системы типов, принятой в языке. Теории типов/языков программирования допускают различные системы типов, не запрещая и определение типа по значению. Для этого даже термин специальный есть type inference. В одной из форм присутствует и во многих функциональных языках.
> ПК>Теперь давай перепишем то же самое без предварительного объявления типов (уже не помню, поддерживает ли такое Ада,
> <...> динамическое их определение бессмысленно. Собственно это и есть разница между патерн-матчингом (динамической проверкой значения) и полиморфизмом (пофигу какой проверки типов).
В Аде переменным подтипов, введенных как диапазон "базового" типа, можно присваивать значения как других диапазонов той же "базы", так и "базового" типа. Все проверки выполняются именно во время исполнения. Соответственно, если бы в Аде можно было бы подобным образом перегрузить функции для поддиапазонов, то выбор функции производился бы именно во время их вызова, т.к. можно было бы написать именно так:
foo(10);
foo(-1);
без явного указания, к какому диапазону относится значение.
> Объяви методы вот так: >
> procedure foo(Param: INTEGER range 0 .. 5) is
> ...
> procedure foo(Param: INTEGER range INTEGER 4 .. 10) is
> ...
>
> И подсунь им в качестве значения 4 или 5. Что при этом произойдет?
Ошибка времени исполнения. Или какой-нибудь компромисс в виде выбора первого подошедшего варианта (не в стиле Ады). Или ошибка компиляции из-за того, что диапазоны пересекаются, если бы такое определение не было бы разрешено. Суть проектное решение автора языка. Для наших рассуждений, какой выбор он сделает, погоды не играет.
> ПК>Подсказка: популярно-упрощенное "определение из Wikipedia: > ПК>
In computer science, a datatype (often simply type) is a name or label for a set of values and some operations which can be performed on that set of values.
> ПК>общепринятым в Computer Science определением не является, > > Чушь.
Не чушь, а факт жизни. Подними любую специализированную статью или книгу по теории типов или языков программирования.
> ПК> и не покрывает даже такой простой случай безымянного типа: > ПК>
> ПК>struct { int i; double m; } my_variable;
> ПК>
> > И правильно делает. Потому-что это нарушение теории типов.
Теория типов различает две системы определения совместимости типов: структурную и именную. Обе имеют право на жизнь, хотя именная традиционно (и справедливо) считается более безопасной.
> Безымянные типы подразумевают сличение типов по соотвествию физической структуры типа данных.
Именные тоже так могут сравниваться. Все зависит от того, какая система типов принята в том или ином языке.
> В Википедии дано нормальное понятие типа. Можешь попытаться найти другое. И попытаться впихнуть в него динамические проверки значений. Но боюсь тебя ждет большой облом.
In computer science, a datatype (often simply called type) is a statically assigned constraint on a programming language phrase that denotes the kinds of values it may take on and gives it certain semantic meaning for the purposes of preventing errors, building abstractions, documenting the program, and gaining some measure of runtime safety and efficiency.
Динамические проверки значений даже впихивать не нужно: это называется динамическая типизация, и известно давным-давно.
Posted via RSDN NNTP Server 1.9 gamma
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
VladD2:
> G> Применение паттерн-матчинга при задании аргументов функции — вот это является одним из самых мощных способов достижения полиморфизма в ФЯ.
> Паттерн-матчинг вообще не имеет отношения к полиморфизму. Прочитай еще раз определение из Википедии. Там четко говорится о типах.
Понятие типа "вообще" не обязательно однозначно связано с такими понятиями, выражаемыми на уровне языка, как класс, "встроенный тип", int, double и т.п.
В computer science тип в самом общем смысле берет свое начало от математического понятия разбиения на классы, и определяется как множество значений, которые может принимать переменная, константа, результат функции и т.п. Некоторые языки даже позволяют определять подтипы с явным указанием набора или диапазона принимаемых значений.
Соответстенно, в случае использования pattern matching при задании параметров функции, можно считать что для параметров определяется новый тип, значения которого задаются через использованный при определении функции pattern. Безымянный тип описывается как бы прямо в определении функции, без отдельного специального определения для типа.
Далее, о наличии полиморфизма говорят, когда один и тот же код может использоваться с разными типами (*) (**).
Таким образом, я вполне согласен с Gaperton'ом, когда он относит использование pattern matching при описании параметров функции к разновидности полиморфизма, т.к. в итоге будет выбрана соответствующая функция на основании типа аргумента (в общем смысле).
(*) В принципе, это даже не обязательно должен быть вызов функции.
(**) Бывают еще и полиморфные типы данных, но это уже другой разговор.
Posted via RSDN NNTP Server 1.9 gamma
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, prVovik, Вы писали:
V>Неужели? А примерчик можно? У меня вот не получилось: V>
V>(defun my_mul (a b) (declare (number a b)) (* a b))
V>(setq num (read))
V>(cond
V> ( (= num 12345 ) (write (my_mul "Vasja" "Masha")) )
V> ( T (write (my_mul 10 2 )) )
V>)
V>
V>CLISP-2.27 Программа работает нормально, пока не введешь магическое число 12345, после которого она падает с ошибкой. Не помогает даже мокание компилятора мордой в молоко: (declare (number a b)).
Поймал, типа .
Попробуй http://www.drscheme.org/
Про нее пишут, что она делает type inference, чтобы помечать потенциальные ошибки.
Вообще, такое возможно благодаря soft type system. Вот некоторые цитаты.
Soft typing is a generalization of static type checking that accommodates both dynamic typing and static typing in one framework. A soft type checker infers types for identifiers and inserts explicit run-time checks to transform untypable programs to typable form. Soft Scheme is a practical soft type system for R4RS Scheme.
I'm not a CS PhD, nor do I play one on TV, but maybe I
ease your aching soul.
A [static] type system is a state of mind. A way of
viewing the world. Specifically a way of saying
statically what is and isn't a valid program. Now
there are many ways of seeing the world and so there
are many type systems. And they all say certain
programs are valid and certain programs are invalid
and they all get it wrong a occasionally. But you
knew that already.
Now if we take this view that a type system is a
static thing we can apply many type systems to the
same program. This is what the PLT guys have done —
Soft Scheme, MrSpidey, and MrFlow all apply different
type systems to Scheme and all accept and reject
certain (and different) programs. So if you desire
you can HM Scheme (which is what Soft Scheme does I
believe) and program in an ML style. Not many Scheme
programs will pass that test but you can make sure the
ones you write do. So you can be statically typed.
And then you can write programs that don't pass the
type checker and you can just tell the Scheme system
to put in the appropriate run time checks and fail if
you made a type error.
So we can take a dynamically type system and by
limiting the language we use we can turn it into a
statically typed system. Any statically typed system.
Now lets go the other way. Hmmm... Can't be done. If
the type system you use fits your program then you're
home. So writing compilers in ML and simulations in
Java probably doesn't suck. It's when you go the
other way that you feel the pain. And that's when you
wished you had a dynamically typed language: because
there are more problems than there are type systems to
handle them and though more advanced type systems
require you to tie less of your hand behind your back
they'll never do away with it entirely (and least
while they remain decidable).
So for my money I'd rather use Scheme than ML. A lot
of my programs look like ML but there are occasions
where they don't and its those outliers that make the
difference. I'm happy to have static type systems
built on to Scheme so that I can statically check 90%
of my programs and I'm just as happy to throw away the
type system for the other 10% of programs. It's the
perfect middle ground!
Quintanar:
> ПК>Давай лучше рассмотрим несколько более близкий пример. Вот как, например, в языке Ада можно определять подтипы целого: > ПК>
> ПК>subtype NonNegativeInt is INTEGER range 0 .. INTEGER'LAST;
> ПК>subtype NegativeInt is INTEGER range INTEGER'FIRST .. -1;
> ПК>
> > Фишка в том, что в ФЯ нельзя определять подтипы, поэтому такое рассуждение для них не подходит.
Дык, тут не дело в определении подтипов (*), а в определении типов (не важно, являются ли они подтипами некоторого другого), выбор из которых происходит в соответствии с их структурой/значением, а не с именем, которого у них может и не быть.
> Полиморфные там только функции, паттерн-матчинг — это лишь способ декомпозиции сложных типов. Если взять и делать вид, что он выделяет некий подтип, то в рантайме мы нарвемся на ошибку non exhaustive pattern, а некоторые языки даже нервничают, если pattern неполный и пишут warnings. То, что тут писали выше (pattern matching при определении функций) это вовсе не перегрузка или что-либо еще, это syntactic sugar. Такое обявление >
> func pat1 = ..
> func pat2 = ..
> ...
>
> эквивалентно >
> func x = case x of
> pat1 -> ..
> pat2 -> ..
> ..
>
> Так что в ФЯ ПМ никак не является формой полиморфизма.
Конечно, сам по себе pattern matching формой полиморфизма не является. Полиморфизмом (ad-hoc, если быть точным) является предоставление набора функций с критериями выбора одной из них по "типу" аргумента/аргументов (в данном случае динамическому).
Интересно, что в C++ есть в некотором роде похожая техника. Сводится она к тому, что можно предоставить набор перегруженных шаблонов функций, выбор среди которых будет производиться на основании некоторого предиката от типа аргумента шаблона:
Вполне возможен выбор и на основании некоторых структурных свойств типа аргумента шаблона. Например, наличия в классе члена с заданной сигнатурой, или соответствия некоторым иным требованиям, скажем, наличия виртуальных функций, или же можно отделить все перечислимые типы от классов и т.п.
По своим возможностям, конечно, техника очень далека от pattern matching ввиду того, что является побочным эффектом определения языка, но, тем не менее, имхо, сходство очевидно.
Точно так же, как и с pattern matching, в случае невозможности выбрать одну из предоставленных функций мы получим ошибку (в данном случае во время компиляции).
И точно так же, как pattern matching, сама по себе используемая функциональность (SFINAE — Substitution Failure Is Not An Error), к полиморфизму отношение имеет весьма опосредованное. Однако в сочетании с перегрузкой функций позволяет проделывать аналогичные вещи, с той разницей, что выбор функции производится во время компиляции, а не во время выполнения.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Nick_, Вы писали:
VD>Статический когда выбор конкретного варианта осуществляется компилятором (перегрузка и т.п.) и динамический кодга конкретный вариант выбирается в рантайме на базе динамического выбора.
Я не вижу тут разницы. Если компилятор С++ знает тип объекта у которого вызывается виртуальный метод, то он может подставить сразу вызов необходимого метода в обход таблиц виртуальных функций.
В С++ есть четкое деление на "статический" и "динамический" полиморфизмы только потому, что у них различается синтаксис. Если хочешь рантайм поддержку приходится писать x->foo(y);
В функциональных языках если компилятор знает тип аргумета, то вызывает конкретную функцию, если не знает, то это делает рантайм. В обоих случаях вызов записывается одинаково: foo x y
N_>>Я знаю только ad-hoc и параметрический полиморфизмы.
VD>Не думаю, что этот термин реально прижился. Не все из Википедии нужно брать на вооружении.
Может этот термин и не прижился в рядах web программистов, но в рядах ученых он используется.
N_>>ad-hoc — это перегрузка(overloading) и то, что обычно понимается под полиморфизмом в С++. N_>>parametric — это то, что в функциональных языках понимается под полиморфизмом. N_>>Шаблоны в С++ — это подобие параметрического полиморфизма.
VD>Это все не типизация. Это общие разрозненные слова. Реально имет значение смысл полиморфизма: создание универсального кода (процедур, функций, методов) или типов, т.е. так чтобы код и типы можно было абстрагировать от конкретных используемых в них типов.
Сложно формально описать систему типов в функциональных языках. Наверное это проще сделать на примерах.
Я на досуге попробую найти хороший пример на хаскеле.
VD>Ну, а дальше можно выделить два подкласса — это статический полиморфизм и динамический. Динамический требует выбора в рантайме, статический ведет к генерации множества вопложений полиморфного кода и типов.
Здравствуйте, VladD2, Вы писали:
G>>О как (век живи — век учись)! Пример пожалуйста, особенно "обычного языка", где учитываются значения аргументов при полиморфном вызове в run-time (твой комментарий по правилам русского языка относится ко всему абзацу, а не ко второй половине ).
VD>1. Мы кажется уже договорились, что полиморфизм бывает статический. При этом 90% современных языков это делают.
К чему это ты? Я не понимаю.
VD>2. мультиметодыmultimethods
Вместе с тем, достаточно часто возникают ситуации, когда гомоморфные иерархии, определяемые как иерархии классов с одинаковым открытым интерфейсом, унаследованным от общего базового класса [1], взаимодействуют через функцию, виртуальную к произвольному числу полиморфных параметров. Такая функция называется мультиметодом [2], а возможность ее использования существует в языке программирования CLOS (Common Lisp Object System). Однако широко распространенные ОО языки программирования не поддерживают подобный механизм в связи с отсутствием его эффективной реализации [3].
В первой ссылке по твоему поиску. Почитал бы ты сам свой гугл , что ли.
G>>Не думаю, что в списке примеров окажется С#, VD>Встроенных нет. Но народ над этим думает http://rover.cs.northwestern.edu/~surana/blog/past/000117.html
Примеров "обычных языков" нет. Впрочем, как и необычных. Все понятно. Вопрос снят.
VD>>>А кое где реализуются имеющимися средствами. G>>Гхм. Имеющееся средство называется... VD>В гугле думаю сразу поймешь о чем я говорю. У нас на сайте тоже статейки имеются.
Хитрый ленинский прищур не изчез, однако . У нас тоже на кое-кого кое-какой материалец имеется . Мои ответы на свои посты тоже ищи в гугле. Сразу все поймешь. Там все есть.
Здравствуйте, VladD2, Вы писали:
G>>Перечитай мой изначальный пост от начала до конца, внимательно. Посмотри примеры, которые я привел. VD>Почитал очень внимательно. Понял, что ты, по-моему, в принципе не верно понимаешь термин полиморфизм.
Плохо. Перечитай еще раз .
VD>Патерн-матчинг ты принимаешь за полиморфизм. Именно по этому я тебя и не понял.
Не думаю. Советую рассмотреть вариант, что ты принимаешь паттерн-матчинг за аналог операции ветвления в ИЯ. Вот поэтому ты меня не понял.
VD>Собственно вот определение из которого я исхожу http://en.wikipedia.org/wiki/Polymorphism_%28computer_science%29#Ad-hoc_polymorphism
Ну наконец-то, конструктивный разговор. Я исхожу из такого же определения. Прикольно, правда? А паттерн-матчинг я за полиморфизм не принимаю, это разные вещи. Применение паттерн-матчинга при задании аргументов функции — вот это является одним из самых мощных способов достижения полиморфизма в ФЯ.
Все эти определения могут быть даны одновременно, и в рантайме будет выбрано наиболее специфичное.
poly_function( { A, B } ) -> ...;
вызовется, если аргумент — структура из двух элементов.
poly_function( [ A, B ] ) -> ...;
вызовется, если аргумент — список из двух элементов. Разные типы, все в порядке, так?
poly_function( { A, { B, C } } ) -> ...;
вызовется, если аргумент — структура из двух элементов, а значение второго элемента — тоже структура из двух элементов. Что можно также понимать, как единое определение типа (такая хитрая структура) — пока все честно, не так ли?
Как видишь, мы уточнили ограничение на тип по сравнению с первой строкой. Теперь оно более специфично.
Паттерн матчинг, однако. И речь идет одновременно и о типах и о значениях. Теперь нам ничего не мешает поступить так:
poly_function( { A, { value_5, C } ) where A < C -> ...;
Почти тоже самое, но мы еще более сузили множество значений, при котором вызовется эта функция. Тип данных в частности однозначно определяется множеством значений этого типа, так что аргумент-паттерн можно также понимать как способ конструирования подтипов без их явного определения (!). С такой точки зрения мы не выходим за рамки классического определения полиморфизма. Если ты еще не понял, о чем я, то заметь, что на С++ я каждый вариант могу завернуть в свой подкласс, и написать совершенно такой же код, где poly_function будет являтся виртуальной функцией каждого подкласса. В ФЯ же я этого делать не обязан.
По сути дела, применяя паттерн-матчинг для спецификации аргументов, мы не просто задаем тип, как по классике. Мы накладываем ограничение на тип и значение аргумента, что позволяет нам произвольно варьировать подмножество объектов, на котором должна сработать выбранная функция. Это и обеспечивает нам более гибкий полиморфизм — то, что вместо простой спецификации типа аргумента мы в состоянии наложить на аргумент и его тип почти произвольное ограничение.
С некоторой точки зрения на полиморфизм и природу типов (такой как у тебя, например), подобное поведение выходит за рамки понятия "полиморфизм". С моей — нет. Здесь разница в слишком глубоких посылках, и философском подходе, чтобы так легко говорить, что кто-то "неверно понимает полиморфизм". Я бы выразился, что с моей точки зрения, ты понимаешь его узко — а именно в соответствии с его реализацией в распространенных ОО языках. Ну а свой взгляд на это явление, а также объяснение, почему это на мой взгляд не противоречит известному определению полиморфизма, я привел. Если непонятно, давай пообсуждаем.
G>>И самое смешное, еще пытаешься меня учить, что такое паттерн-матчинг . VD>Похоже что ты не верно понимаешь значения слова полиморфизм. Но боюсь вместо обсуждения этого в получить новую порцию оскарблений.
Правильно боишься. Вежливый человек на твоем месте сказал бы "похоже, мы с тобой по разному понимаем значение слова полиморфизм". Вот в такой формулировке — да, есть что пообсуждать. А в твоей — обсуждать с тобой то, что я "не верно понимаю", мне не хочется. Потому как самый адекватный ответ на такую фразу — "сам дурак" . Но мы ведь вежливые люди, и не хотим разводить здесь флейм, не так ли? Поэтому я промолчу
Здравствуйте, prVovik, Вы писали:
Q>>Бред какой-то. Типа, если в Лиспе нет оператора for, то он не может покрыть возможностей С++? Лиспу не нужны эти возможности шаблонов, поскольку в его рамках они бессмысленны. V>Повторяю еще раз.
Ну да, повторенье мать учения, и все такое...
V> Шаблоны в С++ нужны для манипуляции типами.
Спорно.
V> Ты говоришь, что шаблоны в лиспе лучше, чем шаблоны в С++. Из этого сравнения следует вывод, что шаблоны лиспа лучше манипулируют типами, чем шаблоны С++.
Тем более спорно. Вывод опирается на ложную посылку.
V> Но в лиспе нет типов!!!
А это уже смешно. Динамическая типизация не предполагает отсутствия типов. Другими словами, "в лиспе есть типы!!!"
V> Следовательно, само сравнение шаблонов С++ и лиспа БРЕДОВОЕ!
Вывод опирается на две БРЕДОВЫЕ посылки. Кстати, использование КАПИТАЛИЗАЦИИ воспринимается как КРИК, это не вежливо.
V>Это разные, несравнимые вещи.
Спорно. Вместо повторения советую переформулировать. Может вы и умную вещь придумали, да больно мудрено, не поймут вас люди, смеятся над вами будут.
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, Gaperton, Вы писали:
WH>Учись гуглить вставай на лыжи... инетом будешь не обижен. WH>Предложение в следующий стандарт С++ подойдет?
Подойдет для чего? Что ты мне доказать хочешь? Я в курсе что такое мультиметоды, вообще-то. И то, что добавить их можно при желании куда угодно — дурацкое-то дело нехитрое, а семантика простая. Вот когда они появятся в стандарте и популярных компиляторах, тогда и будешь спрашивать "подойдет?". А пока — хоть обгуглись.
А вообще, между нами девочками, вопрос адресовался Владу, лично, который вместо того, чтобы написать нормальный содержательный ответ демонстрирует какие-то странные ужимки. Наверно готовится к очередному замеру. А потом еще удивляется, что с ним нормально общаться не получается.
Здравствуйте, Геннадий Васильев, Вы писали:
ГВ>Так что, вся разница между C++ и LISP с этой точки зрения сводится к тому, что C++ позволяет оперировать понятием "тип" на уровне языка, а LISP — на уровне надстройки. Не быстро, разумеется, это работает, но тем не менее...
V>> Это разные, несравнимые вещи. ГВ>Ну скажем так — сравнивать их можно, но сравнение будет совсем не в пользу C++. На LISP потенциально можно играть описаниями типов похлеще, чем с помощью шаблонов C++. Ну что такое плюсовый шаблон с точки зрения машины, ориентированой на обработку структур символов? Ну взяли набор символов, заменили по некоторым правилам одни символы на другие и — вуаля, получили специализацию шаблона. А используя LISP мы можем вообще взять да и выпулить нафиг часть описаний методов. Или перевернуть всё вверх ногами и скомпилировать новый код шаблона (reflection+emitting в одном флаконе). И всё это — не выходя за рамки элементарной, в сущности, исполнительной системы. Одна беда — не слишком быстро оно работает.
Я уже замучился повторять, что шаблоны — это не машина для генерации кода!!! Шаблоны — это средство создания статически полиморфного кода со статической типизацией. Это их ЕДИНСТВЕННОЕ концептуальное предназначение. Тут утверждается, что макросы лиспа более гибки и мощны, но позвольте, разме могут они создавать статически полиморфный код? НЕТ!. А шаблоны могут! И в этом их основная прелесть! Ничего другого от них и не требуется! Ну не должен телефон уметь забивать гвозди!
Вот у меня появился вопрос: а для чего вообще нужны лиспу макросы в том виде, в котором они в нем присутствуют? Почему бы не обходится динамическим полиморфизмом, ведь бонусов от статически типизированного кода мы всеравно не плучим?
P.S.: Страуструп на счет макросов очень точно подметил, что активное их использовании говорит о недостатках выбранного языка, о недостаточности его выразительных средств (там, правда, упаминался еще один вариант, но я не об этом ). Так что такое распространение макросов в лиспе наталкивает на мысли...
Здравствуйте, VladD2, Вы писали:
VD>Вот в данном случае ты как раз начал вещать о мултиметодах и довещался до полной ерунды.
Не хами, модератор. Я уже устал учить тебя вежливости, но видимо придется опять — раз в семье не научили.
VD>А из твоего исходного высказывания совсем не очевидно, что ты имел в виду не полиморфизм, а патрн-матчинг. Особненно это не очевидно в контексте данной темы. Ведь патерн-матчинг к полиморфизкму отношения не имеет. Это сдедство управления ветвлением вроде if/switch.
Перечитай мой изначальный пост от начала до конца, внимательно. Посмотри примеры, которые я привел. Я не могу делать расшифровки каждого абзаца, подобные предыдущей, поэтому придется подумать самому, если конечно у тебя есть желание понять. В чем я лично сильно сомневаюсь. Потому, как ты опять не понимаешь. И самое смешное, еще пытаешься меня учить, что такое паттерн-матчинг . Смени, вобщем, стиль общения, утомляет.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Gaperton, Вы писали: G>>Ну наконец-то, конструктивный разговор. Я исхожу из такого же определения. Прикольно, правда? А паттерн-матчинг я за полиморфизм не принимаю, это разные вещи. Применение паттерн-матчинга при задании аргументов функции — вот это является одним из самых мощных способов достижения полиморфизма в ФЯ.
S>Ну, вообще-то определение полиморфизма в википедии все-таки работает с типами, а не со значениями. Таким образом, паттерн-матчинг является более мощной концепцией, чем ad-hoc полиморфизм, описанный в wiki. Во-первых, он сохраняет некоторые черты параметрического полиморфизма, в том смысле, что множество типов, с которыми может работать конкретная версия функции, не является конечным. Во-вторых, все-таки паттерн может использовать больше информации об аргументе, чем просто тип.
S>С абстрактно-философской точки зрения, тем не менее, я считаю трактовку паттерн-матчинга как средства достижения полиморфизма вполне корректной. Да, ты абсолютно прав: мы можем а) предоставить функцию для работы с аргументами независимо от их типа и б) автоматически выбирать реализацию функции в зависимости от ее аргументов.
Можно рассматривать не только с абстрактно-философской точки зрения. В системе типов Хиндли-Милнера тип — это множество значений. Таким образом, значение тоже является типом.
VladD2:
> ПК>В computer science тип в самом общем смысле берет свое начало от математического понятия разбиения на классы, и определяется как множество значений, которые может принимать переменная, константа, результат функции и т.п. Некоторые языки даже позволяют определять подтипы с явным указанием набора или диапазона принимаемых значений. > > Re[19]: Какой полиморфизм используется в ФЯ?
if здесь совершенно ни при чем, т.к. он строится так, что ему "известно" об используемых "типах" (явный выбор ветвлением), в то время как полиморфизм требует отсутствия этого знания у полиморфного кода.
Давай лучше рассмотрим несколько более близкий пример. Вот как, например, в языке Ада можно определять подтипы целого:
subtype NonNegativeInt is INTEGER range 0 .. INTEGER'LAST;
subtype NegativeInt is INTEGER range INTEGER'FIRST .. -1;
Плюс можно представить наличие двух перегруженных функций (не помню, поддерживает ли Ада перегрузку по диапазонам, но в данном случае это не важно):
procedure foo(Param: NonNegativeInt) is
begin
...
end foo;
procedure foo(Param: NegativeInteger) is
begin
...
end foo;
И вполне можно предствить себе вызовы:
foo(10);
foo(-10);
Это был бы полиморфизм?
Теперь давай перепишем то же самое без предварительного объявления типов (уже не помню, поддерживает ли такое Ада, но, снова таки, это для нас сейчас не имеет никакого значения):
procedure foo(Param: INTEGER range 0 .. INTEGER'LAST) is
begin
...
end foo;
procedure foo(Param: INTEGER range INTEGER'FIRST .. -1) is
begin
...
end foo;
Это все еще полиморфизм, или уже нет?
Я не вижу принципиальной разницы данного случая с pattern matching, разве что последнее позволяет выражать более сложные "типы" параметров по сравнению с поддиапазонами.
> ПК>Соответстенно, в случае использования pattern matching при задании параметров функции, можно считать что для параметров определяется новый тип, значения которого задаются через использованный при определении функции pattern. > > Если мы не хотим получить полнейшую кашу в логике, то не нужно считать ничего что небыло заложено в самом язке. В языках поддерживающих парент-мачинг, есть четко определенное понятие типа. И парент-матчинг на это понятие не распростроняется.
Если мы не будем "считать ничего что небыло заложено в самом язке", то мы о полиморфизме тоже говорить не будем — ибо это надъязыковое понятие.
> Я извиняюсь, но философия должна иметь определенные приделы. Иначе можно договориться до полного маразма. Не вижу смысла отсутпать от общепринятого понятия типа данных в ЯП
В таком случае дай его определение.
Подсказка: популярно-упрощенное "определение из Wikipedia:
In computer science, a datatype (often simply type) is a name or label for a set of values and some operations which can be performed on that set of values.
общепринятым в Computer Science определением не является, и не покрывает даже такой простой случай безымянного типа:
struct { int i; double m; } my_variable;
> а стало быть и от общепринятого понятия полиморфизма.
То же самое относится и к принятому Википедией "определению" полиморфизма.
Posted via RSDN NNTP Server 1.9 gamma
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
VladD2:
> ПК> В этом разговоре речь шла не об определении самих типов, структура которых, в данном случае, определяется на этапе написания программы, а об определении совместимости типов во время вызова функции. При этом совместимость, очевидно, проверяется по структуре типа, а не по его имени, которого у него нет.
> Это называется слабой типизацией. И это уже тема другого разговора.
Это называется ad-hoc полиморфизм для выбора функции (в данном случае использование pattern matching) + параметрический полиморфизм типов (полиморфная система типов функционального языка) + динамическая проверка типов. К слабой типизации это отношения не имеет.
Posted via RSDN NNTP Server 1.9 gamma
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, Аноним, Вы писали:
А>Что-то много эмоций и мало логики. А>Понятие полиморфизм означает применимость функции к разным типам. А>Поскольку эрланг бестиповый язык, никакого полиморфизма в нем не может быть по определению.
Неправильно. Бестиповым языком можно назвать какой-нибудь Forth. А эрланг — это динамически типизированный язык. Если сомневаешься в наличии в нем типов, отсылаю к мануалу по Erlang.
А>Вот это >> poly_function( { A, B } ) -> ...; >> poly_function( [ A, B ] ) -> ...; А>не полиморфная фунция.
Неправильно. Это — полиморфная функция.
А>Применить же сопоставление в одной и той же функции к спискам и кортежам в типизированном языке не получится.
Во-первых, в статически типизированном, конечно. А во-вторых — можно я попробую — вдруг все-таки получится? Вот пример на очень статически типизированном Clean (система типов Милнера-Майкрофта):
::MyType = MyTuple Int Int | MyList [Int]
Funct:: MyType -> Int
Funct ( MyTuple a b ) = a
Funct ( MyList [ a, b ] ) = a
Вот и все. А ты боялся. В статически типизированном Хаскеле (и ML) будет то же самое.
Причем, практически для любых разумных сочетаний фактических типов эелементов А и В возможно определить такой алгебраический тип, что в ML и Хаскель будет то же самое, что и в эрланг (пусть тебя не пугает Int). И наоборот, в "бестиповом" эрланге можно добавить такие же ограничения на типы элементов. А потом прогнать dyalizer, чтобы он статически нашел ошибки типизации.
Впрочем, если не устраивает пример на Clean, я могу привести пример на С++, где такое же сопоставление будет произведено одним простым виртуальным вызовом.
Здравствуйте, Gaperton, Вы писали:
G>Не только в сознании. G>На С++ и Haskell я их могу определить явно, о чем написал в следующем же предложении. G>Ты читаешь и отвечаешь только на первое предложение абзаца, так?
Кстати, тип не обязательно должен быть определен явно, чтобы существовать не только "в голове". В том же С можно в любой момент получить и использовать значение типа, скажем, void***, нигде его явно не определяя. В ML/Haskell просто возможности конструирования типов "на лету" более широки.
Здравствуйте, Gaperton, Вы писали:
Здравствуйте, Gaperton, Вы писали: G>Термин же "бестиповый" в специализированной литературе не распространен, а встречается исключительно в форумах и мэйллистах.
Не буду спорить, термин "бестиповый" менее распространен, но "исключительно в форумах и мэйллистах" — явный перебор. На запрос "typeless language" scirus возвращает более 200 страниц. На "untyped language" — еще больше. Это все равно меньше чем "dynamically typed language", но не настолько чтобы можно было говорить о неупотребительности термина. Наконец, мне лично достаточно одной статьи Карделли, для того чтобы игнорировать любую статистику и считать термин "бестиповый язык" вполне легитимным. Мне он нравится из-за соответствующих параллелей: бестиповое/типизированное лямбда-исчисление, бестиповые/типизированные логики и т.д.
G>Если бы типы отсутствовали, например, в языке Erlang, а существовали только в моем сознании, то и паттерн-матчинг я мог бы выполнять только в своем сознании.
Здесь неявно используется ложная посылка, что паттерн-матчинг связан с типами.
f(1)->...
f(2)->...
f(3)->...
Следует ли признать, что 1,2 и 3 имеют разные типы?
Вообще из Вашей теории следует, что существуют такие типы, как:
— положительные числа;
— четные числа;
— простые числа;
— непустые списки;
— списки, первый элемент которых 1, а второй — alpha;
....
и что любая функция является полиморфной.
Здравствуйте, prVovik, Вы писали:
Q>>Бред какой-то. Типа, если в Лиспе нет оператора for, то он не может покрыть возможностей С++? Лиспу не нужны эти возможности шаблонов, поскольку в его рамках они бессмысленны. V>Повторяю еще раз. Шаблоны в С++ нужны для манипуляции типами. Ты говоришь, что шаблоны в лиспе лучше, чем шаблоны в С++. Из этого сравнения следует вывод, что шаблоны лиспа лучше манипулируют типами, чем шаблоны С++. Но в лиспе нет типов!!! Следовательно, само сравнение шаблонов С++ и лиспа БРЕДОВОЕ!
Ну, это не совсем так.
Насколько я помню, тип данных определяется набором применимых к нему операций. Т.е., к составному типу применима операция "извлечь элемент X" или, скажем, "вызвать метод Z"
Действительно, базовый LISP оперирует символами в списках и тут никаких новых типов не определишь. В этом и сила и слабость LISP-машины. Если мы сконструируем список например, так:
(
(class myclass)
((member m1) a)
((member m2) b)
)
то можно будет говорить о том, что мы создали список определённого типа, или же — объект некоторого типа. Почему? Потому что к этому списку применимы некоторые, вполне кокнкретные операции, например — извлечение значения члена m1, определение имени типа и т.п.
Так что, вся разница между C++ и LISP с этой точки зрения сводится к тому, что C++ позволяет оперировать понятием "тип" на уровне языка, а LISP — на уровне надстройки. Не быстро, разумеется, это работает, но тем не менее...
V> Это разные, несравнимые вещи.
Ну скажем так — сравнивать их можно, но сравнение будет совсем не в пользу C++. На LISP потенциально можно играть описаниями типов похлеще, чем с помощью шаблонов C++. Ну что такое плюсовый шаблон с точки зрения машины, ориентированой на обработку структур символов? Ну взяли набор символов, заменили по некоторым правилам одни символы на другие и — вуаля, получили специализацию шаблона. А используя LISP мы можем вообще взять да и выпулить нафиг часть описаний методов. Или перевернуть всё вверх ногами и скомпилировать новый код шаблона (reflection+emitting в одном флаконе). И всё это — не выходя за рамки элементарной, в сущности, исполнительной системы. Одна беда — не слишком быстро оно работает.
Кстати, где-то на Franz inc, есть наблюдение, что производительность труда программистов на Lisp что-то там, на порядок, что ли, больше, чем на C++. Что вобщем-то, неудивительно при потенциале самого LISP.
... << RSDN@Home 1.1.3 stable >>
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, Геннадий Васильев, Вы писали:
ГВ>А какая связь между макросами LISP (я надеюсь, ты это имел ввиду под "лисам") и OpenC++? Я просто не знаю OpenC++ — может, расскажешь?
Здравствуйте, VladD2, Вы писали:
VD>Что ты понимашь под специализацией?
Создание отдельной функции/класса для каждого конкретного типа. В случае шаблонов от этого не уйти. А вслучае полиморфных функций в ФЯ можно. То что некоторые компиляторы эти функции специализируют, их дело, но в принципе это совершенно необязательно.
VD>С++ логическое развите С. Все его возможности С++ включает. С предпочитается только если нужно переносить код на экзотические платформы. Ну, и отдельными фанатами. В общем, С++ от наличия С не становится не перестает быть системым языком.
Ну и где же многочисленные операционные системы, созданные на С++, который включает С? Под Юниксами даже обычные пользовательские программы, как правило, написаны на С.
VD>Идея шаблонов была в АДА (если не ошибаюсь) и об этом писал Страуступ. А то что что-то где-то изучается еще не значит что оно служит прототипом всему остальному.
Ну ХЗ что там было в АДА. Ценные идеи заложенные в Лиспе постепенно внедрялись в ИЯ (взять хотя бы оператор if ), а некоторым из них это еще предстоит. Вот, интересно, какие идеи принадлежащие исключительно С++ перейдут в следующие языки и будет ли через 40 лет после его рождения о нем кто-то еще помнить.
VD>На примере того же С/С++ люди скорее видят вред макросов. Я бы не называл макросами то что проходит синтаксическую обработку. Иначе возникает путанница.
Это проблемы С++, а не макросов.
VD>Ага. Вот только толку с них никакого. И суть языка от этого не меняется. Или продолжается интерпритация или начинаются ограничения.
Почему ты думаешь, что Лисп нельзя откомпилировать в машинный код? Я давал ссылку на статью про фирму (или продукт) Orbitz. Там ясно написано, что они оптимизировали Лисп для большей производительности и получали очень высокую скорость.
VD>Да нет там никакой эффективности. Суть языка интерпретаторная. Не может быть быстрым нетипизированный код заточенный на работу со связанными списками.
Это заблуждение. Опровержение — Yahoo купила продукт Пола Грехема, написанный на Лиспе, а не поделки его С++снутых конкурентов.
VD>То есть говорить об отсуствии чего-то в Лиспе бессмиысленно. А о незаточенности С++ подо что-то нормально? Еще раз повторю свою мысль. Заявление об убогости шаблонов С++ провакациооно и неразумно. Они прекрасно решают поставленную перед ними задачу, и имеют массу приемуществ перед другими подходмаи. Эдак все что тебе не нравится можно назвать убогим. По мне так сам Лис убог. Что-же теперь?
Я не называл шаблоны убогими. Я назвал их примитивными по сравнению с макросами в Лиспе (по сравнению, а не вообще). В рамках С++ они может и решают свои задачи и лучше, чем что-то еще, но макросы Лиспа более гибкий и мощный инструмент.
VD>Зашибись. Что нельзя написать на С++? А что нельзя написать на ассемблере? Твоя фраза изумительно к ним подожид. Может написать что-то на ассемблере или понять его не так уж и легко, но пользоваться им можно без проблем. Не находиш что от замены Лисап на Асм ничего не изменилось? Такие рассуждения бессмысленны.
Это ты сам что-то бессмысленное придумал. Я уже говорил, что макрос выглядит как обычная функция, только вместо вызова ее в рантайме, происходит подстановка ее результата в компайлтайме. Что тут сложного?
Q>>А если есть 2 вложенных while? VD>Ты говорил о невозможности. Ну, да и это решается если потрахаться.
Ну вот уже надо трахаться. А ведь это буквально самое простое, что позволяют сделать макросы.
VD>Да. Правдой было бы сказать что ее вообще нет. Все списки пишутся на этом языке. Использование же слов вроде примитивные, вульгарные нужно только для того чтобы унизить чьи-то чувства. Я не поборник С++, но и я чувствую неспроведливось в этих действиях.
Ну давай теперь политкоректно называть это list-challenged или macros-challenged, как это принято в USA чтобы не оскорблять ничьих чувств.
VD>Аналогии не могут использоваться при доказательстве (и темболее при обвинении). Ими можно только иллюстрировать некое описание. Иначе такое доказательство начинает называться демагогией. Так что давай без анлогий. Темболее таких долеких.
Я ничего и не доказываю. Я сделал попытку показать, что идеологически шаблоны куда ближе к макросам Лиспа, чем к полиморфным функциям ФЯ.
VD>Еще раз повторюсь, что шаблоны в С++ не являются чистыми макросами. Это фича для обобщенного программирования. Как ее можно сравнивать с макросами из нетипизированного интерпретируемого языка я вообще не понимаю. Что же касается возможностей, то дай бог всем ФЯ иметь такие возможности как у С++. Этому бы языку устранить грабли, цены бы ему не было бы.
Вот это точно бездоказательное утверждение.
Кроме того, я надеюсь, что ты сравниваешь шаблоны с макросами в Лиспе, а не с убожеством называемом макросами в С/C++.
Здравствуйте, Курилка, Вы писали:
К>Вот возник вопрос: К>в ФЯ есть полиморфизм типов, что имхо есть очень близко к шаблонам C++. Наряду с шаблонами C++ есть generics Java и C#, но там используются несколько иные механизмы. Так вот — какой из подходов будет ближе к тому, как это работает в ФЯ? К>Заранее сенкс за любую инфу!
Трудно найти людей, которые одновременно в курсе реализации полиморфизма типов в ФЯ и в еще не существующих языках
Здравствуйте, Курилка, Вы писали:
К>Вот возник вопрос: К>в ФЯ есть полиморфизм типов, что имхо есть очень близко к шаблонам C++. Наряду с шаблонами C++ есть generics Java и C#, но там используются несколько иные механизмы. Так вот — какой из подходов будет ближе к тому, как это работает в ФЯ? К>Заранее сенкс за любую инфу!
На самом деле, полиморфные функции в ФЯ достаточно далеки от шаблонов. Шаблоны — это, скорее, примитивный аналог макросов из Лиспа (идея та же). Примитивный в том смысле, что Лисп позволяет делать более мощные модификации программы на основе параметров макроса. Полиморфные функции существуют в единственном экземпляре для любых подходящих для них типов, в то время как в случае шаблонов для каждого типа генерируется своя функция.
Здравствуйте, Quintanar, Вы писали:
Q>На самом деле, полиморфные функции в ФЯ достаточно далеки от шаблонов. Шаблоны — это, скорее, примитивный аналог макросов из Лиспа (идея та же). Примитивный в том смысле, что Лисп позволяет делать более мощные модификации программы на основе параметров макроса. Полиморфные функции существуют в единственном экземпляре для любых подходящих для них типов, в то время как в случае шаблонов для каждого типа генерируется своя функция.
Думаю, ты ошибашся. И в ФЯ при статическом полиморфизме генерируются тучи воплощений. (тому примером являются декомпилированные исходники того же SML.NET). И макросмаи конечно шаблоны не являются, так как проходят синтаксическую проврку. И примитивными они не являются, так как на ним очень многое можно сделать.
В общем, ненадо недооценивать технологии которые не нравятся. И переоценивать те, которые нравятся.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Quintanar, Вы писали:
Q>И язык системного программирования не С++, а С.
Отчасти это так, но только из-за того, что компиляторы С проще, и, следовательно, более распространены.
Q>Поскольку Лисп изучается во многих западных университетах, то весьма вероятно, что идея шаблонов возникла не на пустом месте, а по аналогии с Лиспом. Ибо это первый язык, где подобная идея была внедрена и используется очень интенсивно. Препроцессор OCaml'a тоже не на пустом месте возник. Люди видят насколько полезны макросы и пытаются внедрить их в другие языки.
какая разница, что появилось первым?
Q>Лисп нетипизированный язык, поэтому предложение сделать типизированую конструкцию бессмысленно. Нужно сравнивать какие возможности предлагают шаблоны и макросы.
Именно потому, что лисп нетипизированный язык, сравнвать его с С++ просто не имеет смысла! Шаблоны в С++ оперируют типами, а в лиспе на этапе компиляции типов нет, следовательно, он не может покрыть возможностей шаблонов С++. А дальше обсуждать нечего.
Здравствуйте, Quintanar, Вы писали:
Q>Да ничего. Дебильный спор какой-то. Я говорю, что есть одна первоначальная идея, которая породила несколько своих вариаций, а мне говорят — какая разница что появилось первым. Чувствую, скоро на замечание, что сборщик мусора впервые появился в Лиспе, буду получать тот же ответ.
Мне действительно по барабану, что и где появлялось первым. Порох, например, китайци первыми придумали, и что теперь всем остальным не использовать огнестрельное оружие?
Q>Да блин. Основное предназначение шаблонов — создавать новые функции и классы с похожей функциональностью на основе параметров.
А зачем надо генерировать функции с похожей функциональностью? Разве нельзя обойтись динамическим полиформизмом? Ведь он и был придуман ради того, чтобы одни и теже функции могли вести себя немного по разному, в зависимости от переданных параметров? Сделать полиморфный вариант STL — это совершенно не проблема. Например, для делфи есть такой полиморфный аналог STL. Для С также существовала масса нетипизированных библиотек, содержащих реализации списков, множеств и пр. структур данных, отличительной особенностью которых являлось то, что они хранили свои элементы, как нетипизированные указатели (void*). Но подобные полиморфные решения c динамической типизацией обладают двумя серьезными недостатками:
1) Производительность. Компилятор не в состоянии проводить агрессивную оптимизацию, подставлять методы (inline). Все проверки безопасности могут быть выполнены только во время работы программы и, следовательно, могут существенно повлиять на ее производительность.
2) Типобезопасность. Возможные ошибки некорректного использования динамически полиморфного кода могут всплыть только на этапе выполнения программы (во время демонстрации её заказчику ). Компилятор не в состоянии тут ничем помочь, так как он не может применить статический контроль типизации.
Решением этих проблем может стать отказ от универсального полиморфного кода и переход к статически типизированному. Именно для этого и служат шаблоны в С++!!!! Именно для создания статически типизированного кода!!! Поэтому я и говорил, что шаблоны С++ оперируют типами. Или другими словами, шаблоны в С++ — это механизм организации статического полиморфизма. Это узкоспециализированный механизм, который АБСОЛЮТНО не предназначен для генерации кода. Из-зи этого совершенно не имеет смысла сравнивать лисповые макросы с шаблонами.
А для генерации кода в С/С++ имеется совершенно другое средство: препроцессор. Вот с ним делать сравнение абсолютно корректно, и я согласен с тем, что в С/С++ препроцессор — это убожество.
Здравствуйте, prVovik, Вы писали:
V>само сравнение шаблонов С++ и лиспа БРЕДОВОЕ!
Большая просьба, выбирать более мягкие выражения. Этот форум не филиал священных войн. Предупреждаю, что подъвекти с оскорбительным характером будут сноситься в "Священные войны".
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, prVovik, Вы писали:
V> 1) Производительность. Компилятор не в состоянии проводить агрессивную оптимизацию, подставлять методы (inline). Все проверки безопасности могут быть выполнены только во время работы программы и, следовательно, могут существенно повлиять на ее производительность. V> 2) Типобезопасность. Возможные ошибки некорректного использования динамически полиморфного кода могут всплыть только на этапе выполнения программы (во время демонстрации её заказчику ). Компилятор не в состоянии тут ничем помочь, так как он не может применить статический контроль типизации.
Может. В динамически типизированных языках можно вывести типы статически из контекста употребления. Не все, конечно, но во многих местах — можно. Из известных языков, где применяется type inference — JScript .NET (сюрприз!).
V>Решением этих проблем может стать отказ от универсального полиморфного кода и переход к статически типизированному. Именно для этого и служат шаблоны в С++!!!! Именно для создания статически типизированного кода!!! Поэтому я и говорил, что шаблоны С++ оперируют типами. Или другими словами, шаблоны в С++ — это механизм организации статического полиморфизма. Это узкоспециализированный механизм, который АБСОЛЮТНО не предназначен для генерации кода. Из-зи этого совершенно не имеет смысла сравнивать лисповые макросы с шаблонами.
Все гораздо проще. В динамически типизированном языке любая функция — "шаблонная". И любой "класс". Там просто нет нужды в механизме, подобном шаблонам — и так все шаблон, причем работает в рантайме. Поэтому макросы лиспа вроде как нельзя сравнивать с шаблонами С++.
Хотя, если посмотреть книжку Александреску, в которой он жестко надругался над С++ — то очень даже можно и нужно . Там он демонстрирует, что в compile time при помощи шаблонов можно сделать практически все, что угодно — благодаря наличию рекурсии мы имеем вычислительную полноту. Ничего не напоминает? Мне напоминает макросы лисп . Так что ответ не так однозначен.
Здравствуйте, Nick_, Вы писали:
N_>Я не вижу тут разницы. Если компилятор С++ знает тип объекта у которого вызывается виртуальный метод, то он может подставить сразу вызов необходимого метода в обход таблиц виртуальных функций.
Причем тут С++ я не знаю. Но сам описанный тобой метод называется спекулятивным устранением виртуальных вызовов. Так что по сути это и есть замена динамического полипорфизма на статический на базе предположения компилятора.
N_>В С++ есть четкое деление на "статический" и "динамический" полиморфизмы только потому, что у них различается синтаксис. Если хочешь рантайм поддержку приходится писать x->foo(y);
Такое деление есть не только в С++. Да и я не о нем говорил. Я говорил в принципе о подходе к реализации. Динамический всегда медленее но универсальнее, а статический пухлее, но шустрее.
N_>В функциональных языках если компилятор знает тип аргумета, то вызывает конкретную функцию, если не знает, то это делает рантайм. В обоих случаях вызов записывается одинаково: foo x y
Это не важно. В любом случае или делаются проверки (выбор) в рантайме, или создаются невидимые воплощения. В С++ тоже тело шаблона одно. Но при воплощении создаются специализированные реализации.
Ты заявлял, что в ФЯ дело осбтоит совершенно иначе. Вот с этим я и не согласен. Все тоже самое. Или компилятор строит статический специализированный кода, или некий универсальный, но с проверкой в рантайме.
N_>Может этот термин и не прижился в рядах web программистов, но в рядах ученых он используется.
Ну, снова. Давай не будем использовать подобные приемы. Не стоит зачислять себя в ряд ученых, а аппонента в ряд веб-программистов.
Этот термин не прижился нигде. Он просто редок.
N_>Я на досуге попробую найти хороший пример на хаскеле.
Мне кажется нужно вообще сделать общую статью о функциональном стиле программирования с кучей примеров на разных языках. Тогда каждый сможет найти язык на котором примеры ему будут понятны, а остальные поймет по аналогии.
Как идея?
VD>>Ну, а дальше можно выделить два подкласса — это статический полиморфизм и динамический. Динамический требует выбора в рантайме, статический ведет к генерации множества вопложений полиморфного кода и типов.
N_>Вот этого не надо. Это дело компилятора.
Я согласен, что оптимальным решенеим было бы переложить выбор типа полиморфизма на компилятор или даже на рантайм вроде Ява-машины или .Net CLR, но к сожалению зачастую это не так. И нужно четко понимать особенности этих двух типов.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Quintanar, Вы писали:
Q>Ну и где же многочисленные операционные системы, созданные на С++, который включает С? Под Юниксами даже обычные пользовательские программы, как правило, написаны на С.
В каждой современной ОС есть С++-код. А тот же БеОС вроде был в чистую на нем написан.
Q>Ну ХЗ что там было в АДА. Ценные идеи заложенные в Лиспе постепенно внедрялись в ИЯ (взять хотя бы оператор if ), а некоторым из них это еще предстоит. Вот, интересно, какие идеи принадлежащие исключительно С++ перейдут в следующие языки и будет ли через 40 лет после его рождения о нем кто-то еще помнить.
Боюсь через 40 лет не нем еще код писать будут.
Q>Это проблемы С++, а не макросов.
Да нет. Макросы в чистом виде многое усложняют. Тут проблема не только всинтаксисе.
Q>Почему ты думаешь, что Лисп нельзя откомпилировать в машинный код?
По сути. Нутро у него на интерпретацию заточено. Вот Си проектировался чтобы было удобно биты двигать. Его тоже пытались интерпретировать, но ничего хорошего из этого не вышло.
Q> Я давал ссылку на статью про фирму (или продукт) Orbitz. Там ясно написано, что они оптимизировали Лисп для большей производительности и получали очень высокую скорость.
Очень хорошая понятие не определенное. Не думаю, что она сравнима с современными С++-компиляторами.
Q>Это заблуждение. Опровержение — Yahoo купила продукт Пола Грехема, написанный на Лиспе, а не поделки его С++снутых конкурентов.
Нда. Я бы сказал всем доказательствам доказательство.
Q>Я не называл шаблоны убогими. Я назвал их примитивными по сравнению с макросами в Лиспе (по сравнению, а не вообще). В рамках С++ они может и решают свои задачи и лучше, чем что-то еще, но макросы Лиспа более гибкий и мощный инструмент.
Это разные инстументы. Тут вообще сравнения не умесны. А уж с применением слов вроде примитивные и подавно.
Q>Это ты сам что-то бессмысленное придумал. Я уже говорил, что макрос выглядит как обычная функция, только вместо вызова ее в рантайме, происходит подстановка ее результата в компайлтайме. Что тут сложного?
macro From Wikipedia: A macro is an abstraction, whereby a certain textual pattern is replaced according to a defined set of rules. The interpreter or compiler automatically replaces the pattern when it is encountered. In compiled languages, macro-expansion always happens at compile-time.
Еще раз. Если обработка ведется на уровне синтаксиса, то это уже не макросы. Так что и шаблоны, и "макросы" Лиспа по сути расширенная синтаксисческая обработка. По крайней мере суть шаблонов С++ — обобщение кода. А применение макросвойств является побочным эффектом и естественно даже не может сравниваться со специально для этого предназначенными. Сравнивать шаблоны с Лиспом некорректно еще и потому, что шаблоны в основмно оперериуют с типами (причем в компайлтайме), а в Лиспе вообще нет понятия тип до рантайма.
Q>Ну вот уже надо трахаться. А ведь это буквально самое простое, что позволяют сделать макросы.
А никто макросам оды не пел.
Q>Ну давай теперь политкоректно называть это list-challenged или macros-challenged, как это принято в USA чтобы не оскорблять ничьих чувств.
Плевать я на ЮСУ хотел. Я тебе об отношении толкую. Ну, не воспринимаются нормально аргументы подкрепленные такими словами.
Q>Я ничего и не доказываю. Я сделал попытку показать, что идеологически шаблоны куда ближе к макросам Лиспа, чем к полиморфным функциям ФЯ.
Ты доказывашь примитивность шалонов по сравнению с макросами Лиспа.
VD>>Еще раз повторюсь, что шаблоны в С++ не являются чистыми макросами. Это фича для обобщенного программирования. Как ее можно сравнивать с макросами из нетипизированного интерпретируемого языка я вообще не понимаю. Что же касается возможностей, то дай бог всем ФЯ иметь такие возможности как у С++. Этому бы языку устранить грабли, цены бы ему не было бы.
Q>Вот это точно бездоказательное утверждение.
Ага. И то что 90% софта на плюсах писано тоже не доказательство.
Q>Кроме того, я надеюсь, что ты сравниваешь шаблоны с макросами в Лиспе, а не с убожеством называемом макросами в С/C++.
Я вообще не хочу сравнивать макросы с шаблонами.
К примеру, могу рассказать про дженерики в Шарпе. Они решают ту же задачу что и шаблоны с теми ограничениями что не поддерживают переменных ну и там по мелочи. Так вот они компилируются в мсил и воплощаются уже в рантайме. А раз в рантайме, то это уж точно не макросы. Но суть то та же!
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Причем тут С++ я не знаю. Но сам описанный тобой метод называется спекулятивным устранением виртуальных вызовов.
VD>Ты заявлял, что в ФЯ дело осбтоит совершенно иначе. Вот с этим я и не согласен.
Я такого не заявлял.
VD>Ну, снова. Давай не будем использовать подобные приемы. Не стоит зачислять себя в ряд ученых, а аппонента в ряд веб-программистов. VD>Этот термин не прижился нигде. Он просто редок.
Не надо мешать индустрию и науку. У инженеров работающих на производстве и у ученых совершенно разная терминология. То, что для инженера швеллер, труба, уголок, рельс или полоса для ученого всего лишь балка. Так как по сути, у них отличаются только моменты инерции. Это наверное глупо выглядит, когда иженеры начинают обсуждать теорию упругости в своих терминах.
Здесь то же самое. Большинство здесь инженеры, а обсуждают вещи из computer science. Давайте придерживаться терминалогии соответствующей теме. Если термин где-то не используется — это не повод считать что он не прижился. Ведь если термин из ядерной физики не прижился на кухне у домохозяйки, это не значит что физики-ядерщики должны заменить их на кухонные.
Здравствуйте, VladD2, Вы писали:
Q>>Я не называл шаблоны убогими. Я назвал их примитивными по сравнению с макросами в Лиспе (по сравнению, а не вообще). В рамках С++ они может и решают свои задачи и лучше, чем что-то еще, но макросы Лиспа более гибкий и мощный инструмент. VD>Это разные инстументы. Тут вообще сравнения не умесны. А уж с применением слов вроде примитивные и подавно.
Уместны, уместны.
Q>>Это ты сам что-то бессмысленное придумал. Я уже говорил, что макрос выглядит как обычная функция, только вместо вызова ее в рантайме, происходит подстановка ее результата в компайлтайме. Что тут сложного? VD>macro From Wikipedia: A macro is an abstraction, whereby a certain textual pattern is replaced according to a defined set of rules. The interpreter or compiler automatically replaces the pattern when it is encountered. In compiled languages, macro-expansion always happens at compile-time.
Wikipedia может думать всё, что угодно, но я так припоминаю, что конструкция defmacro была в LISP, когда wikipedia ещё и в проекте не было. И на самом деле макро в LISP выглядит почти так же, как и определение функции.
VD>Еще раз. Если обработка ведется на уровне синтаксиса, то это уже не макросы.
Ещё раз. defmacro определяет макрос. Просто значение термина "макрос" для C++ и LISP очень сильно отличается. И его функциональное наполнение — тоже.
VD> Так что и шаблоны, и "макросы" Лиспа по сути расширенная синтаксисческая обработка. По крайней мере суть шаблонов С++ — обобщение кода. А применение макросвойств является побочным эффектом и естественно даже не может сравниваться со специально для этого предназначенными. Сравнивать шаблоны с Лиспом некорректно еще и потому, что шаблоны в основмно оперериуют с типами (причем в компайлтайме), а в Лиспе вообще нет понятия тип до рантайма.
Да есть там всё. И deftype есть.
Q>>Я ничего и не доказываю. Я сделал попытку показать, что идеологически шаблоны куда ближе к макросам Лиспа, чем к полиморфным функциям ФЯ. VD>Ты доказывашь примитивность шалонов по сравнению с макросами Лиспа.
Quintanar абсолютно прав. И в том, что шаблоны C++ близки lisp-макросам и в том, что шаблоны несколько уже, чем LISP-макросы. Хотя, тут, наверное, правильно говорить, што шаблоны C++ смахивают на этакий статический LISP. Но — только смахивают. Не больше.
Q>>Кроме того, я надеюсь, что ты сравниваешь шаблоны с макросами в Лиспе, а не с убожеством называемом макросами в С/C++. VD>Я вообще не хочу сравнивать макросы с шаблонами.
У вас путаница в терминологии. Действительно, нельзя сравнивать макросы C++ и макросы LISP — это очень разные вещи по сути. Макросы С++ работают с plain-text исходников, а макросы LISP — это почти такие же лямбды, как и любое определение функции LISP. А вот макросы LISP и шаблоны C++, как это ни удивительно, но сравнивать можно (терминологически ужасно, но что поделаешь?). И в принципе, шаблоны C++ тут проигрывают. C++ вообще заметно проигрывает LISP-у в гибкости (Ага, Влад, это я сказал). Впрочем, я вообще не могу представить императивный язык, который мог бы обскакать LISP по своим возможностям. Хоть с шаблонами, хоть с дженериками. По производительности LISP обставляется легко, а по гибкости — даже не представляю. Имено за счёт того, что базис LISP — простейшие операции с простейшими символами и замечательная парадигма "программа=данные". Соответственно, любую LISP-овскую конструкцию можно свести к списку. LISP-макросы/функции/типы — в том числе.
... << RSDN@Home 1.1.3 stable >>
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, VladD2, Вы писали:
Q>> ну и что, единственное их отличие от обычных функций состоит в том, что они преобразуют код программы на этапе компиляции. VD>Которой по сути нет. И получается, что точно так же генерируют специализации, только из-за того, что рантайм пермешан с компайлтаймом, черт ногу сломит в классификации того или иного явления.
Генерирует он или нет — сильно зависит от исполняющей системы.
Q>> А сделать ими можно просто на несколько порядков больше, чем в С++. VD>Очередное преувеличение. Аналогично моожно сделать обратное заявление. А что? Попробуй сделать типизированную конструкцию на Лиспе?
Ты неправильно делаешь противопоставление. Сильная типизация и гибкость — вообще антагонисты и конкретный баланс зависит от потребностей разработки. Сильная типизация нам нужна для жёсткости и надёжность, а LISP-овская унификация — для гибкости и компактности конструкций.
Q>> В С++, например, невозможно объявить новую конструкцию в языке. VD>Да можно. Есть маньяки которые уже пол Плюсов переписали. Вот только получается так же натянуто и криво как и на Лиспе. В итоге черт ногу сломит в этом коде.
На самом деле, получается своего рода "стремление" к LISP. Т.е., для того, чтобы наиграть кучу интересных вещей приходится на C++ писать некий "метаязык", который выражается в виде своих последовательностей скобочек разного вида и т.п. Тогда как чистый LISP — это и есть только скобочки и символы (значения символов).
VD>Честно говоря Лисп с его миллионом скобочек меня вводит в состояние гипноза.
Не одного тебя, но и кода там получается, AFAIK, поменее, чем на C++/Java/C#. Просто в силу разных парадигм. LISP не делает различия между данными и программой (оценка зависит только от того, вызван ли quote, или eval для списка), а императивные языки такое различие делают. Отсюда и гибкость, и компактность кода.
Q>> а в Лиспе — это одна из простейших задач. Тут вообще не о чем спорить, в Лиспе данные и код выглядят одинаково VD>одинаково фигово.
Ну, на императивный язык типа C++ мало похоже, разумеется. Но по сути Quintanar не ошибается. С точки зрения исполнительной системы LISP код и данные унифицированы. Чего не скажешь ни о C# ни о C++ ни о Java.
Q>> и последний легко обрабатывать средствами самого языка. С++ с его шаблонами такое и не снилось. VD>Ну, а Лиспу не снилось то что делают на шаблонах плюсов.
Не, скорее наоборот — это C++ и в страшном сне не приснится то, что можно творить на LISP. Например, можно и вложенные while как параметр передать.
VD> Лисп конечно можно выразить через самого себя. Но вот работать это будет еще медленее чем он сам. А плюсы не смотря на ве количество граблей заложенных в них позволяют писать шустрый код.
Вот тут ты прав — C++-код на самом деле работает пошустрее, чем LISP-овский. Но с другой стороны, LISP и не претендует на звание языка системного ПО. Хотя, и на нём web-серверы пишут.
Q>>Кстати, уверен, что с утверждением, что шаблоны в С++ примитивны по сравнению с макросами в Лисп, согласится любой, кто знает оба языка. И еще раз, примитивны не в смысле, что они просты, а что возможностей они предоставляют на порядки меньше. VD>Да разные они. Для разного предназначены. Твое утверждение изначально некорректно. И принципияльно содержит в сбебе желаение узизить эти самые шаблоны.
Я согласен с Quintanar. Он правильно употребил термин "примитивные". Никакого уничижительного оттенка там заметно не было. Тем более, что Quintanar специально оговорился:
Примитивный в том смысле, что Лисп позволяет делать более мощные модификации программы на основе параметров макроса.
Единственная ошибка была в том, что не повторил расшифровку термина "макрос", что вызвало кучу нежелательных аллюзий. И вагон флейма.
VD>Нормально бы звучал заявление вроде "В лиспе есть возможности которые или вообще отстсуствуют в С++ или трудно реализуются." Как в прочем верно было ы и братное. Но тут и спорить бы никто не стал.
Да ладно тебе кипеть возмущённым разумом. Quintanar был прав в исходном сравнении на 100%.
... << RSDN@Home 1.1.3 stable >>
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Ты страшный зануда. VD>В данном случая ты усомнившись в предпосылке сделал заключение о неверности всего вывода. Ты уж или развенчивай предпосылки или уж хотя бы называй выводы спроными. А то получается без доказательства или фактов ты наклеиваеш на выводы ярлык ложности.
Ладно, скажу тебе правду. В данном случае я во второй строке выразил (не специально получилось) свое мнение касательно первой посылки. Я надеюсь, вопрос исчерпан? Или продолжим разбор моих опечаток и стиля? Ты спрашивай, не стесняйся
К>>Но типы там есть, причём компилятор/интерпретатор тебе по башке треснет, если ты что-то нето начнёшь вытворять (аля выполнение ф-ций неприменимых к данным типам и т.п.). V>Треснуть то он треснет, но когда? Во время демонстрации программы заказчику? Да уж спасибо, не надо. Остается только молиться на тестеров... V>А вот в случае со статической типизацией, о том, что программа некорректна, станет известно еще на этапе компиляции! Компилятор автоматически проконтролирует корректность использования переменных, еще до запуска программы.
Ocaml треснет по башке именно в момент компиляции.
Здравствуйте, Геннадий Васильев, Вы писали:
ГВ>Ты неправильно делаешь противопоставление.
Я предлагаю не противопоставлять не сопоставимые вещи.
ГВ>Сильная типизация и гибкость — вообще антагонисты и конкретный баланс зависит от потребностей разработки. Сильная типизация нам нужна для жёсткости и надёжность, а LISP-овская унификация — для гибкости и компактности конструкций.
По-моему, предположение о том, что компактность это безусловное благо в корене не верно. Говорить нужно в первую очередь о выражительности и понятности. И тут Лисп в полной заднице. Стоит чуть-чуть увеличить сложность задачи, как код на лиспе превращается в лес скобок понять смысл которого можно только путем последовательной мысленной интерпретации. Тут он сравни Перлу. Программы сразу понятны только тому кто их пишет. Так сказать тайт-онли-языки. Мне кажется такой подход очень опасным.
Кстати, я давно наблюдаю за стилем кодирования приверженцев ФС (функционального стиля). И он мене очень не нарвится. Постонянное стремление к компактности кода переходит все разумные границы. Одно-двух буквенные переменные и функции, стремление написать как можно больше в одну строку, зачастую наплевателство на струкуризацию кода. В общем компактность кода ставится выше простоты его восприятия. Причем все это подкрепляется словами об абстракции. Это не абстракция — это раздалбайство.
Гибкость тоже имеет свои пределы. Универсальные системы всегда проигрывают специализированным как в простоте понимания, так и в производительности и надежности. Для решения конкретных задач нужно искать не самое "гибкое" средство, а самое подходящее. И я не думаю, что, например, тот же Янус будет проще создать на Лиспе, Хаскеле или Окамле, как в прочем и на С++.
ГВ>На самом деле, получается своего рода "стремление" к LISP. Т.е., для того, чтобы наиграть кучу интересных вещей приходится на C++ писать некий "метаязык",
А почму метаязык — это сразу лисп? Получается именно метаязык. Но средства у него свои. И проблемы С++ — это не непохожесть на Лисп, а наличие горы граблей и то что эти метасредства эмулируются на побочных эффектах средств для метапрограммирования не предназначенных. Мы вот как раз пытаемся создать систему метапрограммирования для C# (R#
). Если все получится как хочется, то выйдет очень гибкая система при этом собственными механизмами модификации кода.
Что касается макросов Лиспа, тот тут на лицо терминалогическая путанница. Они по сути не имеют права называться макросами, так как работают на уровне синтаксиса языка, а не на уровене модификации тектса.
ГВ>Не одного тебя, но и кода там получается, AFAIK, поменее, чем на C++/Java/C#. Просто в силу разных парадигм. LISP не делает различия между данными и программой (оценка зависит только от того, вызван ли quote, или eval для списка), а императивные языки такое различие делают. Отсюда и гибкость, и компактность кода.
Еще раз повторюс, что компактность достигнутая потерей смысла — это зло. То же и с гибкостью. На Лиспе нельзя решить элементаные задачи, при это постоянно идут рассуждения о его гибкости. Кому нужна такая гибкость? Мне нужна нибкость при создание ГУИ. Чем тут мне поможет Лисп? Убогими библиотеками наспех прицепленными к его скобочкам? Да ни в жизни. А вот XAML решает пробелму на ура. Причем в нем даже есть некие функциональные черты. Хотя это скрее язык разметки. Но XAML в итоге превращается в код на императивном языке (обычно на Шарпе) и управлять состоянием ГУИ созданного на XAML намного удобнее на том самом императивном языке. И итоге выходит, что реальный потенциал императивного языка снабженного современным набором средств разработки нманого выше чем очень гибких и компактных. Так в чем правда, брат? (с) отморозок из отмороженного фильма.
ГВ> Не, скорее наоборот — это C++ и в страшном сне не приснится то, что можно творить на LISP. Например, можно и вложенные while как параметр передать.
Но нельзя создать статически типизированный код. В общем, опять пошло сравнение предназначенного для разного вещей. Надоело. Не могут делать макросы Лиспа того что могут шаблон. И не потому что у них гибкости не хватает, а потому что не предназначены для этого. Так что прикрате проводить аналогии и что-то по этим аналогиям доказывть.
ГВ>Я согласен с Quintanar. Он правильно употребил термин "примитивные". Никакого уничижительного оттенка там заметно не было. Тем более, что Quintanar специально оговорился: ГВ>
ГВ>Примитивный в том смысле, что Лисп позволяет делать более мощные модификации программы на основе параметров макроса.
Нет слов. Ладно. Начинаю разводить ту же демагогию, держитесь.
Итак, макросы лиспа приметивны потому что не позволяют проивзодить примитивные операции записи в файл, вывода на принтер и т.п. Так же они примитивны по сравнению с простейшим оператором if, так как в отличии от него не позволяют выполнять проверок в рантайме. Ну, и уж несомненно они явлются полнейшим примитивизмом по сравнению с такими мощнешими средствами С++ как Шаблоны! Ведь в отличии от шаблонов они не позволют создавать статически-типизированный, типобезопасный код. В то же время шаблоны С++ не просто на голову рабивают это примитивное образование, но и вообще низвергают весь лисп в небытие, так как кроме всех выше перечисленных достоинств еще позволяют создавать выско-производительный код, а так же, использую побочные эффекты, даже эмулировать действия тех самых примитивных макросов Листпа.
Ну, что нормально если я буду общаться в такой манере? Нет? Ну, тогда не нужно использовать подбные подходы.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Gaperton, Вы писали:
G>А вообще, между нами девочками, вопрос адресовался Владу, лично, который вместо того, чтобы написать нормальный содержательный ответ демонстрирует какие-то странные ужимки. Наверно готовится к очередному замеру. А потом еще удивляется, что с ним нормально общаться не получается.
Думаючто ты пыташся спровоцировать других на флэйм. Но у тебя ничего не выйдет. Вместо этого я просто приведу несколько цитат:
G>А во вторых, при разрешении полиморфного вызова учитываются не только типы, но и значения аргументов (в "обычных" языках — только типы). Причем, в разрешении вызова принимаются во внимание все аргументы (а не только тип неявного аргумента виртуальной функции — объект). Это самое главное отличие полиморфизма ФЯ от обычных языков.
VD>В "обычных языках" это называется мутиметодами. Они кое где реализованы. А кое где реализуются имеющимися средствами.
G>О как (век живи — век учись)! Пример пожалуйста, особенно "обычного языка", где учитываются значения аргументов при полиморфном вызове в run-time (твой комментарий по правилам русского языка относится ко всему абзацу, а не ко второй половине ).
VD>1. Мы кажется уже договорились, что полиморфизм бывает статический. При этом 90% современных языков это делают.
VD>2. мультиметоды multimethods
G>Примеров "обычных языков" нет. Впрочем, как и необычных. Все понятно. Вопрос снят.
G>Я в курсе что такое мультиметоды, вообще-то. И то, что добавить их можно при желании куда угодно — дурацкое-то дело нехитрое, а семантика простая.
Другими словами свое утвреждение:
А во вторых, при разрешении полиморфного вызова учитываются не только типы, но и значения аргументов (в "обычных" языках — только типы). Причем, в разрешении вызова принимаются во внимание все аргументы (а не только тип неявного аргумента виртуальной функции — объект). Это самое главное отличие полиморфизма ФЯ от обычных языков.
Явно говорящее о том, что мултиметоды есть явный признак ФЯ ты сам же и опроверг:
Я в курсе что такое мультиметоды, вообще-то. И то, что добавить их можно при желании куда угодно — дурацкое-то дело нехитрое, а семантика простая.
Ну, и учитывая, что реализации мультиметодов в ИЯ уже есть (ссылки выше), меня полностью удовлетворяет данный ответ. Не удовлетворяет только твоя граничащая с хамством манера выражать своих мысли.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, prVovik, Вы писали:
V>Я уже замучился повторять, что шаблоны — это не машина для генерации кода!!! Шаблоны — это средство создания статически полиморфного кода со статической типизацией. Это их ЕДИНСТВЕННОЕ концептуальное предназначение. Тут утверждается, что макросы лиспа более гибки и мощны, но позвольте, разме могут они создавать статически полиморфный код? НЕТ!. А шаблоны могут! И в этом их основная прелесть! Ничего другого от них и не требуется! Ну не должен телефон уметь забивать гвозди!
Погоди, не кипятись. Никто и не спорит с тем, что шаблоны C++ — "средство создания статически полиморфного кода". Более того, они не просто "могут" создавать СПМК, а это единственное, что они обязаны делать.
В свою очередь у LISP со статической типизацией, в основном, всё не очень хорошо. Но и речь-то шла не о статическом полиморфизме. А о том, какие композиционные возможности предоставляют шаблоны C++ и макросы LISP. Понимаешь разницу? Если нет, то давай сопоставим допустимые разновидности аргументов шаблонов C++ и макросов LISP. Сопоставление очень простое — на две строки:
шаблоны C++ — типы, сигнатуры функций или константы;
макросы LISP — списки.
Теперь сделаем другое сравнение. Что есть программа на C++ и LISP:
C++ — операторы, функции, переменные, опеределения типов; (гусары, молчать! Я знаю, что допускаю здесь упрощение.)
LISP — список, представляющий лямбда-выражение.
Следовательно, аргументом макроса LISP может служить любая конструкция, моделируемая на этом языке, тогда как аргументом шаблона C++, например, оператор "switch" с набором case-веток служить не может (т.е. — может, но его надо просто завернуть в функцию). На LISP это делается с полпинка. Вот и вся разница. Потому и говорят тебе, что макросы LISP предоставляют больше возможностей по компоновке конечной программы (пожалуй, утверждение должно звучать именно так, а не "... модификации программы"). И действительно, C++-шаблоны в этом смысле представляются примитивным решением по сравнению с макросами LISP, т.к. не могут вопсринимать в качестве аргументов нкоторые конструкции C++.
V>Вот у меня появился вопрос: а для чего вообще нужны лиспу макросы в том виде, в котором они в нем присутствуют? Почему бы не обходится динамическим полиморфизмом, ведь бонусов от статически типизированного кода мы всеравно не плучим?
Речи о статически типизированом коде, вобщем-то, не было. Да, с точки зрения конструкции программы, LISP умееет оперировать типами (структурированными списками), но это не совсем то же самое, что и статически типизированный код C++.
V>P.S.: Страуструп на счет макросов очень точно подметил, что активное их использовании говорит о недостатках выбранного языка, о недостаточности его выразительных средств (там, правда, упаминался еще один вариант, но я не об этом ). Так что такое распространение макросов в лиспе наталкивает на мысли...
Опять передёргиваешь. Причём здесь Срауструп? Страуструп говорит о макросах с низкоуровневой семантикой, которые на выходе могут выплюнуть всё, что угодно. К примеру:
#define MY_MACRO(abc) abc + - / BCD
С точки зрения препроцессора — вполне себе допустимый макрос. С точки зрения синтаксиса C++ результат его применения — недопустим.
В свою очередь, макрос LISP не может выдать некорректный с точки зрения LISP-машины код. И в то же время, он позволяет выполнять очень навороченные модификации и работу как со своим телом, так и с аргументами. Т.е., за синтаксис можно не бояться. Это — первое, что роднит LISP-макросы и C++-шаблоны.
Второе. Как шаблоны могут принимать в качестве параметров типы, так и LISP-макросы могут принимать в качестве параметров списочные структуры. Результат подстановки и в том и в том случае даёт некую новую вычислительную структуру: тип C++ — для мшаблонов C++ и лямбда-выражение для LISP.
Полученная структура обрабатывается кодогенератором C++ и исполняющей системой LISP соответственно.
Результирующий код, разумеется, может быть ошибочным в смысле несоответствия требованиям пользователя, но это уже совсем другое.
Давай так. Чтобы не было терминологических передёргиваний, будем называть C++-макросы: "макросами", а LISP-макросы: "defmacro-выражениями". Идёт? И ещё, я сам — давний сторонник именно статической типизации, но и на мой взгляд LISP-макросы куда как более гибкое и мощное средство, нежели шаблоны C++. Но! Именно с указанной несколько выше точки зрения.
... << RSDN@Home 1.1.3 stable >>
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, Геннадий Васильев, Вы писали:
ГВ>Да, спасибо, посмотрю, но тем не менее к теме дискуссии это пока не относится. Мы всё-таки, сопоставляли C++ templates и LISP defmacro.
Позволю уточнить — вы.
ГВ> Я так полагаю, что в итоге ты согласился с доводами оппонентов по существу.
По существу я уже сказал. Если сравнивать средства мета-программирования, то лушче смотреть на продвинутые вещи вроде ОпенС++. А шаблоны можно сравинить со средствами обощенного программирования в статически типизированных языках. А так как Лисп к таковым не относится, то и не стоит сравнивать.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Мне нужна нибкость при создание ГУИ. Чем тут мне поможет Лисп? Убогими библиотеками наспех прицепленными к его скобочкам? Да ни в жизни. А вот XAML решает пробелму на ура. Причем в нем даже есть некие функциональные черты. Хотя это скрее язык разметки.
Кстати, лисп в чистом виде. Только вместо кучи нормальных скобочек, которые тебе не нравятся, есть куча не нормальных,
которые тебе нравятся. Парадокс.
Здравствуйте, Gaperton, Вы писали:
VD>>Вот в данном случае ты как раз начал вещать о мултиметодах и довещался до полной ерунды. G>Не хами, модератор. Я уже устал учить тебя вежливости, но видимо придется опять — раз в семье не научили.
Хамиш в данном случае ты. Причем с переходом на личности.
G>Перечитай мой изначальный пост от начала до конца, внимательно. Посмотри примеры, которые я привел.
Почитал очень внимательно. Понял, что ты, по-моему, в принципе не верно понимаешь термин полиморфизм. Патерн-матчинг ты принимаешь за полиморфизм. Именно по этому я тебя и не понял. Собственно вот определение из которого я исхожу http://en.wikipedia.org/wiki/Polymorphism_%28computer_science%29#Ad-hoc_polymorphism
G>Я не могу делать расшифровки каждого абзаца, подобные предыдущей, поэтому придется подумать самому, если конечно у тебя есть желание понять. В чем я лично сильно сомневаюсь. Потому, как ты опять не понимаешь.
Что же... если тебя постоянно не понимаю, то возможно ты просто плохо объясняшь? Ну, или ошибашся? В общем, это не повод для перехода на личности.
G>И самое смешное, еще пытаешься меня учить, что такое паттерн-матчинг .
Похоже что ты не верно понимаешь значения слова полиморфизм. Но боюсь вместо обсуждения этого в получить новую порцию оскарблений.
G>Смени, вобщем, стиль общения, утомляет.
Прекращай хамить и переходить на личность собеседника. Это форум не для нездов и разборок.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Gaperton, Вы писали: G>Ну наконец-то, конструктивный разговор. Я исхожу из такого же определения. Прикольно, правда? А паттерн-матчинг я за полиморфизм не принимаю, это разные вещи. Применение паттерн-матчинга при задании аргументов функции — вот это является одним из самых мощных способов достижения полиморфизма в ФЯ.
Ну, вообще-то определение полиморфизма в википедии все-таки работает с типами, а не со значениями. Таким образом, паттерн-матчинг является более мощной концепцией, чем ad-hoc полиморфизм, описанный в wiki. Во-первых, он сохраняет некоторые черты параметрического полиморфизма, в том смысле, что множество типов, с которыми может работать конкретная версия функции, не является конечным. Во-вторых, все-таки паттерн может использовать больше информации об аргументе, чем просто тип.
С абстрактно-философской точки зрения, тем не менее, я считаю трактовку паттерн-матчинга как средства достижения полиморфизма вполне корректной. Да, ты абсолютно прав: мы можем а) предоставить функцию для работы с аргументами независимо от их типа и б) автоматически выбирать реализацию функции в зависимости от ее аргументов.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
> В computer science тип в самом общем смысле <...> определяется как множество значений, которые может принимать переменная, константа, результат функции и т.п.
P.S. Плюс, естественно, множество операций, к ним применимых. Хотя на приведенные рассуждения это дополнение не влияет, лучше сразу уточнить, дабы исключить лишние "разборы полетов"
Posted via RSDN NNTP Server 1.9 gamma
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Кстати, расматрение значений как типов определяемых на время вызова процедуры — это прямейшее нарушение принципов инкапсуляции. Хотя это понятие из области ООП, и слабо применимо к ФЯ, но печальные последствия при таком взгляде на жизнь не заставят себя долго ждать. Рано или поздно будут сделаны неверные предположения о "динамическом типе". На то и были придуманы приципы ООП, чтобы материализовывать все свои окраничения и предположения в рамках понтия объекта и его типа.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>if здесь совершенно ни при чем, т.к. он строится так, что ему "известно" об используемых "типах" (явный выбор ветвлением), в то время как полиморфизм требует отсутствия этого знания у полиморфного кода.
Гы. Патерн-матчингу тоже извесно об используемых типах. ФЯ вообще стремятся максимально много знать о типах. По этому полиморфизм в ФЯ большей частью статический. И вообще, ОО-теории хреново воспринимаются функциональщиками. Понятие инкапсуляция для ФЯ довольно пустой звук. Полиморфизм выглядит не так как в ИЯ. И вообще мировозрение сильно иное. Основная тенденция — это замена инкапсуляции на декомпозицию. Т.е. вместо абстрагингвании данных упор делается на абстрагировании кода. Корче другой мир.
ПК>Давай лучше рассмотрим несколько более близкий пример. Вот как, например, в языке Ада можно определять подтипы целого: ПК>
ПК>subtype NonNegativeInt is INTEGER range 0 .. INTEGER'LAST;
ПК>subtype NegativeInt is INTEGER range INTEGER'FIRST .. -1;
ПК>
ПК>Плюс можно представить наличие двух перегруженных функций (не помню, поддерживает ли Ада перегрузку по диапазонам, но в данном случае это не важно):... ПК>Это был бы полиморфизм?
Гы. Это полиморфизм. Так как есть разные четко различимыетипы и способность намерянно скрывать разницу между ними. А вот если типы не вводить, а делать проверки при определении функций или при их вызове, то это уже управление ветвлением.
В твоем примере даже не нужно вводить диапазонов. Это по сути не важно. Достаточно чтобы типы просто по разному интерпретировались. Скажем, типы скорость и масса могут измеряться целыми числами лежащими в одном диапазоне. Но интерпретироваться они будут по разному. Так что в терминах АДА-ы можно было бы написать нечто вроде:
subtype velocity is INTEGER;
subtype mass is INTEGER;
...
procedure foo(Param: velocity) is
begin
...
end foo;
procedure foo(Param: mass) is
begin
...
end foo;
...
ну, и потом создать две переменные, присвоить им одинаковые (с точки зрения целых чисел) значения и вызвать метод foo. При этом должен вызваться нужный перегруженный метод. Я не случаяно тут упомянул слово метод, так как это чистейшей воды ООП, хотя и в несколько процедурной форме.
Другими словами неважно, что типы принадлежать к разным диапазонам значений. Важно, что они обрабатываются как разные типы.
А вот когда одинаковые типы обрабатываются в звисимости от их значений, то это всего лишь вид ветвления исполнения. И совершенно пофигу как оно реализовано. Паттерн-матчинг позволяет перенести выбор из описания вызова функции в описание самой функции. Это несомненно интересное решение и оно точно так же как и перегрузка функций позволяет сделать код менее комплексным и более наглядным, но это не полиморфизм! Увы.
ПК>Теперь давай перепишем то же самое без предварительного объявления типов (уже не помню, поддерживает ли такое Ада,
Не уверен, но вроде нет. Ада врде как тяготеет к строгости, и типы имеющие разные названия в ней интерпретируются как разные. Так что типы с одинаковыми ограничениями просто не совпадут. Так что динамическое их определение бессмысленно. Собственно это и есть разница между патерн-матчингом (динамической проверкой значения) и полиморфизмом (пофигу какой проверки типов).
ПК> но, снова таки, это для нас сейчас не имеет никакого значения): ПК>
ПК> procedure foo(Param: INTEGER range 0 .. INTEGER'LAST) is
ПК> begin
ПК> ...
ПК> end foo;
ПК> procedure foo(Param: INTEGER range INTEGER'FIRST .. -1) is
ПК> begin
ПК> ...
ПК> end foo;
ПК>
ПК>Это все еще полиморфизм, или уже нет?
По-моему — это глупость. Объяви методы вот так:
procedure foo(Param: INTEGER range 0 .. 5) is
...
procedure foo(Param: INTEGER range INTEGER 4 .. 10) is
...
И подсунь им в качестве значения 4 или 5. Что при этом произойдет? А вот при объявленом типе все будет четко не взирая на значение переменных. Это и есть разница между полиморфизмом и паттерн-матчингом.
Языки поддерживающие паттерн-матчинг обычно проверяют, чтобы условия диапазона значений не пересикались. Ну, или выбирают первый подходящий диапазон. Делается это примерно по такой схеме:
def foo(int val) =
where
if паттерн1: {...}
else if паттерн2: {...}
else : {...}
Собственно это легко переписывается в импиративном стиле
int foo(int val)
{
if (паттерн1(val))
foo1(val);
else if (паттерн2(val))
foo2(val);
else
foo3(val);
}
ПК>Я не вижу принципиальной разницы данного случая с pattern matching, разве что последнее позволяет выражать более сложные "типы" параметров по сравнению с поддиапазонами.
Ну, может теперь увидишь.
ПК>Если мы не будем "считать ничего что небыло заложено в самом язке", то мы о полиморфизме тоже говорить не будем — ибо это надъязыковое понятие.
Нет уж. Полиморфизм поддерживается языком. В ООП — это обычно перегрузка методов и переопределение методов. В приципе еще есть еще мультиметоды (перегрузка более чем по одному типу). И все это не паттерн-матчинг. Так как паттерн-матчинг анализирует значения не обращая внимание на тип аргумента.
ПК>В таком случае дай его определение.
Уже задолбался это делать. Я тут уже раз 10 давал ссылки на Википедию. Поиск тебе поможет.
ПК>Подсказка: популярно-упрощенное "определение из Wikipedia: ПК>
In computer science, a datatype (often simply type) is a name or label for a set of values and some operations which can be performed on that set of values.
ПК>общепринятым в Computer Science определением не является,
Чушь.
ПК> и не покрывает даже такой простой случай безымянного типа: ПК>
ПК>struct { int i; double m; } my_variable;
ПК>
И правильно делает. Потому-что это нарушение теории типов. Безымянные типы подразумевают сличение типов по соотвествию физической структуры типа данных. А это в свою очередь, является грубейшим нарушением инкапсуляции и левейшим хаком. К сожалению, подобные хаки включены во многие ЯП, что не делает чести их разработчикам.
Ты описал тип у которого потиряли имя. По идее нормальный компилятор/интерпритатор просто не должен знать что с ним делать дальше, так как он не имеет права дать привести этот тип к некоторому известному, ну, а без этого такое обявление ничем не отличается от объявления двух отдельных переменных (m и i).
>> а стало быть и от общепринятого понятия полиморфизма.
ПК>То же самое относится и к принятому Википедией "определению" полиморфизма.
В Википедии дано нормальное понятие типа. Можешь попытаться найти другое. И попытаться впихнуть в него динамические проверки значений. Но боюсь тебя ждет большой облом.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Gaperton, Вы писали:
G>Скромнее надо быть, Влад.
Будь.
G>Смешно и грустно твои посты читать. Неудобно прям за тебя становится.
Не читай. Чем твоих постов мньше, тем меньше флэйма.
G>Лучше разговоров с тобой избегать, как и чтения твоих постов. Для верности. Чем я и собираюсь заняться с этого момента. Все мои просьбы ты проигнорировал, так что мое время для тебя кончилось.
Ловлю тебя на слове. Буду надеяться, что это не очередные громкие слова.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
VladD2:
>>> ПК>Тогда почему вот это по твоему утверждению не полиморфизм? >>> ПК>
>>> ПК>poly_function( { A, B } ) -> ...;
>>> ПК>poly_function( [ A, B ] ) -> ...;
>>> ПК>
>>> Если { A, B } — это картэж, а [ A, B ] — это список, то это несомненно полиморфная функция <...> В вот если будте, как-то так: <...> То это будет паттерн-матчинг
> ПК> А в первом случае pattern matching происходить не будет?
> Какая разница?
Разница такая, что ты в своем сообщении, на которое я отвечал, противопоставил полиморфизм и pattern matching, хотя в данных случаях, как мы уже установили ранее, второе используется для достижения первого.
> Главное, что ты демонстрируешь перегрузку называя ее поттерн-матчингом.
1) Я не называю перегрузку pattern matching (в противном случае, приведи, пожалуйста, соответствующие ссылки).
2) Без добавления pattern matching в определение функций мы получим набор одинаковых функций, т.к. единственное, чем они отличаются — patterns, использованные в объявлении.
Итого: важно сочетание одного с другим. И получившийся результат — использование pattern matching в объявлении перегруженных функций для обеспечения возможности выбора между ними — и есть один из вариантов полиморфизма. О чем так долго твердили большевики
Posted via RSDN NNTP Server 1.9 gamma
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
А>"Динамически типизированный" и бестиповый — это одно и то же.
бред.
Для примера сравни безтиповый ассемблер, в котором тип данных
определяется исключительно применяемой операцией. Ты можешь
сложить два числа, хотя там могут быть указатели.
Ошибки не будет. Динамически типизируемый язык выдаст ошибку.
Безтиповых языков сейчас, наверное, кроме ассемблера и нет.
Хотя можно поспорить насчет tcl.
Здравствуйте, Gaperton, Вы писали:
А>>"Динамически типизированный" и бестиповый — это одно и то же. G>Кто это вам сказал?
В литературе термины "бестиповый язык", "динамически типизированный язык","язык со скрытыми типами" и т.п. используются как синонимы. Просто "бестиповый"- короче и, имхо, лучше отражает суть дела.
G>Вы не правы. Не стоит повторяться, я и так прекрасно вас понял. К мануалу я уже вас отсылал, раз не помогло, приведу цитату.
[]
А вот это как раз и есть те самые типы, существующие в нашем сознании.
G>Что-то я не понял. То есть если я напишу так G>
G>funct( { X, Y } ) -> X * Y.
G>то эрланг бестиповый язык. А если я добавлю вот это G>
G>funct( { X, Y } ) where is_integer( X ), is_integer( Y ) -> X * Y.
G>то он превратится в типизированный (чем, кстати, не замедлит воспользоваться компилятор). И это все не меняя самого языка. Чудеса? Как будем разрешать этот забавный казус?
Элементарно, Ватсон. В типизированный он не превратится. Принципиально ничего нового по сравнению с
funct( { X, Y } ) where X <10, Y>0 -> X * Y.
А вот если компилятор начнет сообщать о том, что функцию нельзя применить к терму из-за несоответствия типов, вот тогда и язык и станет типизированным.
G>Понятна точка зрения. Не согласен с вашим пониманием полиморфизма.
Ну, это не столько мое понимание, сколько авторское. G>Попробуйте перенести эти рассуждения на Smalltalk. Он динамически типизирован, т. е. в ваших терминах "бестиповый". Ваши рассуждения сведутся к абсурду. Если я не прав, напишите здесь про Smalltalk подробно.
Поскольку я не вижу способа приведения к абсурду, то писать про Smalltalk не буду, лучше уж Вы.
G>Намек понял. Формально — да, это один тип.
Так тип и есть формальное понятие.
G>А вы не сильно удивитесь, если я скажу, что определение типа несложно разбить на три определения, так, чтобы и tuple и list являлись отдельными типами? И что это у нас поменяет? Радикально — ничего, но функция станет полиморфной, так?
С какой это стати она станет полиморфной?
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Sinclair, Вы писали:
S>>Влад, перестань упираться.
VD>И признать очевидную ерунду?
S>> Ок, паттерн матчинг — это отсутствие разницы в использовании объектов разного типа. Где я не прав?
VD>В выделенном жирным. ПМ — это средство управление ветвлением при исполнении на основе анализа значений. Красивый аналог if-а и switch-а.
Тогда вызов виртуальной функции тоже не полиморфизм, а средство управления ветвлением при исполнении на основе анализа значений. Красивый аналог if-a и switch-a.
Здравствуйте, Nick_, Вы писали:
N_>Тогда вызов виртуальной функции тоже не полиморфизм, а средство управления ветвлением при исполнении на основе анализа значений. Красивый аналог if-a и switch-a.
А вот вызов виртуальной функции зависит исключительно от динамического типа объекта. При этом никаких условий ни в методе, ни при его вызове нет.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Вот возник вопрос:
в ФЯ есть полиморфизм типов, что имхо есть очень близко к шаблонам C++. Наряду с шаблонами C++ есть generics Java и C#, но там используются несколько иные механизмы. Так вот — какой из подходов будет ближе к тому, как это работает в ФЯ?
Заранее сенкс за любую инфу!
22.10.04 22:49: Перенесено модератором из 'Философия программирования' — AndrewVK
Здравствуйте, INTP_mihoshi, Вы писали:
INT>Здравствуйте, Курилка, Вы писали:
К>>Вот возник вопрос: К>>в ФЯ есть полиморфизм типов, что имхо есть очень близко к шаблонам C++. Наряду с шаблонами C++ есть generics Java и C#, но там используются несколько иные механизмы. Так вот — какой из подходов будет ближе к тому, как это работает в ФЯ? К>>Заранее сенкс за любую инфу!
INT>Трудно найти людей, которые одновременно в курсе реализации полиморфизма типов в ФЯ и в еще не существующих языках
Я думаю, что множества скорее всего почти совпадают, но мощность у них очень мала
З.Ы. Интересно — кто-нибудь видел всуе живого теоретика/практика ФП? (в смысле близкого к разработке ФЯ)
Здравствуйте, Курилка, Вы писали:
К>Вот возник вопрос: К>в ФЯ есть полиморфизм типов, что имхо есть очень близко к шаблонам C++. Наряду с шаблонами C++ есть generics Java и C#, но там используются несколько иные механизмы. Так вот — какой из подходов будет ближе к тому, как это работает в ФЯ? К>Заранее сенкс за любую инфу!
В смысле статический или динамический?
Думаю, оба варианта. Тот же патер-матчинг — это по сути динамический полиморфизм. Ведь вариант функции для пустого списка может быть подобран только в рантайме. С другой стороны работать с известными типами можно и статически (если они известны во время компиляции).
И вообще, если подумать по лучше, то вопрос необходиомсти "динамичности" в полиморфизме — это вопрос достаточноности информации. Если инфомрации достаточно еще при компиляции, то можно спокойно принять решение и жетсно закодировать алгоритм.
Если же информация доступна при компиляции не вся, и полный ее объем становится доступен программе только на этапе выполнения, то без динамических проверок не обойтись, а стало быть статического полиморфизма недостаточно.
Кстати, забавно, что очень часто динамический полиморфизм применяется исключительно для увучшения модульности приложения. Так КОМ не мыслим без виртуальных вызовов. А тот же АТЛ использу применяет забавные методы эмуляции полиморфизма на базе шаблонов.
И еще забавно, что среды вроде дотнета (обладающие средствами JIT-компиляции) потенциально способны превращать динамический полиморфизм в статический. Ведь на самом деле ложки (тфу-ты, компонентов) на самом деле не существует. Реальное приложение монолитно. Оно загружает все модули превращая их в один исполняемый файл. И в момент когда становятся извесны все входящие в приложение модули (это может быть момент когда все они загружены в процесс или даже момент инсталляции приложения на машину клиента) теоритически нет препятствий для преобразования динамического полиморфизма в статический.
В общем, думаю что через несколько лет (возможно десятков) у разработчиков компиляторов/рантаймов и т.п. руки дойдут и до этого. Тогда вопрос статичности или динамичности полиморфизма станет таким же важным как сейчас вопросы автоматического инлайнинга методов, т.е. будут интересовать только разработчиков компиляторов.
... << RSDN@Home 1.1.4 beta 3 rev. 206>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, INTP_mihoshi, Вы писали:
INT>Трудно найти людей, которые одновременно в курсе реализации полиморфизма типов в ФЯ и в еще не существующих языках
Ложки нет (с)
... << RSDN@Home 1.1.4 beta 3 rev. 206>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Курилка, Вы писали:
К>Я думаю, что множества скорее всего почти совпадают, но мощность у них очень мала К>З.Ы. Интересно — кто-нибудь видел всуе живого теоретика/практика ФП? (в смысле близкого к разработке ФЯ)
Ява 1.5, кстати, вышла. А бэты дотнета более чем достаточно для изучения.
... << RSDN@Home 1.1.4 beta 3 rev. 206>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
VD>И еще забавно, что среды вроде дотнета (обладающие средствами JIT-компиляции) потенциально способны превращать динамический полиморфизм в статический. Ведь на самом деле ложки (тфу-ты, компонентов) на самом деле не существует. Реальное приложение монолитно. Оно загружает все модули превращая их в один исполняемый файл. И в момент когда становятся извесны все входящие в приложение модули (это может быть момент когда все они загружены в процесс или даже момент инсталляции приложения на машину клиента) теоритически нет препятствий для преобразования динамического полиморфизма в статический.
В общем случае не получится. Потому как существует внешняя среда (включая пользователя), которая часто владеет львиной долей информации, необходимой для превращения динамического метода в статический.
Здравствуйте, prVovik, Вы писали:
V>В общем случае не получится.
Еще как, получится. Единственное что может помещать — это динамическое изменение ссылок на объект. Но и это в принципе решается. Хотя и сложнее.
V> Потому как существует внешняя среда (включая пользователя), которая часто владеет львиной долей информации, необходимой для превращения динамического метода в статический.
Какя на фиг внешная среда? И что может сделать пользователь? После того как все модули загружены в процесс никакая внешняя среда никого уже не волнует. При подгрузке новых модулей можно проводить пересборку критический участков кода.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Какя на фиг внешная среда? И что может сделать пользователь? После того как все модули загружены в процесс никакая внешняя среда никого уже не волнует. При подгрузке новых модулей можно проводить пересборку критический участков кода.
Динамический полиформизм используется далеко не только для связи компонент. Это скорее факультативная функция. В общем случае, динамический полиформизм в ООП используется в случаях, когда тип объекта невозможно определить на этапе компиляции. Я уже приводил классический пример графического редактора, где используется полиморфная коллекция графических примитивов. Как этот пример можно привести к статическому виду? Предлагаешь на этапе компиляции сгенерировать пару миллиардов всевозможных вариантов этой коллекции (которая в данном случае станет уже кортежем) и выбирать во время работы нужную в зависимости от желания пользователя?
Здравствуйте, VladD2, Вы писали:
VD>В общем, похоже дальнейшие объяснения бесполезны. По крайней мере я ретируюсь.
Влад, ты не похож сам на себя
Из товего исходного сообщения я сделал вполне логичный вывод, что ты считаешь, что единственным препятствием для преобразования динамического полифорымизма к статическому являеются динамически загружаемые компоненты. Как еще иначе можно интерпретировать твою фразу:
И в момент когда становятся извесны все входящие в приложение модули (это может быть момент когда все они загружены в процесс или даже момент инсталляции приложения на машину клиента) теоритически нет препятствий для преобразования динамического полиморфизма в статический.
В общем, думаю что через несколько лет (возможно десятков) у разработчиков компиляторов/рантаймов и т.п. руки дойдут и до этого. Тогда вопрос статичности или динамичности полиморфизма станет таким же важным как сейчас вопросы автоматического инлайнинга методов, т.е. будут интересовать только разработчиков компиляторов.
Я с этим утвнрждннием не согласился и привел свои доводы. Скажи, где моя ошибка?
Здравствуйте, VladD2, Вы писали:
VD>Думаю, ты ошибашся. И в ФЯ при статическом полиморфизме генерируются тучи воплощений. (тому примером являются декомпилированные исходники того же SML.NET). И макросмаи конечно шаблоны не являются, так как проходят синтаксическую проврку. И примитивными они не являются, так как на ним очень многое можно сделать.
VD>В общем, ненадо недооценивать технологии которые не нравятся. И переоценивать те, которые нравятся.
Даже если и генерируются, то исключительно в целях оптимизации. А про макросы. Ты вообще в курсе, что из себя представляют макросы в Лиспе? Они тоже проходят синтаксическую проверку, ну и что, единственное их отличие от обычных функций состоит в том, что они преобразуют код программы на этапе компиляции. А сделать ими можно просто на несколько порядков больше, чем в С++. В С++, например, невозможно объявить новую конструкцию в языке. Если там не было бы while (бы ли бы только goto), никаким удовлетворительным образом невозможно было бы создать макрос реализующий эту конструкцию, а в Лиспе — это одна из простейших задач. Тут вообще не о чем спорить, в Лиспе данные и код выглядят одинаково и последний легко обрабатывать средствами самого языка. С++ с его шаблонами такое и не снилось.
(while (cond) (operators)) <- Вот такое возможно в Лиспе
Кстати, уверен, что с утверждением, что шаблоны в С++ примитивны по сравнению с макросами в Лисп, согласится любой, кто знает оба языка. И еще раз, примитивны не в смысле, что они просты, а что возможностей они предоставляют на порядки меньше.
Здравствуйте, Quintanar, Вы писали:
Q>Даже если и генерируются, то исключительно в целях оптимизации.
Достаточно этого. В С++ все делается исключительно для оптимизации. Язык, понимаш, системного программирования.
Q> А про макросы. Ты вообще в курсе, что из себя представляют макросы в Лиспе?
В курсе, более менее. Но вот Лисп тут приплетать не стоит. Уж лучше поговорить о препроцессоре Окамла. А то для лиспа по барабану, что код, что данные. Один фиг интерпретация.
Q> Они тоже проходят синтаксическую проверку,
Ага. На совместимость с С-выражениями.
Q> ну и что, единственное их отличие от обычных функций состоит в том, что они преобразуют код программы на этапе компиляции.
Которой по сути нет. И получается, что точно так же генерируют специализации, только из-за того, что рантайм пермешан с компайлтаймом, черт ногу сломит в классификации того или иного явления.
Q> А сделать ими можно просто на несколько порядков больше, чем в С++.
Очередное преувеличение. Аналогично моожно сделать обратное заявление. А что? Попробуй сделать типизированную конструкцию на Лиспе?
Q> В С++, например, невозможно объявить новую конструкцию в языке.
Да можно. Есть маньяки которые уже пол Плюсов переписали. Вот только получается так же натянуто и криво как и на Лиспе. В итоге черт ногу сломит в этом коде.
Честно говоря Лисп с его миллионом скобочек меня вводит в состояние гипноза.
Q> Если там не было бы while (бы ли бы только goto), никаким удовлетворительным образом невозможно было бы создать макрос реализующий эту конструкцию,
Да?
#define While(condition) { if (!(condition)) goto end_while;
#define EndWhile end_while: }
...
int i = 0;
While(i < 10)
...
i++;
EndWhile
Q> а в Лиспе — это одна из простейших задач. Тут вообще не о чем спорить, в Лиспе данные и код выглядят одинаково
одинаково фигово.
Q> и последний легко обрабатывать средствами самого языка. С++ с его шаблонами такое и не снилось.
Ну, а Лиспу не снилось то что делают на шаблонах плюсов. Лисп конечно можно выразить через самого себя. Но вот работать это будет еще медленее чем он сам. А плюсы не смотря на ве количество граблей заложенных в них позволяют писать шустрый код.
Q>Кстати, уверен, что с утверждением, что шаблоны в С++ примитивны по сравнению с макросами в Лисп, согласится любой, кто знает оба языка. И еще раз, примитивны не в смысле, что они просты, а что возможностей они предоставляют на порядки меньше.
Да разные они. Для разного предназначены. Твое утверждение изначально некорректно. И принципияльно содержит в сбебе желаение узизить эти самые шаблоны. Нормально бы звучал заявление вроде "В лиспе есть возможности которые или вообще отстсуствуют в С++ или трудно реализуются." Как в прочем верно было ы и братное. Но тут и спорить бы никто не стал.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Достаточно этого. В С++ все делается исключительно для оптимизации. Язык, понимаш, системного программирования.
Но специализация необязательна. Шаблоны же специализируются не по желанию, а по необходимости и в этом значительно отличаются от полиморфных функций. И язык системного программирования не С++, а С.
VD>В курсе, более менее. Но вот Лисп тут приплетать не стоит. Уж лучше поговорить о препроцессоре Окамла. А то для лиспа по барабану, что код, что данные. Один фиг интерпретация.
Поскольку Лисп изучается во многих западных университетах, то весьма вероятно, что идея шаблонов возникла не на пустом месте, а по аналогии с Лиспом. Ибо это первый язык, где подобная идея была внедрена и используется очень интенсивно. Препроцессор OCaml'a тоже не на пустом месте возник. Люди видят насколько полезны макросы и пытаются внедрить их в другие языки.
VD>Которой по сути нет. И получается, что точно так же генерируют специализации, только из-за того, что рантайм пермешан с компайлтаймом, черт ногу сломит в классификации того или иного явления.
Для Лиспа существуют компиляторы. Так что рантайм и компайлтайм там разграничены. Никто не запрещает естесвенно пользоваться интерпретатором, но для эффективности стоит программы компилировать.
VD>Очередное преувеличение. Аналогично моожно сделать обратное заявление. А что? Попробуй сделать типизированную конструкцию на Лиспе?
Лисп нетипизированный язык, поэтому предложение сделать типизированую конструкцию бессмысленно. Нужно сравнивать какие возможности предлагают шаблоны и макросы. С++ не позволяет значительно преобразовывать свой код, все, что он позволяет, это осуществить замену какого-нибудь Т на название реального класса в теле шаблона. Подобное безусловно легко сделать на Лиспе. С другой стороны мы не можем передать в качестве параметра шаблону операторы С++ (если не считать, что мы это эмулируем с помощью специального класса, что не очень здорово) и, наконец, мы уж точно не можем как-то изменить эти операторы — какие-то может быть выкинуть, что-то добавить в зависимости от того, что нам передали.
VD>Да можно. Есть маньяки которые уже пол Плюсов переписали. Вот только получается так же натянуто и криво как и на Лиспе. В итоге черт ногу сломит в этом коде.
Это в С++ криво и натянуто, а в Лиспе нормально. Может написать макрос или понять его не так уж легко, но пользоваться им можно без проблем, поскольку это выглядит как вызов обычной функции.
VD>Честно говоря Лисп с его миллионом скобочек меня вводит в состояние гипноза.
А если есть 2 вложенных while?
Q>> а в Лиспе — это одна из простейших задач. Тут вообще не о чем спорить, в Лиспе данные и код выглядят одинаково VD>одинаково фигово.
Опять же, дело привычки.
VD>Ну, а Лиспу не снилось то что делают на шаблонах плюсов. Лисп конечно можно выразить через самого себя. Но вот работать это будет еще медленее чем он сам. А плюсы не смотря на ве количество граблей заложенных в них позволяют писать шустрый код.
Хм. макросы обрабатываются на этапе компиляции программы, поэтому замедлять Лисп они врядли могут.
VD>Да разные они. Для разного предназначены. Твое утверждение изначально некорректно. И принципияльно содержит в сбебе желаение узизить эти самые шаблоны. Нормально бы звучал заявление вроде "В лиспе есть возможности которые или вообще отстсуствуют в С++ или трудно реализуются." Как в прочем верно было ы и братное. Но тут и спорить бы никто не стал.
Почему же унизить? Если я скажу, что в С++ поддержка списков и деревьев на уровне языка примитивная, я его унижу? Я вижу явные аналогии между макросами и шаблонами и думаю, что последние были придуманы под влиянием Лиспа. Но как не извращайся в С++ выше головы не прыгнешь. Лисп уникален в том смысле, что позволяет модифицировать свой код и писатели макросов этим активно пользуются. В С++ возможны только самые примитивные операции с кодом типа Find&Replace и поэтому макросы-шаблоны там автоматически будут более примитивными. В OCaml придумали кое-что попродвинутей, кстати.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Курилка, Вы писали:
К>>Я думаю, что множества скорее всего почти совпадают, но мощность у них очень мала К>>З.Ы. Интересно — кто-нибудь видел всуе живого теоретика/практика ФП? (в смысле близкого к разработке ФЯ)
VD>Ява 1.5, кстати, вышла. А бэты дотнета более чем достаточно для изучения.
И к чему это ты?
Ява уже у нас ФЯ теперь чтоли и исходники компилятора её смотреть???
Здравствуйте, prVovik, Вы писали:
V>Здравствуйте, Quintanar, Вы писали:
Q>>И язык системного программирования не С++, а С. V>Отчасти это так, но только из-за того, что компиляторы С проще, и, следовательно, более распространены.
Да неужто? Везде где есть gcc есть и g++. Даже на древних HPUX'ax у нас в универе есть С++.
И не от части, а почти всегда.
Q>>Поскольку Лисп изучается во многих западных университетах, то весьма вероятно, что идея шаблонов возникла не на пустом месте, а по аналогии с Лиспом. Ибо это первый язык, где подобная идея была внедрена и используется очень интенсивно. Препроцессор OCaml'a тоже не на пустом месте возник. Люди видят насколько полезны макросы и пытаются внедрить их в другие языки. V>какая разница, что появилось первым?
Большая. Потому что выдумать что-то новое нелегко, проще адаптировать чужие идеи под свои нужды.
V>Именно потому, что лисп нетипизированный язык, сравнвать его с С++ просто не имеет смысла! Шаблоны в С++ оперируют типами, а в лиспе на этапе компиляции типов нет, следовательно, он не может покрыть возможностей шаблонов С++. А дальше обсуждать нечего.
Бред какой-то. Типа, если в Лиспе нет оператора for, то он не может покрыть возможностей С++? Лиспу не нужны эти возможности шаблонов, поскольку в его рамках они бессмысленны.
Здравствуйте, Quintanar, Вы писали:
Q>Да неужто? Везде где есть gcc есть и g++. Даже на древних HPUX'ax у нас в универе есть С++.
И что с того?
Q>Большая. Потому что выдумать что-то новое нелегко, проще адаптировать чужие идеи под свои нужды.
И что с того?
Q>Бред какой-то. Типа, если в Лиспе нет оператора for, то он не может покрыть возможностей С++? Лиспу не нужны эти возможности шаблонов, поскольку в его рамках они бессмысленны.
Повторяю еще раз. Шаблоны в С++ нужны для манипуляции типами. Ты говоришь, что шаблоны в лиспе лучше, чем шаблоны в С++. Из этого сравнения следует вывод, что шаблоны лиспа лучше манипулируют типами, чем шаблоны С++. Но в лиспе нет типов!!! Следовательно, само сравнение шаблонов С++ и лиспа БРЕДОВОЕ! Это разные, несравнимые вещи.
Здравствуйте, VladD2, Вы писали:
VD>В смысле статический или динамический?
Обьясните мне, что подразумевается под статическим полиморфизмом, а что под динамическим?
Я знаю только ad-hoc и параметрический полиморфизмы.
ad-hoc — это перегрузка(overloading) и то, что обычно понимается под полиморфизмом в С++.
parametric — это то, что в функциональных языках понимается под полиморфизмом.
Шаблоны в С++ — это подобие параметрического полиморфизма.
Здравствуйте, prVovik, Вы писали:
Q>>Большая. Потому что выдумать что-то новое нелегко, проще адаптировать чужие идеи под свои нужды. V>И что с того?
Да ничего. Дебильный спор какой-то. Я говорю, что есть одна первоначальная идея, которая породила несколько своих вариаций, а мне говорят — какая разница что появилось первым. Чувствую, скоро на замечание, что сборщик мусора впервые появился в Лиспе, буду получать тот же ответ.
V>Повторяю еще раз. Шаблоны в С++ нужны для манипуляции типами. Ты говоришь, что шаблоны в лиспе лучше, чем шаблоны в С++. Из этого сравнения следует вывод, что шаблоны лиспа лучше манипулируют типами, чем шаблоны С++. Но в лиспе нет типов!!! Следовательно, само сравнение шаблонов С++ и лиспа БРЕДОВОЕ! Это разные, несравнимые вещи.
Да блин. Основное предназначение шаблонов — создавать новые функции и классы с похожей функциональностью на основе параметров. Причем параметрами могут быть не только другие классы, но и константы. Макросы в Лиспе предназначены абсолютно для того же — для того, чтобы создавать куски кода с похожей функциональностью на основе параметров — функций, костант, кусков Лисповского кода. Если ты не видишь здесь никакой аналогии, то спорить не о чем.
Здравствуйте, Nick_, Вы писали:
N_>Обьясните мне, что подразумевается под статическим полиморфизмом, а что под динамическим?
Статический когда выбор конкретного варианта осуществляется компилятором (перегрузка и т.п.) и динамический кодга конкретный вариант выбирается в рантайме на базе динамического выбора.
N_>Я знаю только ad-hoc и параметрический полиморфизмы.
Не думаю, что этот термин реально прижился. Не все из Википедии нужно брать на вооружении.
N_>ad-hoc — это перегрузка(overloading) и то, что обычно понимается под полиморфизмом в С++. N_>parametric — это то, что в функциональных языках понимается под полиморфизмом. N_>Шаблоны в С++ — это подобие параметрического полиморфизма.
Это все не типизация. Это общие разрозненные слова. Реально имет значение смысл полиморфизма: создание универсального кода (процедур, функций, методов) или типов, т.е. так чтобы код и типы можно было абстрагировать от конкретных используемых в них типов.
Ну, а дальше можно выделить два подкласса — это статический полиморфизм и динамический. Динамический требует выбора в рантайме, статический ведет к генерации множества вопложений полиморфного кода и типов.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Quintanar, Вы писали:
Q>Но специализация необязательна. Шаблоны же специализируются не по желанию, а по необходимости и в этом значительно отличаются от полиморфных функций.
Что ты понимашь под специализацией?
Q>И язык системного программирования не С++, а С.
С++ логическое развите С. Все его возможности С++ включает. С предпочитается только если нужно переносить код на экзотические платформы. Ну, и отдельными фанатами. В общем, С++ от наличия С не становится не перестает быть системым языком.
Q>Поскольку Лисп изучается во многих западных университетах, то весьма вероятно, что идея шаблонов возникла не на пустом месте,
Идея шаблонов была в АДА (если не ошибаюсь) и об этом писал Страуступ. А то что что-то где-то изучается еще не значит что оно служит прототипом всему остальному.
Q> а по аналогии с Лиспом.
А зачем такие натянутые аналогии?
Препроцессор OCaml'a тоже не на пустом месте возник. Люди видят насколько полезны макросы и пытаются внедрить их в другие языки.
На примере того же С/С++ люди скорее видят вред макросов. Я бы не называл макросами то что проходит синтаксическую обработку. Иначе возникает путанница.
Q>Для Лиспа существуют компиляторы.
Ага. Вот только толку с них никакого. И суть языка от этого не меняется. Или продолжается интерпритация или начинаются ограничения.
Q> Так что рантайм и компайлтайм там разграничены.
Что-то не заметно.
Q> Никто не запрещает естесвенно пользоваться интерпретатором, но для эффективности стоит программы компилировать.
Да нет там никакой эффективности. Суть языка интерпретаторная. Не может быть быстрым нетипизированный код заточенный на работу со связанными списками.
VD>>Очередное преувеличение. Аналогично моожно сделать обратное заявление. А что? Попробуй сделать типизированную конструкцию на Лиспе?
Q>Лисп нетипизированный язык, поэтому предложение сделать типизированую конструкцию бессмысленно.
То есть говорить об отсуствии чего-то в Лиспе бессмиысленно. А о незаточенности С++ подо что-то нормально? Еще раз повторю свою мысль. Заявление об убогости шаблонов С++ провакациооно и неразумно. Они прекрасно решают поставленную перед ними задачу, и имеют массу приемуществ перед другими подходмаи. Эдак все что тебе не нравится можно назвать убогим. По мне так сам Лис убог. Что-же теперь?
Q>Это в С++ криво и натянуто, а в Лиспе нормально.
Ага. А мужики то и не знают. (с)
Q> Может написать макрос или понять его не так уж легко,
Все. Достаточно. Это и называется убого!
Q> но пользоваться им можно без проблем,
Зашибись. Что нельзя написать на С++? А что нельзя написать на ассемблере? Твоя фраза изумительно к ним подожид. Может написать что-то на ассемблере или понять его не так уж и легко, но пользоваться им можно без проблем. Не находиш что от замены Лисап на Асм ничего не изменилось? Такие рассуждения бессмысленны.
Q> поскольку это выглядит как вызов обычной функции.
Ну, да. А вызов С++-ного кода выглядит вулгарно и неприлично.
VD>>Честно говоря Лисп с его миллионом скобочек меня вводит в состояние гипноза.
Q>Это дело привычки.
К ассмблеру тоже можно привыкнуть. Вопрос тольк нужно ли?
Q>А если есть 2 вложенных while?
Ты говорил о невозможности. Ну, да и это решается если потрахаться.
Q>Опять же, дело привычки.
Опять же с.м. выше.
Q>Хм. макросы обрабатываются на этапе компиляции программы, поэтому замедлять Лисп они врядли могут.
Его замедлять и не нужно. Медленней уже почти некуда.
Q>Почему же унизить?
Ты сейчас ссам с собой разговариваешь? Я незнаю зачем сравнивать совершенно разные вещи испоьзуя эпитеты вроде "примитивнее".
Q> Если я скажу, что в С++ поддержка списков и деревьев на уровне языка примитивная, я его унижу?
Да. Правдой было бы сказать что ее вообще нет. Все списки пишутся на этом языке. Использование же слов вроде примитивные, вульгарные нужно только для того чтобы унизить чьи-то чувства. Я не поборник С++, но и я чувствую неспроведливось в этих действиях.
Q> Я вижу явные аналогии между макросами и шаблонами и думаю
Аналогии не могут использоваться при доказательстве (и темболее при обвинении). Ими можно только иллюстрировать некое описание. Иначе такое доказательство начинает называться демагогией. Так что давай без анлогий. Темболее таких долеких.
Q>, что последние были придуманы под влиянием Лиспа.
Это утверждение как миниум спорно.
Q> Но как не извращайся в С++ выше головы не прыгнешь. Лисп уникален в том смысле, что позволяет модифицировать свой код и писатели макросов этим активно пользуются. В С++ возможны только самые примитивные операции с кодом типа Find&Replace и поэтому макросы-шаблоны там автоматически будут более примитивными. В OCaml придумали кое-что попродвинутей, кстати.
Еще раз повторюсь, что шаблоны в С++ не являются чистыми макросами. Это фича для обобщенного программирования. Как ее можно сравнивать с макросами из нетипизированного интерпретируемого языка я вообще не понимаю. Что же касается возможностей, то дай бог всем ФЯ иметь такие возможности как у С++. Этому бы языку устранить грабли, цены бы ему не было бы.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Quintanar, Вы писали:
Q>Да блин. Основное предназначение шаблонов — создавать новые функции и классы с похожей функциональностью на основе параметров. Причем параметрами могут быть не только другие классы, но и константы. Макросы в Лиспе предназначены абсолютно для того же — для того, чтобы создавать куски кода с похожей функциональностью на основе параметров — функций, костант, кусков Лисповского кода. Если ты не видишь здесь никакой аналогии, то спорить не о чем.
Вообще-то шаблоны концептуально задумывались как средство создания обобщенного кода. А уж как макросами ими начали пользоваться от нехватки других средств.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Gaperton, Вы писали:
G>...АДТ (абстрактные типы данных
Ты хотел сказать АТД (ADT)?
G>А во вторых, при разрешении полиморфного вызова учитываются не только типы, но и значения аргументов (в "обычных" языках — только типы). Причем, в разрешении вызова принимаются во внимание все аргументы (а не только тип неявного аргумента виртуальной функции — объект). Это самое главное отличие полиморфизма ФЯ от обычных языков.
В "обычных языках" это называется мутиметодами. Они кое где реализованы. А кое где реализуются имеющимися средствами.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Gaperton, Вы писали:
G>>Спорно. VD>... G>>Тем более спорно. Вывод опирается на ложную посылку.
VD>Т.е. спорно в твоих устах значит бесспорно неверно? Мне кажется слова спорный и ложный синонимами не являются.
Спорный тезис, в моих устах, является ложной посылкой, если используется в качестве посылки. Посылка может являтся либо истинной, либо нет. Промежуточного варианта в логике пока не придумали. Если посылка не является истинной, то она ложная. В таком вот аксепте. Компрене ву?
А вообще, может не будем цепляться к словам? Это оффтоп.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Gaperton, Вы писали:
G>>...АДТ (абстрактные типы данных
VD>Ты хотел сказать АТД (ADT)?
Я обычно говорю ADT (АДТ) . Что это ты сегодня за мой русский язык взялся?
G>>А во вторых, при разрешении полиморфного вызова учитываются не только типы, но и значения аргументов (в "обычных" языках — только типы). Причем, в разрешении вызова принимаются во внимание все аргументы (а не только тип неявного аргумента виртуальной функции — объект). Это самое главное отличие полиморфизма ФЯ от обычных языков.
VD>В "обычных языках" это называется мутиметодами. Они кое где реализованы.
О как (век живи — век учись)! Пример пожалуйста, особенно "обычного языка", где учитываются значения аргументов при полиморфном вызове в run-time (твой комментарий по правилам русского языка относится ко всему абзацу, а не ко второй половине ).
Только CLOS не надо приводить, ок? Термин "мультиметод" оттуда, и это диалект лиспа
Не думаю, что в списке примеров окажется С#, Java, и даже Smalltalk. Вряд ли это будет такой уж "обычный" язык. Пример, пример в студию. Интересно, и я думаю, не только мне.
VD>А кое где реализуются имеющимися средствами.
Гхм. Имеющееся средство называется double dispatch для случая двух аргументов, я про это упомянул. Реализуется везде, имеющимися средствами, бо дурацкое дело нехитрое. У Мейерса описан еще более извращенный способ. Если ты о чем то другом, то будь любезен, расскажи, интересно. А то не вполне понятна цель твоего ответа — он не слишком информативен — один хитрый ленинский прищур
Здравствуйте, Gaperton, Вы писали:
G> Все гораздо проще. В динамически типизированном языке любая функция — "шаблонная". И любой "класс".
Скорее, полиморфная. Но это уже терминология, так что не важно...
G>Хотя, если посмотреть книжку Александреску, в которой он жестко надругался над С++ — то очень даже можно и нужно . Там он демонстрирует, что в compile time при помощи шаблонов можно сделать практически все, что угодно — благодаря наличию рекурсии мы имеем вычислительную полноту. Ничего не напоминает? Мне напоминает макросы лисп . Так что ответ не так однозначен.
Приведу аналогию. Вот компания Nokia выпустила сотовый телефон в титановом корпусе. Он очень крепкий и, наверное, им можно забивать гвозди. Дак вот, сравнивать этот телефон с молотком мне кажется некорректно, даже несмотря на то, что телефоном в принцепе можно забивать гвозди. .
Понятно, что молотком забивать гвозди проще, но из-за этого у телефона его телефонных качеств не прибавляется и не убавляется .
Я говорю: "А зато, с помощью молотка нельзя звонить". На что мне отвечают:
Бред какой-то... Лиспу не нужны эти возможности шаблонов, поскольку в его рамках они бессмысленны.
V>Приведу аналогию. Вот компания Nokia выпустила сотовый телефон в титановом корпусе. Он очень крепкий и, наверное, им можно забивать гвозди. Дак вот, сравнивать этот телефон с молотком мне кажется некорректно, даже несмотря на то, что телефоном в принцепе можно забивать гвозди. . V>Понятно, что молотком забивать гвозди проще, но из-за этого у телефона его телефонных качеств не прибавляется и не убавляется .
Все аналогии некорректны. Мы не дети, чтобы переходить на яблоки.
V>Я говорю: "А зато, с помощью молотка нельзя звонить". На что мне отвечают: V>
Бред какой-то... Лиспу не нужны эти возможности шаблонов, поскольку в его рамках они бессмысленны.
V>
Правильно тебе отвечают. В лиспе делается все тоже самое, что делается на шаблонах, легко обходясь без понятия шаблона. На шаблонах, при помощи техники Александреску, можно сделать через зад многие вещи, которые делаются на макросах лиспа, и делаются там красиво. Я не понимаю, причем тут "А зато, с помощью молотка нельзя звонить".
Здравствуйте, Gaperton, Вы писали:
V>>Приведу аналогию. Вот компания Nokia выпустила сотовый телефон в титановом корпусе. Он очень крепкий и, наверное, им можно забивать гвозди. Дак вот, сравнивать этот телефон с молотком мне кажется некорректно, даже несмотря на то, что телефоном в принцепе можно забивать гвозди. . V>>Понятно, что молотком забивать гвозди проще, но из-за этого у телефона его телефонных качеств не прибавляется и не убавляется . G>Все аналогии некорректны. Мы не дети, чтобы переходить на яблоки.
Думаю, у меня получилать очень хорошая аналогия
V>>Я говорю: "А зато, с помощью молотка нельзя звонить". На что мне отвечают: V>>
Бред какой-то... Лиспу не нужны эти возможности шаблонов, поскольку в его рамках они бессмысленны.
V>> G>Правильно тебе отвечают. В лиспе делается все тоже самое, что делается на шаблонах, легко обходясь без понятия шаблона.
Из твоих слов следует, что на лиспе легко можно писать статически полиморфный код со статической типизацией? Это так?
Здравствуйте, Gaperton, Вы писали:
G>Может. В динамически типизированных языках можно вывести типы статически из контекста употребления. Не все, конечно, но во многих местах — можно. Из известных языков, где применяется type inference — JScript .NET (сюрприз!).
Если есть вывод типов, то есть и статическая типизация. Но есть языки просто не предназначенные для статической типизации. Например, тот же Питон. В нем вообще нет объявлений переменных. Первое же упоминание и появляется переменная. Далее переменная может быть переопределена. Получается, что сделать типзированную переменную очень трудно. Проще создать неких вариант или указатель. Далее списки. Конечно можно предпологать, что в списке должны быть объекты только одного типа. Но это предположение нестыкуется с нетипизированныеми языками. Ну, нет в нем понятия типизированного списка. В итоге для процедуры то может и можно вывести, что список однотипный, но общаться то с ней прйдется именно нетипизированными списками. А что с этого толку? Ведь на пребразование уйдет слишком много времени. А ведь код на сегодня все больше закладывается в независимые компонеты, а стало быть у компилятора просто нет всей информации. В итоге теоритически то можно выводить типы. Но фактически сам язык и его рантайм должны быть заточены под это. У JScript .NET рантайм строготипизированный. А вот у Лиспа он явно на типизацию не рассчитан.
G> Все гораздо проще. В динамически типизированном языке любая функция — "шаблонная". И любой "класс". Там просто нет нужды в механизме, подобном шаблонам — и так все шаблон, причем работает в рантайме. Поэтому макросы лиспа вроде как нельзя сравнивать с шаблонами С++.
Именно! У низ разная "заточка".
G>Хотя, если посмотреть книжку Александреску, в которой он жестко надругался над С++
Я бы сказал жестоко.
G> — то очень даже можно и нужно .
Скорее у него вышло нечто вроде Окамла.
G> Там он демонстрирует, что в compile time при помощи шаблонов можно сделать практически все, что угодно — благодаря наличию рекурсии мы имеем вычислительную полноту. Ничего не напоминает? Мне напоминает макросы лисп . Так что ответ не так однозначен.
И все-таки не однозначен. Макросы Лиспа не делются на компайл и рантайм. Лисп вещь в себе. К тому же при серьезной идее весма странная реализация. Все эти цдр адр... ужас.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Gaperton, Вы писали:
G>Спорный тезис, в моих устах, является ложной посылкой, если используется в качестве посылки.
Спорно.
Точнее ошибочно.
G> Посылка может являтся либо истинной, либо нет.
Спорная посылка — это посылка истинность или ложность которой не очевидна. С точки зрения логики мы имем три состояния:
1. Истинно. И тогда формально верное заключение сделанное на базе это предпосылки тоже верно.
2. Неверно (соотвественно не верен и вывод).
3. Спорно. При этом формально верное заключение сделанное на базе это предпосылки тоже спорным. Заметь! Спорным, а не неверным!
G>А вообще, может не будем цепляться к словам? Это оффтоп.
В данном случая ты усомнившись в предпосылке сделал заключение о неверности всего вывода. Ты уж или развенчивай предпосылки или уж хотя бы называй выводы спроными. А то получается без доказательства или фактов ты наклеиваеш на выводы ярлык ложности.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Gaperton, Вы писали:
G>Я обычно говорю ADT (АДТ) . Что это ты сегодня за мой русский язык взялся?
Я не за русский. Но не очень понятно зачем буквы переставил. Вдруг что-то в этом есть мне не понятное.
G>О как (век живи — век учись)! Пример пожалуйста, особенно "обычного языка", где учитываются значения аргументов при полиморфном вызове в run-time (твой комментарий по правилам русского языка относится ко всему абзацу, а не ко второй половине ).
1. Мы кажется уже договорились, что полиморфизм бывает статический. При этом 90% современных языков это делают.
2. мультиметодыmultimethods
G>Не думаю, что в списке примеров окажется С#,
Здравствуйте, prVovik, Вы писали:
V>Мне действительно по барабану, что и где появлялось первым. Порох, например, китайци первыми придумали, и что теперь всем остальным не использовать огнестрельное оружие?
Какие-то странные выводы Где я написал, что, если что-то появилось раньше в Лиспе, то это нельзя использовать?
V>А зачем надо генерировать функции с похожей функциональностью? Разве нельзя обойтись динамическим полиформизмом? Ведь он и был придуман ради того, чтобы одни и теже функции могли вести себя немного по разному, в зависимости от переданных параметров? Сделать полиморфный вариант STL — это совершенно не проблема.
Во-первых, это невозможно для некоторых функций. Во-вторых, специальная версия для конкретного типа эффективнее полиморфной (контейнеры object'ов в C# vs специализированные контейнеры). В-третьих, ты сам об этом сказал, в С/С++ подобная полиморфность достигается за счет устранения контроля типов, что опасно.
V>Решением этих проблем может стать отказ от универсального полиморфного кода и переход к статически типизированному. Именно для этого и служат шаблоны в С++!!!! Именно для создания статически типизированного кода!!! Поэтому я и говорил, что шаблоны С++ оперируют типами. Или другими словами, шаблоны в С++ — это механизм организации статического полиморфизма. Это узкоспециализированный механизм, который АБСОЛЮТНО не предназначен для генерации кода. Из-зи этого совершенно не имеет смысла сравнивать лисповые макросы с шаблонами.
Если бы он был не предназначен для генерации кода, то все шаблоны бы компилировались в объектники, а не хранились бы в header файлах, как не пойми чего.
G>Вместе с тем, достаточно часто возникают ситуации, когда гомоморфные иерархии, определяемые как иерархии классов с одинаковым открытым интерфейсом, унаследованным от общего базового класса [1], взаимодействуют через функцию, виртуальную к произвольному числу полиморфных параметров. Такая функция называется мультиметодом [2], а возможность ее использования существует в языке программирования CLOS (Common Lisp Object System). Однако широко распространенные ОО языки программирования не поддерживают подобный механизм в связи с отсутствием его эффективной реализации [3].
G>В первой ссылке по твоему поиску. Почитал бы ты сам свой гугл , что ли.
Нда, конструктивный разговор с тобой получается. Выдрал из контекста то что больше понраивалсь и доволен.
G>>>Не думаю, что в списке примеров окажется С#, VD>>Встроенных нет. Но народ над этим думает http://rover.cs.northwestern.edu/~surana/blog/past/000117.html G>Примеров "обычных языков" нет. Впрочем, как и необычных. Все понятно. Вопрос снят.
Ну, то-есть сделал вид что ничего не заметил и объявил себя правым? Заодно поёрничал...
Ай как некрасиво.
VD>>В гугле думаю сразу поймешь о чем я говорю. У нас на сайте тоже статейки имеются. G>Хитрый ленинский прищур не изчез, однако . У нас тоже на кое-кого кое-какой материалец имеется . Мои ответы на свои посты тоже ищи в гугле. Сразу все поймешь. Там все есть.
Жаль что по человечески ты общаться не хочешь.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
VD>Мне кажется нужно вообще сделать общую статью о функциональном стиле программирования с кучей примеров на разных языках. Тогда каждый сможет найти язык на котором примеры ему будут понятны, а остальные поймет по аналогии. VD>Как идея?
Знаешь Влад, имхо было бы интересна статья аля "полиморфизм с разных т.зр.", где можно было бы рассмотреть все разл. подходы, принятые в разных языках (в ФП в т.ч.) с тем как это перекладывается на процессор и пр.
В своих силах по этому поводу сомневаюсь , но в обсуждении был бы рад поучаствовать и внести посильный вклад.
Что скажешь?
ГВ>Впрочем, я вообще не могу представить императивный язык, который мог бы обскакать LISP по своим возможностям. Хоть с шаблонами, хоть с дженериками. По производительности LISP обставляется легко, а по гибкости — даже не представляю.
Forth?
Да и многие императивные динамические языки (Python, Ruby) по гибкости тоже мало лиспу уступают.
[нафиг поскипано]
V>P.S.: Страуструп на счет макросов очень точно подметил, что активное их использовании говорит о недостатках выбранного языка, о недостаточности его выразительных средств (там, правда, упаминался еще один вариант, но я не об этом ). Так что такое распространение макросов в лиспе наталкивает на мысли...
Слушай, ты вообще знаешь о каких макросах речь?
Такое ощущение, что ты плюсовые переносишь на лисп и поэтому так и кричишь
Тут же уже объясняли, что это совершенно разные вещи.
А в лиспе нет расницы между кодом и данными поэтому программа может генерировать программы...
Здравствуйте, Курилка, Вы писали:
К>Слушай, ты вообще знаешь о каких макросах речь? К>Такое ощущение, что ты плюсовые переносишь на лисп и поэтому так и кричишь К>Тут же уже объясняли, что это совершенно разные вещи. К>А в лиспе нет расницы между кодом и данными поэтому программа может генерировать программы...
А можешь сказать, с чем именно ты не согласен? Только без констатации своих ощущений!
Здравствуйте, Gaperton, Вы писали:
G>Здравствуйте, WolfHound, Вы писали:
WH>>Здравствуйте, Gaperton, Вы писали:
WH>>Учись гуглить вставай на лыжи... инетом будешь не обижен. WH>>Предложение в следующий стандарт С++ подойдет? G>Подойдет для чего? Что ты мне доказать хочешь? Я в курсе что такое мультиметоды, вообще-то. И то, что добавить их можно при желании куда угодно — дурацкое-то дело нехитрое, а семантика простая. Вот когда они появятся в стандарте и популярных компиляторах, тогда и будешь спрашивать "подойдет?". А пока — хоть обгуглись.
G>А вообще, между нами девочками, вопрос адресовался Владу, лично, который вместо того, чтобы написать нормальный содержательный ответ демонстрирует какие-то странные ужимки. Наверно готовится к очередному замеру. А потом еще удивляется, что с ним нормально общаться не получается.
А причем тут тогда это:
в разрешении вызова принимаются во внимание все аргументы (а не только тип неявного аргумента виртуальной функции — объект). Это самое главное отличие полиморфизма ФЯ от обычных языков.
Здравствуйте, prVovik, Вы писали:
V>Здравствуйте, Курилка, Вы писали:
К>>Слушай, ты вообще знаешь о каких макросах речь? К>>Такое ощущение, что ты плюсовые переносишь на лисп и поэтому так и кричишь К>>Тут же уже объясняли, что это совершенно разные вещи. К>>А в лиспе нет расницы между кодом и данными поэтому программа может генерировать программы... V>А можешь сказать, с чем именно ты не согласен? Только без констатации своих ощущений!
1. Страуструп тут совсем не в тему (если ты не плюсовые макросы рассматривешь, ес-но)
2. Статическая типизация шаблонов довольно похожа на полиморфизм, который наличествует в ФП (и на макросы в лиспе), только разница заключается в том, что типы в плюсах определяются обязательно и отдельно от всего остального, а в ФП практически всегда они выводятся из задаваемых пользователем констант, т.к. нет там свободных переменных. Но типы там есть, причём компилятор/интерпретатор тебе по башке треснет, если ты что-то нето начнёшь вытворять (аля выполнение ф-ций неприменимых к данным типам и т.п.).
Здравствуйте, Курилка, Вы писали:
К>1. Страуструп тут совсем не в тему (если ты не плюсовые макросы рассматривешь, ес-но)
Я рассматриваю макросы, как средство генерации кода.
К>2. Статическая типизация шаблонов довольно похожа на полиморфизм, который наличествует в ФП (и на макросы в лиспе), только разница заключается в том, что типы в плюсах определяются обязательно и отдельно от всего остального, а в ФП практически всегда они выводятся из задаваемых пользователем констант, т.к. нет там свободных переменных.
Угу. Только этого вывода компилятор сразу почему-то забывает о типе.
К>Но типы там есть, причём компилятор/интерпретатор тебе по башке треснет, если ты что-то нето начнёшь вытворять (аля выполнение ф-ций неприменимых к данным типам и т.п.).
Треснуть то он треснет, но когда? Во время демонстрации программы заказчику? Да уж спасибо, не надо. Остается только молиться на тестеров...
А вот в случае со статической типизацией, о том, что программа некорректна, станет известно еще на этапе компиляции! Компилятор автоматически проконтролирует корректность использования переменных, еще до запуска программы.
Здравствуйте, prVovik, Вы писали:
V>Здравствуйте, Курилка, Вы писали:
К>>1. Страуструп тут совсем не в тему (если ты не плюсовые макросы рассматривешь, ес-но) V>Я рассматриваю макросы, как средство генерации кода.
И? Если так подходить, то шаблоны тоже средство генерации кода, не иначе, не вижу принципиальной разницы с этой т.зр.
К>>2. Статическая типизация шаблонов довольно похожа на полиморфизм, который наличествует в ФП (и на макросы в лиспе), только разница заключается в том, что типы в плюсах определяются обязательно и отдельно от всего остального, а в ФП практически всегда они выводятся из задаваемых пользователем констант, т.к. нет там свободных переменных. V>Угу. Только этого вывода компилятор сразу почему-то забывает о типе.
И? Что ты этим хотел сказать? Поясни, пожалуйста...
К>>Но типы там есть, причём компилятор/интерпретатор тебе по башке треснет, если ты что-то нето начнёшь вытворять (аля выполнение ф-ций неприменимых к данным типам и т.п.). V>Треснуть то он треснет, но когда? Во время демонстрации программы заказчику? Да уж спасибо, не надо. Остается только молиться на тестеров...
Имхо всё выглядет совсем не так, как тебе кажется V>А вот в случае со статической типизацией, о том, что программа некорректна, станет известно еще на этапе компиляции! Компилятор автоматически проконтролирует корректность использования переменных, еще до запуска программы.
И?
Для ФЯ есть компиляторы и там есть также строгая типизация (не факт что статическая, т.к. мы слишком общо сейчас обсуждаем, давай возьмём лисп и приведи вариант, где будет преимущество стат. типизации шаблонов C++)
Здравствуйте, prVovik, Вы писали:
V>А причем тут тогда это: V>
в разрешении вызова принимаются во внимание все аргументы (а не только тип неявного аргумента виртуальной функции — объект). Это самое главное отличие полиморфизма ФЯ от обычных языков.
V>?
Это тебе лучше знать. С моей точки зрения, эта выдранная из контекста фраза вообще лишена смысла. Уж не знаю, злой-ли жто умысел с твоей стороны или особенности твоего восприятия. Вот полная цитата — обратите внимание на разницу:
А во вторых, при разрешении полиморфного вызова учитываются не только типы, но и значения аргументов (в "обычных" языках — только типы). Причем, в разрешении вызова принимаются во внимание все аргументы (а не только тип неявного аргумента виртуальной функции — объект). Это самое главное отличие полиморфизма ФЯ от обычных языков.
Впрочем, полная цитата по большому счету тоже не причем. Я совершенно не понимаю, к чему ты ее вообще привел и как связан твой ответ с моим постом.
Здравствуйте, Курилка, Вы писали:
К>И? Что ты этим хотел сказать? Поясни, пожалуйста...
То что компилятор лиспа не знает типов переменных.
К>И? К>Для ФЯ есть компиляторы и там есть также строгая типизация
Если ты не заметил, мы говорим конкретно о лиспе
К>(не факт что статическая, т.к. мы слишком общо сейчас обсуждаем, давай возьмём лисп и приведи вариант, где будет преимущество стат. типизации шаблонов C++)
Я уже плохо помню синтсакис лиспа, но поробуй в нем завести две строковые переменные и перемножить их. Получишь ошибку времени выполнения.
В С++ таких проблем нет.
template <class T> T mul(T a, T b){ return a*b; }
При вызове mul("Вася", "Маша") получаем сообщение об ошибке еще на этапе компиляции.
G>А во вторых, при разрешении полиморфного вызова учитываются не только типы, но и значения аргументов (в "обычных" языках — только типы). Причем, в разрешении вызова принимаются во внимание все аргументы (а не только тип неявного аргумента виртуальной функции — объект). Это самое главное отличие полиморфизма ФЯ от обычных языков.
G>Впрочем, полная цитата по большому счету тоже не причем. Я совершенно не понимаю, к чему ты ее вообще привел и как связан твой ответ с моим постом.
Мне не понятно, при чем тут ФЯ? Наличие мультиметодов не является отличительной особенностью функционального подхода. Ты и сам впоследствии это признал.
Здравствуйте, prVovik, Вы писали:
V>Здравствуйте, prVovik, Вы писали:
V>>То что компилятор лиспа не знает типов переменных. V>В смысле, что он может различать только типы констант.
Нет кроме них ничего по сути, так что это не нужно в принципе,
нет оператора присваивания...
Здравствуйте, prVovik, Вы писали:
V>Здравствуйте, Курилка, Вы писали:
К>>(не факт что статическая, т.к. мы слишком общо сейчас обсуждаем, давай возьмём лисп и приведи вариант, где будет преимущество стат. типизации шаблонов C++) V>Я уже плохо помню синтсакис лиспа, но поробуй в нем завести две строковые переменные и перемножить их. Получишь ошибку времени выполнения. V>В С++ таких проблем нет.
V>
V>template <class T> T mul(T a, T b){ return a*b; }
V>
V>При вызове mul("Вася", "Маша") получаем сообщение об ошибке еще на этапе компиляции.
Любой компилятор лиспа тебе тоже выдаст такое же, зря ты лисп недооцениваешь,
из умножения автоматически выводятся типы, которыми могут быть параметры, соотв-но тебе по рукам надают за это,
а переменных свободных нету в ФЯ, ещё раз повторяю!
Здравствуйте, FR, Вы писали:
FR>Forth? FR>Да и многие императивные динамические языки (Python, Ruby) по гибкости тоже мало лиспу уступают.
Тут вопрос что считать гибкостью. По мне так говорить нужно не об абстрактной гибкости, о выразительной полноте для решения некоторой задачи. И тут решения на лиспе оказываются настолько запутанными и непонятными, что говорить о гибкости просто смешно.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, prVovik, Вы писали:
V>Здравствуйте, FR, Вы писали:
FR>>Ocaml треснет по башке именно в момент компиляции. V>А причем тут Ocaml? Разговор вообще-то идет о лиспе.
Здравствуйте, VladD2, Вы писали:
VD>Другими словами свое утвреждение: VD>
А во вторых, при разрешении полиморфного вызова учитываются не только типы, но и значения аргументов (в "обычных" языках — только типы). Причем, в разрешении вызова принимаются во внимание все аргументы (а не только тип неявного аргумента виртуальной функции — объект). Это самое главное отличие полиморфизма ФЯ от обычных языков.
VD>Явно говорящее о том, что мултиметоды есть явный признак ФЯ ты сам же и опроверг:
В этом высказывании главная часть выделена. Второстепенная (хоть и тоже важная) отделена от главной словом-связкой "причем". Обе части являются неотъемлемой частью тезиса (одного). Начало отмечено фразой "а во вторых". Плюс ко всему, речь идет не о признаке ФЯ, а о полиморфизме в современных ФЯ. Он обеспечивается выполнением pattern matching по всем аргументам, что не предполагает наличие классов. Называть такое "мультиметодом" можно с большой натяжкой, и тем более нельзя сравнивать с мультиметодами С++, python, whatever, так как общего здесь очень мало. Так что я не понимаю, что именно я опроверг.
У меня просьба, личного характера. Не мог бы ты читать весь текст моих постов, а не отрывки, перед тем, как отвечаешь на них? Если тебя сильно не затруднит, конечно. В противном случае я не буду на них отвечать, все равно получается беседа слепого с глухим.
VD>
Я в курсе что такое мультиметоды, вообще-то. И то, что добавить их можно при желании куда угодно — дурацкое-то дело нехитрое, а семантика простая.
VD>Ну, и учитывая, что реализации мультиметодов в ИЯ уже есть (ссылки выше), меня полностью удовлетворяет данный ответ. Ну и хорошо. Особенно в свете того, что я потерял нить беседы.
VD>Не удовлетворяет только твоя граничащая с хамством манера выражать своих мысли.
Ты удивишься, но меня тоже не устраивает твоя манера выражать свои мысли.
В "обычных языках" это называется мутиметодами. Они кое где реализованы. А кое где реализуются имеющимися средствами.
Она навевает подозрение в их отсутствии (уж извини — говорю правду, не с целью тебя обидеть). В самом деле, список "кое где" реализаций ты привел в 3-м (третьем) ответе (видимо, наконец заглянув в гугл), его из тебя клещами пришлось тянуть. По поводу второго "кое где" вообще не смог дать внятного ответа. Это либо некомпетентность, либо пренебрежение. Выбирай что лучше. Мне не нравятся оба варианта. Не нравится мне твоя манера не читать чужие посты перед ответом (не только мои — вообще), и переходы в автономный режим общения. Не нравится твоя самоуверенность и пренебрежительное отношение к собеседникам.
А в остальном — отлично. Попробую угадать, что ты сейчас ответишь. Если вообще ответишь, конечно. Сравним.
Здравствуйте, prVovik, Вы писали:
V>Здравствуйте, Gaperton, Вы писали:
G>>
G>>А во вторых, при разрешении полиморфного вызова учитываются не только типы, но и значения аргументов (в "обычных" языках — только типы). Причем, в разрешении вызова принимаются во внимание все аргументы (а не только тип неявного аргумента виртуальной функции — объект). Это самое главное отличие полиморфизма ФЯ от обычных языков.
G>>Впрочем, полная цитата по большому счету тоже не причем. Я совершенно не понимаю, к чему ты ее вообще привел и как связан твой ответ с моим постом.
V>Мне не понятно, при чем тут ФЯ? Наличие мультиметодов не является отличительной особенностью функционального подхода. Ты и сам впоследствии это признал.
Ок, теперь понятно. Почитай мой ответ Владу. Там детальный разбор этого абзаца. Ты меня неправильно понял. http://www.rsdn.ru/Forum/Message.aspx?mid=869836&only=1
Здравствуйте, FR, Вы писали:
ГВ>>Впрочем, я вообще не могу представить императивный язык, который мог бы обскакать LISP по своим возможностям. Хоть с шаблонами, хоть с дженериками. По производительности LISP обставляется легко, а по гибкости — даже не представляю.
FR>Forth? FR>Да и многие императивные динамические языки (Python, Ruby) по гибкости тоже мало лиспу уступают.
Насчёт "мало уступают" — согласен вобщем-то. Но я имел ввиду — обскакать. Ну Forth, в принципе — ещё туда-сюда. ИМХО.
... << RSDN@Home 1.1.3 stable >>
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, Курилка, Вы писали:
К>Здравствуйте, prVovik, Вы писали:
V>>Здравствуйте, Курилка, Вы писали:
К>>>(не факт что статическая, т.к. мы слишком общо сейчас обсуждаем, давай возьмём лисп и приведи вариант, где будет преимущество стат. типизации шаблонов C++) V>>Я уже плохо помню синтсакис лиспа, но поробуй в нем завести две строковые переменные и перемножить их. Получишь ошибку времени выполнения. V>>В С++ таких проблем нет.
V>>
V>>template <class T> T mul(T a, T b){ return a*b; }
V>>
V>>При вызове mul("Вася", "Маша") получаем сообщение об ошибке еще на этапе компиляции.
К>Любой компилятор лиспа тебе тоже выдаст такое же, зря ты лисп недооцениваешь, К>из умножения автоматически выводятся типы, которыми могут быть параметры, соотв-но тебе по рукам надают за это, К>а переменных свободных нету в ФЯ, ещё раз повторяю!
Неужели? А примерчик можно? У меня вот не получилось:
(defun my_mul (a b) (declare (number a b)) (* a b))
(setq num (read))
(cond
( (= num 12345 ) (write (my_mul "Vasja" "Masha")) )
( T (write (my_mul 10 2 )) )
)
CLISP-2.27 Программа работает нормально, пока не введешь магическое число 12345, после которого она падает с ошибкой. Не помогает даже мокание компилятора мордой в молоко: (declare (number a b)).
Здравствуйте, prVovik, Вы писали:
V>CLISP-2.27 Программа работает нормально, пока не введешь магическое число 12345, после которого она падает с ошибкой. Не помогает даже мокание компилятора мордой в молоко: (declare (number a b)).
А вот при использовании статической типизации ошибка вылезла бы еще во время компиляции.
Здравствуйте, Gaperton, Вы писали:
G>В этом высказывании главная часть выделена. Второстепенная (хоть и тоже важная) отделена от главной словом-связкой "причем". Обе части являются неотъемлемой частью тезиса (одного). Начало отмечено фразой "а во вторых". Плюс ко всему, речь идет не о признаке ФЯ, а о полиморфизме в современных ФЯ. Он обеспечивается выполнением pattern matching по всем аргументам, что не предполагает наличие классов. Называть такое "мультиметодом" можно с большой натяжкой, и тем более нельзя сравнивать с мультиметодами С++, python, whatever, так как общего здесь очень мало. Так что я не понимаю, что именно я опроверг.
А, ну, то есть я не понял. Так что же ты вместо того чтобы сказать, что я тебя не понял, и ты говоришь про патерн-матчинг, начал доказывать, что мултиметода — это норенная особенность ФЯ?
G>У меня просьба, личного характера. Не мог бы ты читать весь текст моих постов, а не отрывки, перед тем, как отвечаешь на них? Если тебя сильно не затруднит, конечно. В противном случае я не буду на них отвечать, все равно получается беседа слепого с глухим.
А у меня к тебе пробсьба общественно характера. Смени стиль общения. Прекрати постоянно пытаться задевать других людей.
ЗЫ
В общем, редлагаю не разводить здесь флэйм.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
ГВ>>Ты неправильно делаешь противопоставление. VD>Я предлагаю не противопоставлять не сопоставимые вещи.
Ладно, уболтал.
ГВ>>Сильная типизация и гибкость — вообще антагонисты и конкретный баланс зависит от потребностей разработки. Сильная типизация нам нужна для жёсткости и надёжность, а LISP-овская унификация — для гибкости и компактности конструкций. VD>По-моему, предположение о том, что компактность это безусловное благо в корене не верно.
Я не говорил о том, что компактность — абсолютное благо.
VD>Говорить нужно в первую очередь о выражительности и понятности. И тут Лисп в полной заднице. Стоит чуть-чуть увеличить сложность задачи, как код на лиспе превращается в лес скобок понять смысл которого можно только путем последовательной мысленной интерпретации.
Ну, во-первых, он всегда представляет собой "лес скобок". Просто в силу синтаксиса.
VD> Тут он сравни Перлу. Программы сразу понятны только тому кто их пишет. Так сказать тайт-онли-языки. Мне кажется такой подход очень опасным.
Во-вторых, давай не будем сравнивать восприятие LISP-программы теми, кто привык к императивному стилю и самими LISP-программистами. Угу?
VD>Кстати, я давно наблюдаю за стилем кодирования приверженцев ФС (функционального стиля). И он мене очень не нарвится. Постонянное стремление к компактности кода переходит все разумные границы. Одно-двух буквенные переменные и функции, стремление написать как можно больше в одну строку, зачастую наплевателство на струкуризацию кода. В общем компактность кода ставится выше простоты его восприятия. Причем все это подкрепляется словами об абстракции. Это не абстракция — это раздалбайство.
Как много шума на пустом месте. Давай ещё джихад на тему "4 пробела vs. табуляция начнём"! Это всё второстепенно. И причём тут "стиль кодирования приверженцев ФЯ"? Знаешь, из того, что кто-то где-то пишет так, что это кому-то где-то непонятно, ничего не следует относительно гибкости использованного средства. Не надо связывать разнородные сущности.
VD>Гибкость тоже имеет свои пределы. Универсальные системы всегда проигрывают специализированным как в простоте понимания, так и в производительности и надежности. Для решения конкретных задач нужно искать не самое "гибкое" средство, а самое подходящее. И я не думаю, что, например, тот же Янус будет проще создать на Лиспе, Хаскеле или Окамле, как в прочем и на С++.
Всё имеет свои пределы. И гибкость, и универсальность.
Вобщем, честно говоря, я так и не понял, что ты тут хотел сказать. ИМХО, ты со мной согласился:
ГВ>>Сильная типизация и гибкость — вообще антагонисты и конкретный баланс зависит от потребностей разработки.
VD>Гибкость тоже имеет свои пределы.
...только как-то уж очень многословно. Хотя, если выразиться точнее, то ты приписал мне утверждение о беспредельной ценности гибкости и начал его опровергать. Поскольку отрицание такого утверждения содержалось в исходной реплике, то я могу сделать вывод о том, что ты со мной согласен.
ГВ>>На самом деле, получается своего рода "стремление" к LISP. Т.е., для того, чтобы наиграть кучу интересных вещей приходится на C++ писать некий "метаязык", VD>А почму метаязык — это сразу лисп?
Ответ содержится в поскипанной тобой части реплики:
ГВ>На самом деле, получается своего рода "стремление" к LISP. Т.е., для того, чтобы наиграть кучу интересных вещей приходится на C++ писать некий "метаязык", который выражается в виде своих последовательностей скобочек разного вида и т.п. Тогда как чистый LISP — это и есть только скобочки и символы (значения символов).
Метафора — и почти что не более того. Да, получающиеся метаязыки нередко состоят из набора функций, и конструкторов объектов. Мы их вкладываем один в другой и получаем последовательность скобочек. Ну и объявления шаблонов — как раз наборы треугольных скобочек. Естественно, это не LISP.
VD> Получается именно метаязык. Но средства у него свои. И проблемы С++ — это не непохожесть на Лисп, а наличие горы граблей и то что эти метасредства эмулируются на побочных эффектах средств для метапрограммирования не предназначенных.
Возможно, что и так.
VD>Мы вот как раз пытаемся создать систему метапрограммирования для C# (R#
). Если все получится как хочется, то выйдет очень гибкая система при этом собственными механизмами модификации кода.
VD>Что касается макросов Лиспа, тот тут на лицо терминалогическая путанница. Они по сути не имеют права называться макросами, так как работают на уровне синтаксиса языка, а не на уровене модификации тектса.
Трудно сказать, имеют ли они право так называться или нет. ИМХО — имеют, как устоявшаяся терминология. Сам LISP создан в 1962 г., когда появилась конструкция defmacro — не знаю.
ГВ>>Не одного тебя, но и кода там получается, AFAIK, поменее, чем на C++/Java/C#. Просто в силу разных парадигм. LISP не делает различия между данными и программой (оценка зависит только от того, вызван ли quote, или eval для списка), а императивные языки такое различие делают. Отсюда и гибкость, и компактность кода. VD>Еще раз повторюс, что компактность достигнутая потерей смысла — это зло.
Если бы компактность достигалась потерей смысла, то и конечная программа никогда не была бы написана. Я не сомневаюсь, что LISP-текст довольно трудно читать программистам, привыкшим к императивному стилю программирования (я из их числа). Ну и что из того? Это только вопрос привычки. Равно как и чтение C++-шаблонов.
VD>То же и с гибкостью. На Лиспе нельзя решить элементаные задачи, при это постоянно идут рассуждения о его гибкости. Кому нужна такая гибкость?
[skip] VD>И итоге выходит, что реальный потенциал императивного языка снабженного современным набором средств разработки нманого выше чем очень гибких и компактных. Так в чем правда, брат? (с) отморозок из отмороженного фильма.
Ещё раз. LISP имеет в своей основе очень неплохую парадигму: "программа = данные". Наличие библиотек — это только наличие библиотек и ничего более. Вопрос времени и популярности конкретного языка. Я вижу в идеях Java и .Net очень многое похожее на LISP.
ГВ>> Не, скорее наоборот — это C++ и в страшном сне не приснится то, что можно творить на LISP. Например, можно и вложенные while как параметр передать.
VD>Но нельзя создать статически типизированный код. В общем, опять пошло сравнение предназначенного для разного вещей. Надоело. Не могут делать макросы Лиспа того что могут шаблон. И не потому что у них гибкости не хватает, а потому что не предназначены для этого. Так что прикрате проводить аналогии и что-то по этим аналогиям доказывть.
Исходно речь шла о сравнении шаблонов C++ с макросами LISP только в аспекте допустимых трансформаций программы. О достижении этой программой каких-либо свойств никто вобщем-то, не говорил. И никто не утверждал, что макросы LISP позволяют порождать статически типизированый код, свойства которого полностью аналогичны коду на C++. (предыдущее предложение читать и цитировать только полностью!) И аналогии проводились только для того, чтобы собеседнику было понятнее — на каких свойствах ммакросов LISP заостряется внимание.
ГВ>>Я согласен с Quintanar. Он правильно употребил термин "примитивные". Никакого уничижительного оттенка там заметно не было. Тем более, что Quintanar специально оговорился: ГВ>>
ГВ>>Примитивный в том смысле, что Лисп позволяет делать более мощные модификации программы на основе параметров макроса.
VD>Нет слов. Ладно. Начинаю разводить ту же демагогию, держитесь.
VD>
Итак, макросы лиспа приметивны потому что не позволяют проивзодить примитивные операции записи в файл, вывода на принтер и т.п. Так же они примитивны по сравнению с простейшим оператором if, так как в отличии от него не позволяют выполнять проверок в рантайме. Ну, и уж несомненно они явлются полнейшим примитивизмом по сравнению с такими мощнешими средствами С++ как Шаблоны! Ведь в отличии от шаблонов они не позволют создавать статически-типизированный, типобезопасный код. В то же время шаблоны С++ не просто на голову рабивают это примитивное образование, но и вообще низвергают весь лисп в небытие, так как кроме всех выше перечисленных достоинств еще позволяют создавать выско-производительный код, а так же, использую побочные эффекты, даже эмулировать действия тех самых примитивных макросов Листпа.
Хм. Где-то я уже слышал что-то подобное пару лет назад. Это у меня дежа-вю, что ли?
VD>Ну, что нормально если я буду общаться в такой манере? Нет? Ну, тогда не нужно использовать подбные подходы.
Ещё раз. Медленно. Сопоставлялись только возможности комбинирования конструкций языка программирования, доступные для LISP-макросов и C++-шаблонов. Только и всего. Ни о статической типизации, ни о полной типобезопасности, ни о вводе-выводе речи не было и быть не могло.
Соответственно, твоя иллюстрация "демагогии" летит даже не мимо кассы, а... в противоположную сторону, что ли... да, как-то так.
... << RSDN@Home 1.1.3 stable >>
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, Геннадий Васильев, Вы писали:
ГВ>Соответственно, твоя иллюстрация "демагогии" летит даже не мимо кассы, а... в противоположную сторону, что ли... да, как-то так.
Нет уж. Твое сравнение точно такое же. Просто тут для тебя все очевидно. Сравни с макросами лисам сопоставимые вещи, например, OpenC++. Вот тогда и поговорим о гибкости и возможностях.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
ГВ>>Соответственно, твоя иллюстрация "демагогии" летит даже не мимо кассы, а... в противоположную сторону, что ли... да, как-то так. VD>Нет уж. Твое сравнение точно такое же. Просто тут для тебя все очевидно. Сравни с макросами лисам сопоставимые вещи, например, OpenC++.
А какая связь между макросами LISP (я надеюсь, ты это имел ввиду под "лисам") и OpenC++? Я просто не знаю OpenC++ — может, расскажешь?
... << RSDN@Home 1.1.3 stable >>
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Да, спасибо, посмотрю, но тем не менее к теме дискуссии это пока не относится. Мы всё-таки, сопоставляли C++ templates и LISP defmacro. Я так полагаю, что в итоге ты согласился с доводами оппонентов по существу.
... << RSDN@Home 1.1.3 stable >>
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, VladD2, Вы писали:
ГВ>>Да, спасибо, посмотрю, но тем не менее к теме дискуссии это пока не относится. Мы всё-таки, сопоставляли C++ templates и LISP defmacro. VD>Позволю уточнить — вы.
Угу, пусть так.
ГВ>> Я так полагаю, что в итоге ты согласился с доводами оппонентов по существу. VD>По существу я уже сказал. Если сравнивать средства мета-программирования, то лушче смотреть на продвинутые вещи вроде ОпенС++. А шаблоны можно сравинить со средствами обощенного программирования в статически типизированных языках. А так как Лисп к таковым не относится, то и не стоит сравнивать.
В ринципе я стобой согласен. Вобщем-то, по большому счёту, сравнение не совсем правомерное, но отельные аспекты — вполне себе даже сравнимы. По крайней мере, в таком обсуждении. Ну да ладно.
... << RSDN@Home 1.1.3 stable >>
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, Геннадий Васильев, Вы писали:
ГВ>В ринципе я стобой согласен. Вобщем-то, по большому счёту, сравнение не совсем правомерное, но отельные аспекты — вполне себе даже сравнимы. По крайней мере, в таком обсуждении. Ну да ладно.
Самое забавное что многие сторонники С++ действительно считают шаблоны некой заменой компйлтайм-метакода а-ля макросы Лиспа, и всячески пытаются аворотить на них что-то. И я постоянно спорю с ними доказывая им, что применение побочных эффектов не есть гуд. Они в ответ мне все время твердят, что это нормальное использование... И возможности просто потрясающие...
А сталкиваясь с теми кто защищает ФП я вижу раздражение не качественностью шаблонов вызванной тем, что они не реализуют всех возможностей мета-программирования. И при этом нет даже желания взглянуть на то, что плохим называется применение не по назначению.
Я понимаю откуда взгляд на шаблоны как на хреновые мета-мекросы. И понимаю откуда все это восхищение побочными эффектами. Просто надо понять и признать несколько очень простых фактов.
1. В С++ нет шаттных средств мета-программировния.
2. С++ не совершенен и ему очень нужны подобные средства.
3. Шаблоны позволяют частично решить эту проблему.
4. Есть средства и подходы позволяющие решать эти задачи более чистым образом. Идеальным было бы расширение С++ с целью введения штатных мета-средств. Но можно пережить и фишками вроде кодогенераторов и ОпенС++.
Отсюда вся кривость решений мета-программирования основанного на шаблонах. И ощущение убогости. Реально же шаблоны С++ прекрасно решают задачи которые ставились перед ними в момент их создания. Но это другие задачи. Это задачи обобщенного программирования, например, создания коллекций.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали: N_>>Я знаю только ad-hoc и параметрический полиморфизмы. VD>Ну, а дальше можно выделить два подкласса — это статический полиморфизм и динамический. Динамический требует выбора в рантайме, статический ведет к генерации множества вопложений полиморфного кода и типов.
На самом деле вы оба правы. Статический/динамический относится к компиляции, следовательно, это варианты реализации полиморфизма. Потому что логика программы от этого не меняется. А ad-hoc и параметрический различаются по логике. Т.е. есть два варианта классификации полиморфизма (по логике и по реализации). Их действительно часто путают.
Здравствуйте, Gaperton, Вы писали:
G>1) Существует два способа. Первый — параметрические типы (аналог шаблонов), и второй — АДТ (абстрактные типы данных, ближе всего к интерфейсам). Вроде как все знакомо. G>2) А вот здесь начинается самое интересное. Во-первых, для каждого типа (класса), соответствующего АДТ (реализующего интерфейс) надо явно указать набор функций, которые реализуют АДТ. Функции могут быть совершенно произвольными, в частности две разных реализации АДТ могут вообще говоря иметь пересекающийся набор функций. Что прикольно.
Категорически не согласен. Значит, метод write может выполнять чтение? То есть сделать так можно, но не нужно. Конечно, все реализации метода имеют некоторый общий знаменатель. Я думаю, что в ООП этот знаменатель есть интуитивное представление о том, что должен делать метод. В ФП встречается такая новая вещь, как законы. Некоторое математическое равенство, включающее метод(ы), должно выполняться на всех реализациях.
Здравствуйте, beroal, Вы писали:
B>На самом деле вы оба правы. Статический/динамический относится к компиляции, следовательно, это варианты реализации полиморфизма. Потому что логика программы от этого не меняется. А ad-hoc и параметрический различаются по логике. Т.е. есть два варианта классификации полиморфизма (по логике и по реализации). Их действительно часто путают.
Собственно я говорил именно о "статический/динамический" и "ad-hoc и параметрический" не приплетал.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, beroal, Вы писали:
B>Здравствуйте, Gaperton, Вы писали:
G>>1) Существует два способа. Первый — параметрические типы (аналог шаблонов), и второй — АДТ (абстрактные типы данных, ближе всего к интерфейсам). Вроде как все знакомо. G>>2) А вот здесь начинается самое интересное. Во-первых, для каждого типа (класса), соответствующего АДТ (реализующего интерфейс) надо явно указать набор функций, которые реализуют АДТ. Функции могут быть совершенно произвольными, в частности две разных реализации АДТ могут вообще говоря иметь пересекающийся набор функций. Что прикольно. B>Категорически не согласен. Значит, метод write может выполнять чтение?
Нет, не значит. "могут вообще говоря" означает, что в общем случае, они не обязаны быть разными. И ничего кроме. B>То есть сделать так можно, но не нужно.
А теперь насчет того, когда это нужно, а когда нет. Во первых, это позволяет просимулировать наследование реализации. Во вторых, есть ситуации, когда это просто спасает. Пример — есть много классов, с примерно одинаковыми данными, но немного разным прикладным смыслом. Классы состоят друг с другом в сложных отношениях. В этом случае так делать нужно.
Здравствуйте, Gaperton, Вы писали:
G>На всякий случай, когда тебе кажется, что кто-то написал глупость, вместо этого считай, что ты человека не понял. Неплохой индикатор непонимания, сильно не ошибешься. Не придется разводить флейм, упираться, и пытаться потом сохранить лицо. Потому как убедить тебя, что ты не понял, как показывает опыт, практически невозможно. Это первый на моей памяти случай.
Тут оно как, всегда кто-то кого-то может непонять. И всегда это можно объяснить. А вот если в отвоет, начинать доказвать что-то другое, то конечно получается фигня.
Вот в данном случае ты как раз начал вещать о мултиметодах и довещался до полной ерунды. А из твоего исходного высказывания совсем не очевидно, что ты имел в виду не полиморфизм, а патрн-матчинг. Особненно это не очевидно в контексте данной темы. Ведь патерн-матчинг к полиморфизкму отношения не имеет. Это сдедство управления ветвлением вроде if/switch.
VD>>А у меня к тебе пробсьба общественно характера. Смени стиль общения. Прекрати постоянно пытаться задевать других людей. G>Я постоянно это делать и не пытаюсь. Так скажем, я вообще не пытаюсь задевать других людей.
Судя по результатам у тебя это плохо получается.
G> Я реагирую на их посты. В чем может убедится каждый, посмотрев историю моих постов. И в чем ты можешь убедиться лично, выполнив мою просьбу и последовав предыдущему совету. Если тебя это сильно не затруднит, конечно.
Каждый и убеждается. И поверь убеждается именно в том, о чем я тебе говорю. А свои просбы тебе бы в первую очередь самому бы выполнять. Глядишь проблем было бы меньше.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Sinclair, Вы писали:
S>Ну, вообще-то определение полиморфизма в википедии все-таки работает с типами, а не со значениями. Таким образом, паттерн-матчинг является более мощной концепцией, чем ad-hoc полиморфизм, описанный в wiki. Во-первых, он сохраняет некоторые черты параметрического полиморфизма, в том смысле, что множество типов, с которыми может работать конкретная версия функции, не является конечным. Во-вторых, все-таки паттерн может использовать больше информации об аргументе, чем просто тип.
И это тоже зависит от точки зрения. G>> Тип данных в частности однозначно определяется множеством значений этого типа, так что аргумент-паттерн можно также понимать как способ конструирования подтипов без их явного определения (!). С такой точки зрения мы не выходим за рамки классического определения полиморфизма.
S>С абстрактно-философской точки зрения, тем не менее, я считаю трактовку паттерн-матчинга как средства достижения полиморфизма вполне корректной.
Не такая уж она (точка зрения) абстрактно-философская. Паттерн-матчинг часто на практике применяется там, где в С++ пользуются виртуальными функциями. Перейдем от абстрактных рассуждений к конкретным примерам.
Рассмотрим задачу обхода бинарного дерева. Пусть у нас есть бинарное дерево с числами в узлах, и нам необходимо выполнить его обход чтобы посчитать сумму. На С++ получится примерно два-три класса c виртуальным методом Sum, если мы конечно захотим воспользоваться "родным" для С++ полиморфизмом для определения различия между листом и обычным узлом. Т. е. чтобы воспользоваться встроенным в язык run-time полиморфизмом, нам надо явно определить новый класс (тип) на каждое определение функции. Плюс, определение полиморфной функции получится обязательно привязано к определению типа — это не нравится многим функциональщикам, например Joe Armstrong-у. Я, впрочем, к этому отношусь спокойно, возможно потому, что С++ мой основной язык.
// без деструкторов и конструкторов, бо ни к чему это в примере...class Leaf
{
protected:
int m_number;
public:
virtual int Sum() const { return m_number; }
};
class NonLeaf : public Leaf
{
TreeNode *m_pLeft, *m_pRight;
public:
int Sum() const { return m_number + m_pLeft -> Process() + m_pRight -> Process(); }
};
А на ФЯ мы для решения абсолютно той же задачи (разная функция обработки для узлов разных типов) применим pattern-matching:
sum( { Left, Right, Num } ) -> Num + process( Left ) + process( Right );
sum( Num ) -> Num.
Как видишь, код соответствует практически один в один. Подобное применение паттерн-матчинга — повседневная практика для программиста на ФЯ, а не абстрактная философия.
Кстати, опять, решение "в лоб" на ФЯ является самым "правильным". Это возвращаясь к разговору о "невидимости паттернов".
Здравствуйте, Gaperton, Вы писали:
G>Кстати, опять, решение "в лоб" на ФЯ является самым "правильным". Это возвращаясь к разговору о "невидимости паттернов".
А вот тут можно чуть подробнее?
Уже не 1-й раз встречаю об этом, но всё "всколзь". Хотелось бы чего-нибудь почитать на сию тему. Или м.б. уже на рсдн осбуждали, но меня рядом не оказалось?
Заявление: G>А паттерн-матчинг я за полиморфизм не принимаю, это разные вещи.
Слабо сочетается с: G> Применение паттерн-матчинга при задании аргументов функции — вот это является одним из самых мощных способов достижения полиморфизма в ФЯ.
Паттерн-матчинг вообще не имеет отношения к полиморфизму. Прочитай еще раз определение из Википедии. Там четко говорится о типах.
G>Все эти определения могут быть даны одновременно, и в рантайме будет выбрано наиболее специфичное. G>poly_function( { A, B } ) -> ...; G>вызовется, если аргумент — структура из двух элементов.
G>poly_function( [ A, B ] ) -> ...; G>вызовется, если аргумент — список из двух элементов. Разные типы, все в порядке, так?
Так. Но это перегрузка функций, а не паттерн-матчинг. Перегрузка — это несомненно статический полиморфизм.
G>poly_function( { A, { B, C } } ) -> ...; G>вызовется, если аргумент — структура из двух элементов, а значение второго элемента — тоже структура из двух элементов. Что можно также понимать, как единое определение типа (такая хитрая структура) — пока все честно, не так ли?
Не так, Ли. Это всего лишь иная запись для if-а из ИЯ.
G>Как видишь, мы уточнили ограничение на тип по сравнению с первой строкой. Теперь оно более специфично.
Не вижу. Вижу подмену понятий.
G>Паттерн матчинг, однако. И речь идет одновременно и о типах и о значениях.
Каша, однако.
G>С некоторой точки зрения на полиморфизм и природу типов (такой как у тебя, например), подобное поведение выходит за рамки понятия "полиморфизм".
Эта точка зрения называется классической. И ее придерживаются все толковые словари. Полиморфизм работат на уровне типов. Точка! Все что не связано с типами к полиморфизму не относится.
G> С моей — нет. Здесь разница в слишком глубоких посылках, и философском подходе, чтобы так легко говорить, что кто-то "неверно понимает полиморфизм".
Эдак любой термин можно переиначит на наезжать на других, что тебя не понимают. Термины для того и определяются, чтобы люди друг-друга понимали.
G> Я бы выразился, что с моей точки зрения, ты понимаешь его узко — а именно в соответствии с его реализацией в распространенных ОО языках. Ну а свой взгляд на это явление, а также объяснение, почему это на мой взгляд не противоречит известному определению полиморфизма, я привел. Если непонятно, давай пообсуждаем.
Твое обоснование, лично для меня, выглядит не убедительно.
G>Правильно боишься. Вежливый человек на твоем месте сказал бы "похоже, мы с тобой по разному понимаем значение слова полиморфизм".
Косвенное наклеивание на собеседника ярлыка, например, не вежливого человека является довольно низкопроблым демагогическим приемом. Лично я не считаю, что мое мнение о твоей не правоте является не вижливым или оскорбительным. Более того, после подобных выпадов я только больше укрепляюсь в этом мнении.
G> Вот в такой формулировке — да, есть что пообсуждать. А в твоей — обсуждать с тобой то, что я "не верно понимаю", мне не хочется.
То есть обсуждать ты хочешь только если за тобой признают абсолютную правоту?
G> Потому как самый адекватный ответ на такую фразу — "сам дурак" .
Для снесения в помойку, да.
G> Но мы ведь вежливые люди, и не хотим разводить здесь флейм, не так ли? Поэтому я промолчу
Что-то ты слишком громко молчишь. И все не по теме.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Sinclair, Вы писали:
S>С абстрактно-философской точки зрения, тем не менее, я считаю трактовку паттерн-матчинга как средства достижения полиморфизма вполне корректной. Да, ты абсолютно прав: мы можем а) предоставить функцию для работы с аргументами независимо от их типа и б) автоматически выбирать реализацию функции в зависимости от ее аргументов.
Тогда банальный if — это тоже полиморфизм.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Вот аналог твоей процедуры без наследования полипорфизма и т.п.
class NonLeaf : public Leaf
{
TreeNode *m_pLeft;
TreeNode *m_pRight;
int m_number;
public:
int Sum() const
{
return
(m_pLeft == NULL ? 0 : m_pLeft->Sum())
+ (m_pRight == NULL ? 0 : m_pRight->Sum())
+ m_number;
};
Еще раз повторюсь. Если имеет место рантайм-анализ значений, то это не полиморфизм. Если имеет место подбор функции по типу, то это полиморфизм. Но подбор функции по типу — это перегрузка или виртуальный вызов, а не как не паттерн-мачинг.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Nick_, Вы писали:
N_>Можно рассматривать не только с абстрактно-философской точки зрения. В системе типов Хиндли-Милнера тип — это множество значений. Таким образом, значение тоже является типом.
Ну, тогда любой код полиморфный. Ведь все значения отдельные типы. По-моему — это уже абсурд.
Все таки есть общепринятое (классическое) понятие типа. И общепринятое понятие полипорфизма. И в разговоре с другими (особенно не обращенными в некую религию) нужно придерживаться общепринятых понятий.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Nick_, Вы писали:
N_>>Можно рассматривать не только с абстрактно-философской точки зрения. В системе типов Хиндли-Милнера тип — это множество значений. Таким образом, значение тоже является типом.
VD>Ну, тогда любой код полиморфный. Ведь все значения отдельные типы. По-моему — это уже абсурд.
VD>Все таки есть общепринятое (классическое) понятие типа. И общепринятое понятие полипорфизма. И в разговоре с другими (особенно не обращенными в некую религию) нужно придерживаться общепринятых понятий.
Здравствуйте, VladD2, Вы писали: VD>Тогда банальный if — это тоже полиморфизм.
Ну... в общем-то, почему бы и нет? Точнее, if может использоваться для достижения полиморфизма. Не вижу никаких препятствий этому.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Nick_, Вы писали:
VD>Ну, тогда любой код полиморфный. Ведь все значения отдельные типы. По-моему — это уже абсурд.
При чем тут любой код? Мы говорим о паттерн-матчинге.
Здравствуйте, Sinclair, Вы писали:
S>Ну... в общем-то, почему бы и нет? Точнее, if может использоваться для достижения полиморфизма. Не вижу никаких препятствий этому.
Речь шала о средствах поддержки полиморфизма в языках программирования. И если начать причислять к таковым средства ветвления логики вроде if-ов, то получится "плодотвореное" обсуждение сферического коня в вакуме.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>В computer science тип в самом общем смысле берет свое начало от математического понятия разбиения на классы, и определяется как множество значений, которые может принимать переменная, константа, результат функции и т.п. Некоторые языки даже позволяют определять подтипы с явным указанием набора или диапазона принимаемых значений.
ПК>Соответстенно, в случае использования pattern matching при задании параметров функции, можно считать что для параметров определяется новый тип, значения которого задаются через использованный при определении функции pattern.
Если мы не хотим получить полнейшую кашу в логике, то не нужно считать ничего что небыло заложено в самом язке. В языках поддерживающих парент-мачинг, есть четко определенное понятие типа. И парент-матчинг на это понятие не распростроняется.
Еще раз повторю, что если речь идет о средствах поддержки полиморфизма в ЯП, то нефига обсуждать средства управление ветвлением, и наче можно договориться до того, что if и switch — это тоже сресдства обеспечения полиморфизма, а вся задача программирования сводится к созданию одной полиморфной процедуры.
ПК> Безымянный тип описывается как бы прямо в определении функции, без отдельного специального определения для типа.
Ага. Безымянный тип определяется прямо в рамках if-а. Ну, ну, прада... мы же можем работать с теми же годами как с целыми. При этом любой if — начинает подразумевать ограничение на хранимую в целочисленной переменной информацию. В общем, очередной сферический конь.
ПК>Далее, о наличии полиморфизма говорят, когда один и тот же код может использоваться с разными типами (*) (**).
ПК>Таким образом, я вполне согласен с Gaperton'ом, когда он относит использование pattern matching при описании параметров функции к разновидности полиморфизма, т.к. в итоге будет выбрана соответствующая функция на основании типа аргумента (в общем смысле).
В общем, довели все до состояния сферического коня в вакуме, притянули за уши типы к значениям и на основание того что неможем отличить типов от значений зачислили if-ы и им подобные структуры в средства обеспечения полиморфизма.
Я извиняюсь, но философия должна иметь определенные приделы. Иначе можно договориться до полного маразма. Не вижу смысла отсутпать от общепринятого понятия типа данных в ЯП, а стало быть и от общепринятого понятия полиморфизма.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Если мы не хотим получить полнейшую кашу в логике, то не нужно считать ничего что небыло заложено в самом язке. В языках поддерживающих парент-мачинг, есть четко определенное понятие типа. И парент-матчинг на это понятие не распростроняется.
VD>Еще раз повторю, что если речь идет о средствах поддержки полиморфизма в ЯП, то нефига обсуждать средства управление ветвлением, и наче можно договориться до того, что if и switch — это тоже сресдства обеспечения полиморфизма, а вся задача программирования сводится к созданию одной полиморфной процедуры.
VD>В общем, довели все до состояния сферического коня в вакуме, притянули за уши типы к значениям и на основание того что неможем отличить типов от значений зачислили if-ы и им подобные структуры в средства обеспечения полиморфизма.
Не все так просто. В функциональном языке трудно отличить тип от значения.
Например, что такое список? Можно рассматривать список как тип, а можно как результат функции Cons (конструктор списка).
Тогда и полиморфизм можно свести к паттерн матчингу
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Давай лучше рассмотрим несколько более близкий пример. Вот как, например, в языке Ада можно определять подтипы целого: ПК>
ПК>subtype NonNegativeInt is INTEGER range 0 .. INTEGER'LAST;
ПК>subtype NegativeInt is INTEGER range INTEGER'FIRST .. -1;
ПК>
Фишка в том, что в ФЯ нельзя определять подтипы, поэтому такое рассуждение для них не подходит. Полиморфные там только функции, паттерн-матчинг — это лишь способ декомпозиции сложных типов. Если взять и делать вид, что он выделяет некий подтип, то в рантайме мы нарвемся на ошибку non exhaustive pattern, а некоторые языки даже нервничают, если pattern неполный и пишут warnings. То, что тут писали выше (pattern matching при определении функций) это вовсе не перегрузка или что-либо еще, это syntactic sugar. Такое обявление
func pat1 = ..
func pat2 = ..
...
эквивалентно
func x = case x of
pat1 -> ..
pat2 -> ..
..
Так что в ФЯ ПМ никак не является формой полиморфизма.
Здравствуйте, Sinclair, Вы писали:
S>Влад, не парь моск. Ничего страшного, что косвенная адресация может использоваться для обемпечения полиморфизма, причем также, как и для switch? Или уже начался вакуум? Главное отличие полиморфизма от конструкций ветвления в том, что выбор делается не явно клиентом, а средой. Ну вот паттерн-матчинг, так же как и выбор метода по типу аргумента в плюсах, делается средой.
Выбор — это не полиморфизм. Полиморфизм — это отсуствие разницы в использовании объектов разного типа.
ЗЫ
А вакуум крепчал.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Nick_, Вы писали:
N_>Например, что такое список? Можно рассматривать список как тип, а можно как результат функции Cons (конструктор списка).
Экземляры списков — это значения. Список позволяющий хранить элементы некоторого типа — это тип. Списко позволяющий хранить списки любого типа можно рассматривать как список хнанящий ссылки на некий базовый тип. Стало быть он тоже является одним типом, какие бы элементы в нем не находились.
N_>Тогда и полиморфизм можно свести к паттерн матчингу
N_>length Cons a b = 1 + length b N_>length x = 1
И все же это явный перебор. Перегрузка и патерн-матчинг четко разделяются и зачем их смешивать совершенно не ясно. Я собственно не спорю с тем, что патерн-матчинг — это интересное решение и красивая идея. Но с полиморфизмом ее путать не надо. Иначе так можно перемешать все понятия.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Тогда уж скорее статической типизации...
Похоже ты все же начинашь понимать... Хотя еще не доконца.
ПК> Каким образом динамическое определение типа нарушает инкапсуляцию?
Динамического определения типов по большому счету небывает. Его конечно можно отложить во времени, но после определения ты получишь субстанцию ни чем не отличающуюся от статически определенной. Можно даже использовать в разное время одно и тоже имя для определения типа. Но это всего лишь некрасивая возможность на подобии переопределения переменной.
Даже в языках с динамической типизацией понятие тип не исчезает. Так что проблем быть не должно.
Гипотетический пример:
class A is 1..10
class B is 3..120
def A.Test:
print "A:" + self
def B.Test:
print "B:" + self
var1 = A.new(5) // переменная на время получает значение типа А (нинамическая типизация в действии)
var1.Test() // Вызов A.Test
var1 = B.new(5) // Переменная переопределяется и начинает указывать на объект другого типа.
var1.Test() // Вызов B.Test
В общем, суть понятия типа от динамического характера языка не меняется. Задание типа на одни вызов является полнейшей профанацией. А изменение типа объекта в рантайме (не путать с изменением типа переменной или с вариантными типами) просто сумашедшей идеей ломающей все концепции ООП (полиморфизм, инкапсуляцию), и я бы даже сказал, уничтожающую понятие типа как такового.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Главное, что об этом не было бы известно в точке использования определенных таким образом функций. В случае pattern matching в параметрах это так, в случае if это не так. Наличие явных определений всех функций просто означает, что это форма ближе к ad-hoc полиморфизму, наравне с перегрузкой, а не к параметрическому полиморфизму, как это имеет место, когда одна и та же функция может работать с данными разных типов.
Извини, но это чушь. Эдакий полиморфизм можно сделать зи ифа написав один макрос.
>> И вообще, ОО-теории хреново воспринимаются функциональщиками.
ПК>Полиморфизм не требует ООП. Более того, понятие полиморфизма "родилось" именно в одном из функциональных языков, в ML, в 1976 г. Так что ОО в данном случае — переход на другую тему.
А я и не утрверждал, что с полиморфизмом в ФЯ есть какие-то проблемы. Пробелмы имеются с инкапсуляцией и вообще с восприятием ООП как идиомы.
>> Гы. Это полиморфизм. Так как есть разные четко различимыетипы и способность намерянно скрывать разницу между ними. А вот если типы не вводить, а делать проверки при определении функций или при их вызове, то это уже управление ветвлением. <...>
ПК>Все зависит от системы типов, принятой в языке. Теории типов/языков программирования допускают различные системы типов, не запрещая и определение типа по значению. Для этого даже термин специальный есть type inference. В одной из форм присутствует и во многих функциональных языках.
Нет никаких типов по значению. Есть типы и есть экземляры этих типов. Значения могут быть только в экземплярах. Иначе это уже вакханалия. Тип затем и был придуман, чтобы работать с ним как с доменом, а не как с набором значений. Большинство языки о которых идет речь реализуют совершенно обыкновенную систему типов. Тот же Окамл даже классы поддерживает. В них есть понятие перегрузки. И оно четко отделяется от понятия паттерн-матчинга. Так что не нужно снова заводить эту песню. Думаю, что ты и сам уже на своих примерах понял, что был не прав.
ПК>В Аде переменным подтипов, введенных как диапазон "базового" типа, можно присваивать значения как других диапазонов той же "базы", так и "базового" типа.
Т.е. автоматическое приведение? Тогда это вообще работать не будет. Будет невозможна ни перегрузка, ни паттерн-матчинг.
ПК> Все проверки выполняются именно во время исполнения. Соответственно, если бы в Аде можно было бы подобным образом перегрузить функции для поддиапазонов, то выбор функции производился бы именно во время их вызова, т.к. можно было бы написать именно так:
Извини, но говорить о гипотетической глупости на базе совершенно мне незнакомого языка я не хочу. Мне кажется я уже довольно хорошо донес свою мысль. Я исхожу из классического определения типов, полиморфизма и т.п. Так что в разговорах со мной лучше избегать терминов из области управления сферическми конями в вакууме.
ПК>Ошибка времени исполнения.
не в стиле Ады
(с) ты.
ПК> Или какой-нибудь компромисс в виде выбора первого подошедшего варианта (не в стиле Ады).
Во-во.
ПК> Или ошибка компиляции из-за того, что диапазоны пересекаются, если бы такое определение не было бы разрешено. Суть проектное решение автора языка. Для наших рассуждений, какой выбор он сделает, погоды не играет.
Или другое гадание на кофейной гуще. Предлагаю завязать. Навязывать мне столь необоснованную точку зрения действительно бессмысленно.
Пока что я придерживаюсь мнения о том, что полиморфизм — это работа с объектами разных типов одинаковыми метадами. А паттерн-матчикнг — это работа со с разными значениями одного типа одинаковыми метадами. Если будут аргументы отличные от кармического понимания сущьности тип, то с удовольствием продолжу обсуждение. А так надоело.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
VladD2:
> ПК> Каким образом динамическое определение типа нарушает инкапсуляцию?
> Динамического определения типов по большому счету небывает.
Бывает, но это уже другой разговор.
В этом разговоре речь шла не об определении самих типов, структура которых, в данном случае, определяется на этапе написания программы, а об определении совместимости типов во время вызова функции. При этом совместимость, очевидно, проверяется по структуре типа, а не по его имени, которого у него нет.
Posted via RSDN NNTP Server 1.9 gamma
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>В этом разговоре речь шла не об определении самих типов, структура которых, в данном случае, определяется на этапе написания программы, а об определении совместимости типов во время вызова функции. При этом совместимость, очевидно, проверяется по структуре типа, а не по его имени, которого у него нет.
Это называется слабой типизацией. И это уже тема другого разговора.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
VladD2:
> ПК> Главное, что об этом не было бы известно в точке использования определенных таким образом функций. В случае pattern matching в параметрах это так, в случае if это не так. Наличие явных определений всех функций просто означает, что это форма ближе к ad-hoc полиморфизму, наравне с перегрузкой, а не к параметрическому полиморфизму, как это имеет место, когда одна и та же функция может работать с данными разных типов.
> Эдакий полиморфизм можно сделать зи ифа написав один макрос.
Ок, продемонстрируй. При этом множество типов должно быть расширяемым без модификации этого макроса, путем определения функций, среди которых производится выбор.
> Пока что я придерживаюсь мнения о том, что полиморфизм — это работа с объектами разных типов одинаковыми метадами. А паттерн-матчикнг — это работа со с разными значениями одного типа одинаковыми метадами.
Хорошо. В таком случае вопрос: структура из двух элементов, и список из двух элементов — это два разных типа, или два разных значения одного типа?
Posted via RSDN NNTP Server 1.9 gamma
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Nick_, Вы писали:
N_>>Например, что такое список? Можно рассматривать список как тип, а можно как результат функции Cons (конструктор списка).
VD>Экземляры списков — это значения. Список позволяющий хранить элементы некоторого типа — это тип. Списко позволяющий хранить списки любого типа можно рассматривать как список хнанящий ссылки на некий базовый тип. Стало быть он тоже является одним типом, какие бы элементы в нем не находились.
При чем тут базовый тип? Что такое вообще базовый тип? Ты про наследование? При чем тут вообще наследование? Полиморфизм от наследования никак не зависит.
N_>>Тогда и полиморфизм можно свести к паттерн матчингу
N_>>length Cons a b = 1 + length b N_>>length x = 1
VD>И все же это явный перебор. Перегрузка и патерн-матчинг четко разделяются и зачем их смешивать совершенно не ясно. Я собственно не спорю с тем, что патерн-матчинг — это интересное решение и красивая идея. Но с полиморфизмом ее путать не надо. Иначе так можно перемешать все понятия.
Приведу пример на С++. Есть перегрузка, а есть параметры по умолчанию. С помощью перегрузки можно сделать параметры по умолчанию. Если перегрузку и параметры по умолчанию не "путать", то в язык можно засунуть и то и другое. Вот так и получаются неоднозначности в языке.
Re[22]: Какой полиморфизм используется в ФЯ?
От:
Аноним
Дата:
05.11.04 06:59
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:
ПК> понятие полиморфизма "родилось" именно в одном из функциональных языков, в ML, в 1976 г.
Ели быть совсем уж точным, понятие полиморфизма "родилось" чуть раньше, в CPL.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Павел Кузнецов, Вы писали:
VD>Кстати, расматрение значений как типов определяемых на время вызова процедуры — это прямейшее нарушение принципов инкапсуляции. Хотя это понятие из области ООП, и слабо применимо к ФЯ, но печальные последствия при таком взгляде на жизнь не заставят себя долго ждать. Рано или поздно будут сделаны неверные предположения о "динамическом типе". На то и были придуманы приципы ООП, чтобы материализовывать все свои окраничения и предположения в рамках понтия объекта и его типа.
Такс, не мог бы ты привести примерчик нарушения инкапсуляции в ФЯ? Интересно, однако...
Как это ф. программисты вот уже полстолетия слона не замечают.
(твой пример про диапазоны "не катит", т.к. не знаю я таких ФЯ, где бы они были, типы определяются, имхо, до "целое", "с плав. запятой", "строка" и т.п.)
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Sinclair, Вы писали:
S>>С абстрактно-философской точки зрения, тем не менее, я считаю трактовку паттерн-матчинга как средства достижения полиморфизма вполне корректной. Да, ты абсолютно прав: мы можем а) предоставить функцию для работы с аргументами независимо от их типа и б) автоматически выбирать реализацию функции в зависимости от ее аргументов.
VD>Тогда банальный if — это тоже полиморфизм.
Конечно, если if применяется для определения типа. Это так называемый "исскуственный полиморфизм". Термин взят не из википедий, а из работ господина Калиниченко, где излагается законченная теория типа (google. Это было в 99 году, так что ссылок не помню). И вот эта функция funct( void * ) тоже может быть полиморфной, если внутри делаются разные действия в зависимости от фактического значения (типа) аргумента. Впрочем, если ты внимательно прочтешь свое определение из википедии (а не будешь продолжать оперировать своим интуитивным представлением о полиморфизме), то вопрос должен уйти сам собой, так там нет никаких противоречий с явной проверкой типа.
Это было во первых. А во вторых, совершенно не понятно, причем здесь if. Паттерн-матчинг в моих примерах про дерево применяется только для того, чтобы различать разные типы, и является частью сигнатур функций, что является прямым аналогом "виртуальных функций". Вот тебе тот же пример со строгой типизацией (Хиндли-Милнер):
data Tree = Node Integer Tree Tree | Leaf Integer
sum Node value left right = value + sum left + sum right
sum Leaf value = value
Вот взять, например, замечательный язык Nemerle под платформу .NET. В нем для типа Tree будет создан базовый класс, в то время как для Node и Leaf будут созданны подклассы. Я и пример подобрал специально, чтобы было прямое соответствие. Не знаю, что надо сделать, чтобы объяснить лучше.
> ПК> понятие полиморфизма "родилось" именно в одном из функциональных языков, в ML, в 1976 г.
> Ели быть совсем уж точным, понятие полиморфизма "родилось" чуть раньше, в CPL.
Да, действительно, сам полиморфизм родился ранее. Поправка принята. Правда, термин, насколько я понимаю, родился позже, но это не суть важно.
Posted via RSDN NNTP Server 1.9 gamma
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, Gaperton, Вы писали:
VD>>Тогда банальный if — это тоже полиморфизм. G>Конечно,
Ну, в общем-то ситуация полного бессмыслия достигнута и дальше уже можно не продолжать. Классический случай сферического коня в вакууме.
G> если if применяется для определения типа.
Тогда паттерн-мтчинг и полиморфизм есть во всех языках так как if может применяться для чего угодно.
Надо все же разделять классификацию возможностей и цели их применения. Нет ни одного языка программирования на котором можно было написать то, что нельзя реализовать на С. Но это не делает С ни ФЯ, ни ООЯ.
G>Это было во первых. А во вторых, совершенно не понятно, причем здесь if. Паттерн-матчинг в моих примерах про дерево применяется только для того, чтобы различать разные типы,
Это не патерн-матчинг. Это перегрузка функций. Или, если трактовать все расширительно, то паттерн-матчинг есть в любом ООЯ.
G> и является частью сигнатур функций, что является прямым аналогом "виртуальных функций". Вот тебе тот же пример со строгой типизацией (Хиндли-Милнер):
G>
G>data Tree = Node Integer Tree Tree | Leaf Integer
G>sum Node value left right = value + sum left + sum right
G>sum Leaf value = value
G>
Это перегрузка функций по типу. Просто в ООЯ она записывается несколько по другому.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
N_>При чем тут базовый тип? Что такое вообще базовый тип? Ты про наследование? При чем тут вообще наследование? Полиморфизм от наследования никак не зависит.
Отсуствие наследования где-то еще не отменяет принципа родовой принадлежности.
N_>Приведу пример на С++. Есть перегрузка, а есть параметры по умолчанию. С помощью перегрузки можно сделать параметры по умолчанию. Если перегрузку и параметры по умолчанию не "путать", то в язык можно засунуть и то и другое. Вот так и получаются неоднозначности в языке.
И перегрузка, и параметры по умолчанию — это решение одной и той же проблемы. Это все по сути перегрузка. Собственно плохо или хорошо совмещать их в одном зыке вопрос спорный. В Шарпе и Яве решили, что плохо. Я первое время мучился, но потом привык и особых проблем не возникает. Правда у меня их и в С++ не возникало. Так что скорее вопрос привычки и к данной теме он вряд ли относится.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Ок, продемонстрируй. При этом множество типов должно быть расширяемым без модификации этого макроса, путем определения функций, среди которых производится выбор.
А типы то с какого должны расширяться. Или мы снова про коника?
>> Пока что я придерживаюсь мнения о том, что полиморфизм — это работа с объектами разных типов одинаковыми метадами. А паттерн-матчикнг — это работа со с разными значениями одного типа одинаковыми метадами.
ПК>Хорошо. В таком случае вопрос: структура из двух элементов, и список из двух элементов — это два разных типа, или два разных значения одного типа?
Два разных. Более того две структуры тоже два разных типа. И два списка с разными типами элементов тоже разные типы (если конечно тип списка определен заранее, и она не полиморфная).
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Курилка, Вы писали:
К>Такс, не мог бы ты привести примерчик нарушения инкапсуляции в ФЯ? Интересно, однако...
Да они на каждом шагу. Те же кортежи (тюплы), работа с незакрытыми методами просыми типами и т.п. Вместо инкапсуляции данных делается упор на декомпозиции кода. В принципе упрощение кода снижает требования к инкапсуляции, так как в простом коде ошибки сделать слонее. Но жизнь от кода, а не от данных всегда приводит к наплевательскому отношению к инкапсуляции.
Ты лучше покажи мне хтя бы одно средство инкапсуляции в ФЯ, кроме разве что вариантрых типов. Есть конечно языки впитавшие в себя ОО-принципы, но в этом вряд ли заслуга именно ФЯ.
К>Как это ф. программисты вот уже полстолетия слона не замечают.
Да шишники вот уже 35 лет слона не замечают. Хотя не все. Многие просто чисто интиуитивно переползают на более совершенные с точки зрения инкапсуляции языки вроде С++, Явы, Шарпа...
К>(твой пример про диапазоны "не катит", т.к. не знаю я таких ФЯ, где бы они были, типы определяются, имхо, до "целое", "с плав. запятой", "строка" и т.п.)
Дык потому их и нет. На любом ООЯ можно создать подобный тип просто штатными средствами. Я просто пытался написать максимально простой псевда-код. В реальной жизни диапазон прийтеся инкапсулировать в класс, а управлять им методами и операторами.
В большинстве же ФЯ мне прийдется объявить переменную подходящего типа, а ее значение контролировать средствами вроде паттерн-матчинга, ифов, кейсов и т.п. В любой момент я могу ошибиться и компилятор мне ничем не поможет, так как без инкапсуляции он просто не в силах предугадать что же я собственно хотел.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Павел Кузнецов, Вы писали:
>> Так что в ФЯ ПМ никак не является формой полиморфизма.
ПК>Конечно, сам по себе pattern matching формой полиморфизма не является.
Читал... долго думал... То ли это такой способ признать свою неправоту, то еще что. Но забавно.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
VladD2:
>>> Так что в ФЯ ПМ никак не является формой полиморфизма.
> ПК>Конечно, сам по себе pattern matching формой полиморфизма не является.
> Читал... долго думал... То ли это такой способ признать свою неправоту, то еще что. Но забавно.
А где я утверждал, что pattern matching является формой полиморфизма?
Речь шла об использовании pattern matching для получения полиморного поведения. Результат такого использования — да, является вариантом полиморфизма. Точно так же механизм SFINAE полиморфизмом не является, но может быть использован для реализации полиморфизма в сочетании с перегрузкой шаблонов функций.
А паттерн-матчинг я за полиморфизм не принимаю, это разные вещи. Применение паттерн-матчинга при задании аргументов функции — вот это является одним из самых мощных способов достижения полиморфизма в ФЯ.
Posted via RSDN NNTP Server 1.9 gamma
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
VladD2:
> ПК> Ок, продемонстрируй. При этом множество типов должно быть расширяемым без модификации этого макроса, путем определения функций, среди которых производится выбор.
> А типы то с какого должны расширяться.
Потому что в противном случае ты будешь решать другую задачу.
>>> полиморфизм — это работа с объектами разных типов одинаковыми метадами. А паттерн-матчикнг — это работа со с разными значениями одного типа одинаковыми метадами.
> ПК> структура из двух элементов, и список из двух элементов — это два разных типа, или два разных значения одного типа?
> Два разных.
Тогда почему вот это по твоему утверждению не полиморфизм?
poly_function( { A, B } ) -> ...;
poly_function( [ A, B ] ) -> ...;
Posted via RSDN NNTP Server 1.9 gamma
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Таким образом, я вполне согласен с Gaperton'ом, когда он относит использование pattern matching при описании параметров функции к разновидности полиморфизма, т.к. в итоге будет выбрана соответствующая функция на основании типа аргумента (в общем смысле).
ПК>Речь шла об использовании pattern matching для получения полиморного поведения.
Неправда. Речь, шал о неверной использовании термина полиморфизм. Речь вообще о полиморфизме в ФЯ (см. тему).
ПК> Результат такого использования — да, является вариантом полиморфизма.
Угу. Как и if. Не надо все доводить до состояния коника в вакууме.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Тогда почему вот это по твоему утверждению не полиморфизм? ПК>
ПК>poly_function( { A, B } ) -> ...;
ПК>poly_function( [ A, B ] ) -> ...;
ПК>
А что ты под этим понимашь? Если { A, B } — это картэж, а [ A, B ] — это список, то это несомненно полиморфная функция, а операция называется перегрузкой. В вот если будте, как-то так:
VladD2,
> ПК> А где я утверждал, что pattern matching является формой полиморфизма?
> Практически во всех сообщениях этой темы. > Например: Re[17]: Какой полиморфизм используется в ФЯ?
Таким образом, я вполне согласен с Gaperton'ом, когда он относит использование pattern matching при описании параметров функции к разновидности полиморфизма, т.к. в итоге будет выбрана соответствующая функция на основании типа аргумента (в общем смысле).
Ты, действительно, считаешь эти два предложения семантически эквивалентными?
Использование pattern matching в описании параметров для выбора подходящей функции является разновидностью полиморфизма.
Pattern matching является разновидностью полиморфизма.
А эти?
Использование SFINAE в объявлении шаблона для выбора подходящей функции является разновидностью полиморфизма.
SFINAE является разновидностью полиморфизма.
Posted via RSDN NNTP Server 1.9 gamma
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
VladD2:
> ПК>Тогда почему вот это по твоему утверждению не полиморфизм? > ПК>
> ПК>poly_function( { A, B } ) -> ...;
> ПК>poly_function( [ A, B ] ) -> ...;
> ПК>
> Если { A, B } — это картэж, а [ A, B ] — это список, то это несомненно полиморфная функция <...> В вот если будте, как-то так: <...> То это будет паттерн-матчинг
А в первом случае pattern matching происходить не будет?
Posted via RSDN NNTP Server 1.9 gamma
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, Павел Кузнецов, Вы писали:
>> ПК>Тогда почему вот это по твоему утверждению не полиморфизм? >> ПК>
>> ПК>poly_function( { A, B } ) -> ...;
>> ПК>poly_function( [ A, B ] ) -> ...;
>> ПК>
>> Если { A, B } — это картэж, а [ A, B ] — это список, то это несомненно полиморфная функция <...> В вот если будте, как-то так: <...> То это будет паттерн-матчинг
ПК>А в первом случае pattern matching происходить не будет?
Какая разница? Главное, что ты демонстрируешь перегрузку называя ее поттерн-матчингом.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали: VD>Да они на каждом шагу. Те же кортежи (тюплы), работа с незакрытыми методами просыми типами и т.п. ... Ты лучше покажи мне хтя бы одно средство инкапсуляции в ФЯ, кроме разве что вариантрых типов.
В Haskell можно скрывать отдельные поля кортежа, методы класса в списке экспортов модуля (т.е. файла) (http://www.haskell.org/onlinereport/modules.html#sect5.2). Какие ещё средства инкапсуляции остались?
VladD2:
> ПК> Ты, действительно, считаешь эти два предложения семантически эквивалентными?
> Я считаю, что ты выкручиваешся.
1) Этого я у тебя не спрашивал. 2) Это является переходом к обсуждению моих действий, что к ранее обсуждаемой теме не относится, и мне мало интересно.
Так ответь, пожалуйста, на тот вопрос, что я задавал. А именно, являются ли следующие два предложения эквивалентными:
Использование pattern matching в описании параметров для выбора подходящей функции является разновидностью полиморфизма.
Pattern matching является разновидностью полиморфизма.
Т.к. если ты эти предложения эквивалентными не считаешь, то твое заявление о том, что я утверждал второе, ты так и не подтвердил.
Если же ты считаешь эти два предложения эквивалентными, то дальше разговор можно не продолжать, т.к. это будет означать, что у нас с тобой совершенно различные взгляды на логику. А разговаривать с собеседником, использующим принципиально другие правила вывода, мне представляется абсолютно неконструктивным.
Posted via RSDN NNTP Server 1.9 gamma
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, beroal, Вы писали:
B>В Haskell можно скрывать отдельные поля кортежа, методы класса в списке экспортов модуля (т.е. файла) (http://www.haskell.org/onlinereport/modules.html#sect5.2). Какие ещё средства инкапсуляции остались?
К сожалению я не знаком (покрайней мере так близко) с Хаскелем. Так что ничего определенного сказать не могу.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>1) Этого я у тебя не спрашивал. 2) Это является переходом к обсуждению моих действий, что к ранее обсуждаемой теме не относится, и мне мало интересно.
Не тебе говорить о подмене темы, так как ты только этим и знимашся все последние посты.
Вступать в демагогические обсуждения эквивалентности высказываний я не собираюсь. Если ты согласен с тем, что паттерн-матчинг и перегрузка функций вещи разные, и если ты согласен с тем, что паттерн-матчинг не является сам по себе полиморфизмом, то обсуждать больше нечего так как наши мнения сходятся.
Правда тогда становится очевидным, что поддежка Гапертона была не более чем попыткой увести разговор от темы подменив ее общей философией. Ну, а как это называется ты знаешь не хуже меня.
ПК>Так ответь, пожалуйста, на тот вопрос, что я задавал.
А я не хочу идти у тебя на поводу. Твои цели мне более чем ясны. Потокать им я не считаю нужным.
Далее я всего лишь поясняю почему я не хочу двать ответы на подобные вопросы.
ПК> А именно, являются ли следующие два предложения эквивалентными: ПК> Использование pattern matching в описании параметров для выбора подходящей функции является разновидностью полиморфизма. ПК> Pattern matching является разновидностью полиморфизма.
Ошибочны оба утверждения. И фактическая эквивалентность тут просто не причем. Разница между этими предложениями не имеет никакого отношения к делу. Это часть откровенной демагогии которая раскручивается здесь вот уже несколко постов. (Надо признать, что не без успеха.)
Этот вопрос из серии "Бросил ли ты уже пить коньяк по утрам?". Как не овечай все равно будет глупость. Одеинственно верный ответ в таких ситуациях — впорос сформулирован некорректно, я никогда не пил коньяк по утрам.
Лучше я попытаюсь вернуть дискуссию к исходному вопросу и продемонстрирую очевидность этой демагогии.
Итак, вот с чего начался этот спор:
G>А во вторых, при разрешении полиморфного вызова учитываются не только типы, но и значения аргументов (в "обычных" языках — только типы). Причем, в разрешении вызова принимаются во внимание все аргументы (а не только тип неявного аргумента виртуальной функции — объект). Это самое главное отличие полиморфизма ФЯ от обычных языков.
В "обычных языках" это называется мутиметодами. Они кое где реализованы. А кое где реализуются имеющимися средствами.
Здесь я к сожалению не обратил внимания на превую часть фразы которая содержала ложные предпосылки. А именно "при разрешении полиморфного вызова учитываются не только типы, но и значения аргументов". При полиморфных вызовах никакие значения не учитываются. Тут Гапертон говорил о патерн-матчинге, но так как он говорил о полиморфизме, то я прост не заметил ошибки в логике. Несомненно полиморфизм можно эмулировать на обычных операциях ветвления и ручном хранении информации о типах, но это всего лишь эмуляция. И такая эмуляция возможна в любых языках. Даже в С на базе if-ов или switch-ей. И тогда разговоры о полиморфизме в ФЯ становятся форменной демагогией, так как это не является свойством ФЯ, а всего лишь доказывает, что и на ФЯ можно эмулировать некоторое поведение.
Я же отвечал на вторую половину этой фразы, а именно на "Причем, в разрешении вызова принимаются во внимание все аргументы", подразумевая, что речь идет о полиморфизме, причем, полиморфизме обеспечиваемом языком, а не эмулируемом.
Когда я понял, что именно я не понял в его высказывании, я обратил его внимание на то, что паттерн-матчинг который тот неявно подразумевал не является средством обеспечения полиморфизма: Re[14]: Какой полиморфизм используется в ФЯ?
А паттерн-матчинг я за полиморфизм не принимаю, это разные вещи. Применение паттерн-матчинга при задании аргументов функции - вот это является одним из самых мощных способов достижения полиморфизма в ФЯ.
Что же это заявление должно было обозначать? Если товоришь проглотил тот факт, что речь идет об эмуляции, то это демагогия так как эмуляция не может быть свойством языка, или их группы (ФЯ). Если же все же имеется в виду, что паттерн-матчинг непосредственно обеспечивает поддержку полиморфизма, то это а) неправда, б) противоречит первому выделенному фрагменту. В общем, как не крути — это форменная демагогия.
Далее ты полез его защищать не смотря на то что товаришь без малейшего намека на приличие продолжил развивать демагогию переходом на личность оппонента и косвенными оскорблениями. В процессе защиты ты мне начал доказывать
if здесь совершенно ни при чем, т.к. он строится так, что ему "известно" об используемых "типах" (явный выбор ветвлением), в то время как полиморфизм требует отсутствия этого знания у полиморфного кода.
Далее ты начал расскзаывать про какое-то гипотетическое поведение АДЫ (которую ты явно так же не знаешь как и я) и далать на базе этого какие-то выводы. Тебе не устроили определения из Википедии и в конце концов обсуждение вылелось в натуральную демагогию.
тебя не остановили. В итоне ты перешел на доказательство неких фразиологических соответствий вместо обсуждения сути проблемы.
По сему предлагаю ответить на поставленные в начале обсуждения вопросы и закрыть таким образом тему.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[29]: Какой полиморфизм используется в ФЯ?
От:
Аноним
Дата:
07.11.04 16:27
Оценка:
Что-то много эмоций и мало логики.
Понятие полиморфизм означает применимость функции к разным типам.
Поскольку эрланг бестиповый язык, никакого полиморфизма в нем не может быть по определению.
Вот это > poly_function( { A, B } ) -> ...; > poly_function( [ A, B ] ) -> ...;
не полиморфная фунция.
Применить же сопоставление в одной и той же функции к спискам и кортежам в типизированном языке не получится.
И еще о терминологии. Термины "параметрический полиморфизм" и "полиморфизм ad-hoc" реально используются, а вот "динамический/статический полиморфизм" -нет. Говорят о динамической или статической диспетчеризации.
VladD2,
> <... риторика и очередная порция наездов пропущена ...>
> ПК> А именно, являются ли следующие два предложения эквивалентными: > ПК> Использование pattern matching в описании параметров для выбора подходящей функции является разновидностью полиморфизма. > ПК> Pattern matching является разновидностью полиморфизма.
> Ошибочны оба утверждения. И фактическая эквивалентность тут просто не причем.
Очень даже причем, т.к. я был согласен с первым и нигде не утверждал второго, в то время как ты приписывал мне высказывания второго из этих утверждений "практически во всех сообщениях этой темы". Впредь не надо торопиться делать подобные заявления, раз ты не можешь подтвердить их цитатами, и все будет хорошо.
Posted via RSDN NNTP Server 1.9 gamma
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, VladD2, Вы писали: VD>Выбор — это не полиморфизм. Полиморфизм — это отсуствие разницы в использовании объектов разного типа.
Влад, перестань упираться. Ок, паттерн матчинг — это отсутствие разницы в использовании объектов разного типа. Где я не прав?
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[31]: Какой полиморфизм используется в ФЯ?
От:
Аноним
Дата:
09.11.04 06:26
Оценка:
Здравствуйте, Gaperton, Вы писали:
G>А эрланг — это динамически типизированный язык.
"Динамически типизированный" и бестиповый — это одно и то же.
А>>Вот это >>> poly_function( { A, B } ) -> ...; >>> poly_function( [ A, B ] ) -> ...; А>>не полиморфная фунция. G>Неправильно. Это — полиморфная функция.
Повторюсь. Полиморфная функция-функция,применимая к объектам разных типов. В эрланге все функции имеют один тип аргумента — терм.
G>
G>::MyType = MyTuple Int Int | MyList [Int]
G>Funct:: MyType -> Int
G>Funct ( MyTuple a b ) = a
G>Funct ( MyList [ a, b ] ) = a
G>
Вы наверное удивитесь, если я скажу, что это тоже не полиморфная функция? Посмоторите на её сигнатуру. G> в "бестиповом" эрланге можно добавить такие же ограничения на типы элементов.
А после этого он превратится в типизированный.
Полиморфизм нужен чтобы обходить ограничения, накладываемые системой типов. Если никаких
ограничений нет, значит нет и типов и полиморфизм ни к чему.
Re[4]: Какой полиморфизм используется в ФЯ?
От:
Аноним
Дата:
09.11.04 06:57
Оценка:
Пример, пример в студию. Интересно, и я думаю, не только мне.
Здравствуйте, Аноним, Вы писали:
G>>А эрланг — это динамически типизированный язык. А>"Динамически типизированный" и бестиповый — это одно и то же.
Сомнительное утверждение. Не мог бы ты это обосновать?
А>Полиморфизм нужен чтобы обходить ограничения, накладываемые системой типов. Если никаких А>ограничений нет, значит нет и типов и полиморфизм ни к чему.
Ну а это вообще бред. Полиморфизм — это более сложная система типов.
Бывают простые системы типов, в которых тип — это "константа". Например как в паскале. А бывают системы типов в которых тип может зависить от другого типа.
Например функция берущая первый элемент списка берет список элементов типа A и возвращает элемент типа A.
First :: [A] -> A
A — это тип и он является параметром других типов: [A] — список элементов типа A, [A] -> A[/code] — тип функции принимающей один аргумент — список A и возвращающей элемент типа A
Разные системы типов, естественно, накладывают разные ограничения на программу. Но полиморфизм — это не сбоку приделка к простой системе типов, а ее обобщение.
Re[33]: Какой полиморфизм используется в ФЯ?
От:
Аноним
Дата:
09.11.04 08:14
Оценка:
Здравствуйте, Nick_, Вы писали:
А>>"Динамически типизированный" и бестиповый — это одно и то же. N_>Сомнительное утверждение. Не мог бы ты это обосновать?
Некоторая сущность (в данном случае тип) присутствует в языке, если в нем имеются средства для её выражения. В противном случае все эти "типы" существуют только в нашем сознании, но никак ни в программах, ни в языке.
А>>Полиморфизм нужен чтобы обходить ограничения, накладываемые системой типов. Если никаких А>>ограничений нет, значит нет и типов и полиморфизм ни к чему.
N_>Разные системы типов, естественно, накладывают разные ограничения на программу. Но полиморфизм — это не сбоку приделка к простой системе типов, а ее обобщение.
Ну правильно, обобщение. Но вот зачем понадобилось это обобщение? Очевидно, как раз потому, что ограничения, накладываемые мономорфной системой типов слишком серьезные.
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Gaperton, Вы писали:
G>>А эрланг — это динамически типизированный язык. А>"Динамически типизированный" и бестиповый — это одно и то же.
Кто это вам сказал?
А>>>Вот это >>>> poly_function( { A, B } ) -> ...; >>>> poly_function( [ A, B ] ) -> ...; А>>>не полиморфная фунция. G>>Неправильно. Это — полиморфная функция. А>Повторюсь. Полиморфная функция-функция,применимая к объектам разных типов. В эрланге все функции имеют один тип аргумента — терм.
Вы не правы. Не стоит повторяться, я и так прекрасно вас понял. К мануалу я уже вас отсылал, раз не помогло, приведу цитату.
2 Data Types 2.1 Terms
Erlang provides a number of data types which are listed in this chapter. A piece of data of any data type is called a term.
2.2 Number
2.3 Atom
2.4 Binary
2.5 Reference
2.6 Fun
2.7 Port Identifier
2.8 Pid
2.9 Tuple
2.10 List
2.11 String
2.12 Record
2.13 Boolean
2.14 Escape Sequences 2.15 Type Conversions
G>>
G>>::MyType = MyTuple Int Int | MyList [Int]
G>>Funct:: MyType -> Int
G>>Funct ( MyTuple a b ) = a
G>>Funct ( MyList [ a, b ] ) = a
G>>
А>Вы наверное удивитесь, если я скажу, что это тоже не полиморфная функция? Посмоторите на её сигнатуру.
Намек понял. Формально — да, это один тип. А вы не сильно удивитесь, если я скажу, что определение типа несложно разбить на три определения, так, чтобы и tuple и list являлись отдельными типами? И что это у нас поменяет? Радикально — ничего, но функция станет полиморфной, так?
G>> в "бестиповом" эрланге можно добавить такие же ограничения на типы элементов. А>А после этого он превратится в типизированный.
Что-то я не понял. То есть если я напишу так
funct( { X, Y } ) -> X * Y.
то эрланг бестиповый язык. А если я добавлю вот это
funct( { X, Y } ) where is_integer( X ), is_integer( Y ) -> X * Y.
то он превратится в типизированный (чем, кстати, не замедлит воспользоваться компилятор). И это все не меняя самого языка. Чудеса? Как будем разрешать этот забавный казус?
А>Полиморфизм нужен чтобы обходить ограничения, накладываемые системой типов. Если никаких А>ограничений нет, значит нет и типов и полиморфизм ни к чему.
Понятна точка зрения. Не согласен с вашим пониманием полиморфизма. Попробуйте перенести эти рассуждения на Smalltalk. Он динамически типизирован, т. е. в ваших терминах "бестиповый". Ваши рассуждения сведутся к абсурду. Если я не прав, напишите здесь про Smalltalk подробно.
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Очень даже причем, т.к. я был согласен с первым и нигде не утверждал второго, в то время как ты приписывал мне высказывания второго из этих утверждений "практически во всех сообщениях этой темы". Впредь не надо торопиться делать подобные заявления, раз ты не можешь подтвердить их цитатами, и все будет хорошо.
Оба утверждения не верны.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Nick_, Вы писали:
N_>>Тогда вызов виртуальной функции тоже не полиморфизм, а средство управления ветвлением при исполнении на основе анализа значений. Красивый аналог if-a и switch-a.
VD>А вот вызов виртуальной функции зависит исключительно от динамического типа объекта. При этом никаких условий ни в методе, ни при его вызове нет.
Здравствуйте, Трурль, Вы писали:
G>>Если бы типы отсутствовали, например, в языке Erlang, а существовали только в моем сознании, то и паттерн-матчинг я мог бы выполнять только в своем сознании. Т>Здесь неявно используется ложная посылка, что паттерн-матчинг связан с типами. Т>
Т>f(1)->...
Т>f(2)->...
Т>f(3)->...
Т>
Т>Следует ли признать, что 1,2 и 3 имеют разные типы? Т>Вообще из Вашей теории следует, что существуют такие типы, как: Т>- положительные числа; Т>- четные числа; Т>- простые числа; Т>- непустые списки; Т>- списки, первый элемент которых 1, а второй — alpha; Т>.... Т>и что любая функция является полиморфной.
Здравствуйте, Трурль, Вы писали:
G>>Если бы типы отсутствовали, например, в языке Erlang, а существовали только в моем сознании, то и паттерн-матчинг я мог бы выполнять только в своем сознании. Т>Здесь неявно используется ложная посылка, что паттерн-матчинг связан с типами.
А она не ложная. Он связан одновременно и с типами, и со значениями, а не только с типами. Вот например, эта функция принимает аргументом списки и кортежи целых чисел размерности 2. Это разные типы, и я не понимаю, где здесь ложная посылка. У каждого значения в динамически типизированном языке есть тип.
f( { A, B } ) where is_integer( A ), is_integer( B ) ->
f( X ) where is_integer( X ) ->
f( [ H | T ] ) where is_integer( H ) ->
f( [] ) ->
Т>Следует ли признать, что 1,2 и 3 имеют разные типы?
Не следует.
Т>Вообще из Вашей теории следует, что существуют такие типы, как: Т>- положительные числа; Т>- четные числа; Т>- простые числа; Т>- непустые списки; Т>- списки, первый элемент которых 1, а второй — alpha; Т>....
Будут существовать, если я такие типы определю, и буду думать о них как о типах. Вот например на С++ я смогу классы под все перечисленные типы создать, и ограничить операции, и это будет являться полноценным типом с точки зрения языка.
В Erlang же с точки зреня языка, компилятора, и системы типов перечисленные вещи типами не являются. При этом, с точки зрения теории типов они являются подтипами number и list, а паттерн-матчинг является способом конструировать типы и подтипы на лету. Этот взгляд на вещи тоже вполне корректен. Выбирайте любую точку зрения, которая удобна в данный момент.
Т>и что любая функция является полиморфной.
Переменная полиморфна, если может хранить значения разных типов. Функция полиморфна, если ее аргументы — полиморфные переменные. Следовательно, в динамически типизированном языке формально любая функция является полиморфной, это жесткая правда жизни. Но есть три нюанса.
1) В статически типизированном языке это очевидно не так, так как далеко не любая переменная там может хранить значения разных типов. Но вот, допустим, переменная-указатель на базовый класс или интерфейс — может вполне.
2) В динамически типизированном языке с аннотацией типов далеко не любая переменная может хранить значение любого типа. Примеры — JScript .NET, Erlang.
non_poly_fun( X ) where is_integer( X ) ->
3) В динамически типизированном языке без аннотации типов тоже не любая функция будет полиморфной де-факто. Так как функция должна не просто принимать аргументы разных типов, но и выполнять с ними осмысленную работу.
non_poly_fun( Array, Index ) -> element( Array, Index ).
Эта функция не полиморфна, так как типы аргументов установлены жестко — шаг влево шаг вправо — и exception.
Вот например, я такую функцию
process( [ H | T ] ) where is_integer( H ) ->
process( [] ) ->
полиморфной не считаю. А также такую
process( [ H | T ], S ) -> process( T, S + H )
process( [], S ) -> S
Почему? Да потому, что в этой функции из контекста определяются типы элементов списка и S — это number. При передаче внутрь чего-нибудь другого вылетит exception, не смотря на отсутствие проверки типа в паттерне (хотя number это на самом деле два типа — integer и float, так что ее можно считать полиморфной).
Здравствуйте, Трурль, Вы писали:
Т>Здравствуйте, Nick_, Вы писали:
N_>>И чему это противоречит?
Т>Ничему не противоречит. Но, согласитесь, странно вводить термин, обозначающий свойство которым обладают все функции.
Не все. Читайте мой ответ.
Здравствуйте, Gaperton, Вы писали: G>Следовательно, в динамически типизированном языке формально любая функция является полиморфной, это жесткая правда жизни.
Следовательно, в динамически типизированном языке сказать "f-полиморфная функция" то же самое, что сказать "f-функция".
G>Будут существовать, если я такие типы определю, и буду думать о них как о типах.
Вот, вот. Только в сознании.
Здравствуйте, Трурль, Вы писали:
G>>Если бы типы отсутствовали, например, в языке Erlang, а существовали только в моем сознании, то и паттерн-матчинг я мог бы выполнять только в своем сознании. Т>Здесь неявно используется ложная посылка, что паттерн-матчинг связан с типами. Т>
Т>f(1)->...
Т>f(2)->...
Т>f(3)->...
Т>
Т>Следует ли признать, что 1,2 и 3 имеют разные типы? Т>Вообще из Вашей теории следует, что существуют такие типы, как: Т>- положительные числа; Т>- четные числа; Т>- простые числа; Т>- непустые списки; Т>- списки, первый элемент которых 1, а второй — alpha; Т>.... Т>и что любая функция является полиморфной.
Вот именно. И самое смешное, что создать типы с ограничением на значение можно. Но это уже совсем другая история.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Трурль, Вы писали:
Т>Здравствуйте, Gaperton, Вы писали: G>>Следовательно, в динамически типизированном языке формально любая функция является полиморфной, это жесткая правда жизни. Т>Следовательно, в динамически типизированном языке сказать "f-полиморфная функция" то же самое, что сказать "f-функция".
Читай все письмо, для тебя писал. Там было перечислено три нюанса. Из которых два относятся к этому вопросу.
G>>Будут существовать, если я такие типы определю, и буду думать о них как о типах. Т>Вот, вот. Только в сознании.
Не только в сознании.
На С++ и Haskell я их могу определить явно, о чем написал в следующем же предложении.
Ты читаешь и отвечаешь только на первое предложение абзаца, так?
P.S.: Слушай, тебе правда кажется, что если ты удалишь содержательные части ответа, и будешь отвечать на фразы вырванные из контекста, то этого никто не заметит, и ты таким образом докажешь свою правоту?
Здравствуйте, Gaperton, Вы писали:
G>Хотя, если посмотреть книжку Александреску, в которой он жестко надругался над С++ — то очень даже можно и нужно . Там он демонстрирует, что в compile time при помощи шаблонов можно сделать практически все, что угодно — благодаря наличию рекурсии мы имеем вычислительную полноту. Ничего не напоминает? Мне напоминает макросы лисп . Так что ответ не так однозначен.
Здравствуйте, EvilChild, Вы писали:
EC>Здравствуйте, Gaperton, Вы писали:
G>>Хотя, если посмотреть книжку Александреску, в которой он жестко надругался над С++ — то очень даже можно и нужно . Там он демонстрирует, что в compile time при помощи шаблонов можно сделать практически все, что угодно — благодаря наличию рекурсии мы имеем вычислительную полноту. Ничего не напоминает? Мне напоминает макросы лисп . Так что ответ не так однозначен.
EC>А почему ты считаешь это надругательством?
Я бы так уж совсем-то не называл, но это очень близко, т.к. это уже и не императив, каким C++ по идее являются, и не функциональный язык (ибо до него ещё далеко). Т.е. напоминает забивание гвоздей микроскопом, хотя очень точное забивание
Это моё имхо, но к Александреску я уважительно очень отношусь, ибо мужик уж больно умный, а то что он делает — это уже последствия плюсов