VladD2,
> ПК>Если речь идет о concepts, то совсем не интерфейсы в смысле C++/C#/Java: указать, что данный тип удовлетворяет заданным ограничениям можно при использовании типа, а не при его определении.
> Паш, concepts вводятся в С++ (если конечно вводятся), чтобы уменьшить последствия утиной типизации присутствующей в шаблонах сегодня. Причем средство это не обязательное, и когда все осознают его необходимость баАальшой вопрос.
Это инструмент, нужный для определенных случаев. То, что их больше, не означает, что структурная типизация без ограничений не нужна. Нужно и то, и другое. И совершенно верно вводятся concepts, не запрещая структурной типизации в чистом виде. То чего, к сожалению, сделать уже нельзя, так это изменить выбор по умолчанию.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
AndrewVK,
>>> Нет, не получаем, потому что нет формального контракта, связанного с сигнатурой. Совпадение сигнатуры еще ничего не означает. А если мы такой формальный контракт введем, то получим интерфейсы — вид сбоку.
> ПК> Если речь идет о concepts, то совсем не интерфейсы в смысле C++/C#/Java: указать, что данный тип удовлетворяет заданным ограничениям можно при использовании типа, а не при его определении.
> А казалось бы, при чем тут С++?
При том, что это конкретный язык со статической структурной типизацией вместо сфероконя.
> Нет, речь не о concepts
Тогда, пожалуйста, поясни свою мысль. Я привел concepts как пример формального контракта, связанного с сигнатурой, и указал разницу с интерфейсами, которую ты отрицал в процитированной выше цитате.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
VladD2,
> ПК>Можно пояснить мысль поподробнее относительно того, что ты понимаешь под передачей объекту C++ "непонятного" для него сообщения? > > Наверно нечто вроде: >
> int i = 0;
> double* pd = (double*)&i;
> *pd = 1.3;
>
Что, очевидно, таковым не является, и, более того, запрещено спецификациями языков Си и Си++ (хотя среда исполнения и не обязана детектировать нарушения).
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>При том, что это конкретный язык со статической структурной типизацией вместо сфероконя.
Я говорил о принципах, а не о конкретном языке.
>> Нет, речь не о concepts
ПК>Тогда, пожалуйста, поясни свою мысль. Я привел concepts как пример формального контракта, связанного с сигнатурой, и указал разницу с интерфейсами, которую ты отрицал в процитированной выше цитате.
В той цитате я говорил о конкретном duck typing, описанном Евгением (я так понимаю в реализации Ruby). Что касается concepts, то не готов говорить о них за недостаточным знанием предмета.
... << RSDN@Home 1.2.0 alpha rev. 615 on Windows XP 5.1.2600.131072>>
Здравствуйте, Павел Кузнецов, Вы писали:
>> Согласен. Но здесь мы с AndrewVK говорили, как мне кажется, о среднестатистических командах.
ПК>Средняя температура по больнице?
Угу
Если пытаться продвигать чего-нибудь массовое (или в массы ), то нужно именно на среднюю температуру ориентироваться.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Это инструмент, нужный для определенных случаев. То, что их больше, не означает, что структурная типизация без ограничений не нужна. Нужно и то, и другое. И совершенно верно вводятся concepts, не запрещая структурной типизации в чистом виде. То чего, к сожалению, сделать уже нельзя, так это изменить выбор по умолчанию.
Думаю, ты просто плывешь по течению принимая за правильное складывающееся положение вещей. В общем, я с тобой не согласен. Я считаю, что будь коцепты введены в самом начали и не позволяли бы писать без них, то С++ стал чуточку проще в использовании.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Павел Кузнецов, Вы писали:
>> Наверно нечто вроде: >>
>> int i = 0;
>> double* pd = (double*)&i;
>> *pd = 1.3;
>>
ПК>Что, очевидно, таковым не является, и, более того, запрещено спецификациями языков Си и Си++ (хотя среда исполнения и не обязана детектировать нарушения).
А кто такой "хотя среда исполнения"?
----------------------------------------------------------------
— Дети! Запешите предложине — "В углу сребет мышь.". Все понятно, дети?
— Да, Марья Ивановна... только... ээаа... А кто такой "Вуглускр"?!
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
ПК>>Можно пояснить мысль поподробнее относительно того, что ты понимаешь под передачей объекту C++ "непонятного" для него сообщения?
VD>Наверно нечто вроде: VD>
Почти. Собственно имелось ввиду, взять указатель, привести к void*, а потом откастить к чему-нить не тому. И вот с результатом каста и поработать. Т.е. на низком уровне это будет выглядеть как переходы по несуществующим записям в vtbl и как передача в функции состояний стека и регистров, которые они не ожидают. А если вернуться обратно в текст на C++ и забыть на секунду про vtbl, стек и регистры, то увидим "непонятные" сообщения.
Здравствуйте, VladD2, Вы писали:
VD> [ skipped ]
VD>А может проще дать пользователю библиотеки просто функцию передать в качестве параметра? Будет в принципе тот же traits: VD>
VD>и никаких расширений языка не потребуется. VD>В общем, если интерфейс заранее известен, то просто ползуемся ООП. Если нет, то применяем функциональный подход. В итоге все красиво, быстро и без утиных историй.
По-моему, такой перенос выбора способа позиционирования потока с уровня классов, представляющих поток (File, Socket, Stream, whatever), на уровень отдельных вызовов (функции load_header_and_data) — это совсем даже не просто и не красиво, и вообще выглядит как хак.
не "ничего не делает", а проверяет соответствие аргументов шаблона некоторым требованиям.
VD>Никакой полезной работы он не производит. А ограничения нужно задавать декларативно, а не эмуляцией бурной деятельности.
А это такой вид декларативности.
А вообще, на основе "эмуляции бурной деятельности" основано очень много всего в метапрограммировании С++ (чего стоят хотя бы пресловутое использование sizeof для принятия решений в compile-time). Извращение, конечно, но задачи решает, и довольно часто успешно прячется от нескромных взглядов в глубине библиотек или helper'ов.
Кстати, эти самые проверки constraint'ов по ссылке можно спрятать еще глубже (я заменил constraint'ы на более подходящие для std::sort):
template< class T >
struct sort_concept_test
: constraint::is_random_access_iterator<T>
, constraint::is_less_than_comparable<
std::iterator_traits<T>::value_type> >
{};
Здравствуйте, pvgoran, Вы писали:
P>По-моему, такой перенос выбора способа позиционирования потока с уровня классов, представляющих поток (File, Socket, Stream, whatever), на уровень отдельных вызовов (функции load_header_and_data) — это совсем даже не просто и не красиво, и вообще выглядит как хак.
Твоя задача абстрагировать частный алгоритм от конкретных реализаций потоков. Вот и выполняй ее, а не полагайся на совподение имен методов.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, pvgoran, Вы писали:
P>А это такой вид декларативности.
Императивный? Шутку понял, смешно. (с)
P>А вообще, на основе "эмуляции бурной деятельности" основано очень много всего в метапрограммировании С++ (чего стоят хотя бы пресловутое использование sizeof для принятия решений в compile-time). Извращение, конечно, но задачи решает, и довольно часто успешно прячется от нескромных взглядов в глубине библиотек или helper'ов.
Метапрограммирование в С++ является примером того "как не надо делать". Это пример полного извращенчиства и маразма. И это при том, что есть языки и фрэймворки в которых метапрограммирвоание выглядит очень достойно.
P>Кстати, эти самые проверки constraint'ов по ссылке можно спрятать еще глубже (я заменил constraint'ы на более подходящие для std::sort):
P>
P>template< class T >
P>struct sort_concept_test
P> : constraint::is_random_access_iterator<T>
P> , constraint::is_less_than_comparable<
P> std::iterator_traits<T>::value_type> >
P> {};
P>
P>Так лучше?
Почти идиально. Осталось понять зачем нужны все эти сложности?
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Метапрограммирование в С++ является примером того "как не надо делать". Это пример полного извращенчиства и маразма. И это при том, что есть языки и фрэймворки в которых метапрограммирвоание выглядит очень достойно.
Так-то оно так, да только метапрограммирование в С++ (при всей его корявости) позволяет добавлять новые качества старым C++ программам. А вот переход на новые языки и фреймворки только для более удобного метапрограмирования с портированием туда же сотен тысяч строк отлаженного и работающего кода -- это не меньшее извращенчество. Другое дело -- объединять C++ код с кодом на других языках. Но и здесь есть свои проблемы.
P>>Кстати, эти самые проверки constraint'ов по ссылке можно спрятать еще глубже (я заменил constraint'ы на более подходящие для std::sort):
P>>
P>>template< class T >
P>>struct sort_concept_test
P>> : constraint::is_random_access_iterator<T>
P>> , constraint::is_less_than_comparable<
P>> std::iterator_traits<T>::value_type> >
P>> {};
P>>
P>>Так лучше?
VD>Почти идиально. Осталось понять зачем нужны все эти сложности?
Чтобы не вводить интерфейс IComparable
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, pvgoran, Вы писали:
P>>По-моему, такой перенос выбора способа позиционирования потока с уровня классов, представляющих поток (File, Socket, Stream, whatever), на уровень отдельных вызовов (функции load_header_and_data) — это совсем даже не просто и не красиво, и вообще выглядит как хак.
VD>Твоя задача абстрагировать частный алгоритм от конкретных реализаций потоков. Вот и выполняй ее, а не полагайся на совподение имен методов.
Я разве предлагал использовать для абстрагирования duck typing?? Я всего лишь указал на концептуальный недостаток (который легко может перерасти в недостаток практический) решения, основанного на делегатах.
Кстати, "полагаться на совпадение имен методов" — это таки решение задачи абстрагирования (если не забывать это самое совпадение как-то поддерживать). Хотя лично мне больше нравится C++-ное решение на основе специализации шаблонов.
Здравствуйте, VladD2, Вы писали:
P>>А это такой вид декларативности.
VD>Императивный? Шутку понял, смешно. (с)
Поясняю. Исполняться этот код не будет (так что императивность — это только форма, но никак не содержание), он интересует нас с точки зрения проверки/декларирования поддержки типом определенных операций.
Вот если бы мы говорили "продвинутому" компилятору "проверь, что можно создавать объекты данного типа, присваивать их и т.п." — это была бы императивность.
VD>Метапрограммирование в С++ является примером того "как не надо делать". Это пример полного извращенчиства и маразма.
В определенных областях это, безусловно, верно. Но кое-что получилось довольно удачно.
VD>И это при том, что есть языки и фрэймворки в которых метапрограммирвоание выглядит очень достойно.
Кстати, какие (кроме Lisp-based)?
P>>Кстати, эти самые проверки constraint'ов по ссылке можно спрятать еще глубже (я заменил constraint'ы на более подходящие для std::sort):
P>>[ skipped ]
P>>Так лучше?
VD>Почти идиально. Осталось понять зачем нужны все эти сложности?
Здравствуйте, pvgoran, Вы писали:
P>Я разве предлагал использовать для абстрагирования duck typing??
А зачем ты тогда влез в этот спор? Ведь даже в сабже ясно о чем идет речь.
P>Я всего лишь указал на концептуальный недостаток (который легко может перерасти в недостаток практический) решения, основанного на делегатах.
Я не вижу никакого концептуального недостатка. Я вижу нежелание принимать непривычных подходов.
Функцональное абстрагирование очень удобная вещь во многих случаях. В отличии от утиной типизации — надежный и бытсрый.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, pvgoran, Вы писали:
P>Поясняю. Исполняться этот код не будет (так что императивность — это только форма, но никак не содержание), он интересует нас с точки зрения проверки/декларирования поддержки типом определенных операций.
Будет не будут. Ты указывашь что делать, а не что нужно. Этот способ просто извращенческий. Это как всегда залатывание дыр языка. Надеюсь, что на основании того, что можно извернуться концепты не будут выброшены из нового стандарта.
P>Вот если бы мы говорили "продвинутому" компилятору "проверь, что можно создавать объекты данного типа, присваивать их и т.п." — это была бы императивность.
Ну, "мы" это уже давно говорим. Правда компилятору C# 2.0. И что характерно совершанно декларативно.
VD>>Метапрограммирование в С++ является примером того "как не надо делать". Это пример полного извращенчиства и маразма.
P>В определенных областях это, безусловно, верно. Но кое-что получилось довольно удачно.
Проблема в том, что решение пригодное только "для кое-чего" не является полноценным. И это при том, что есть языки в которых есть полноценные решения.
Внимание, вопрос! Если видно, что пользователи языка используют побочные эффекты для эмуляции метапрограммирования, то почему бы не ввести в язык полноценную его поддержку? Где драть вроде ясно...
P>Кстати, какие (кроме Lisp-based)?
Препроцессор ОКамла. Он пожалуй подходит больше всего, так как сам ОКамл является компилируемым статически типизированным языком. Так же есть еще куча менее подходящих языков вроде Руби и несколько научных исследований прикручивающих похожие возможности к разным языкам (в том числе Яве и Шарпу).
VD>>Почти идиально. Осталось понять зачем нужны все эти сложности?
P>Какие именно сложности?
Ты видел как выглядят констрэйны в C# 2.0? Они просты и понятны. А то что привел ты — это нагромождение кода.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, pvgoran, Вы писали:
P>>Я разве предлагал использовать для абстрагирования duck typing??
VD>А зачем ты тогда влез в этот спор?
С целью критики неудачного с моей точки зрения решения . Правда, критика получилась неконструктивной — я это попытаюсь сейчас исправить.
Когда я писал то сообщение, "для себя" я имел в виду решение задачи абстрагирования в стиле предложенных Зверьком trait'ов — т.е. реализация требуемой для функции load_header_and_data функциональности пропуска байтов выбирается исходя из класса, представляющего поток.
В предложенном Вами решении — передаче делегата при каждом вызове этой функции — присутствует концептуально лишняя конкретность: реализация функциональности пропуска байтов выбирается заново при каждом вызове функции load_header_and_data.
VD>Ведь даже в сабже ясно о чем идет речь.
Вообще-то, то, что предложили Вы, скорее ближе к ФП, чем к ООП (о котором написано в сабже).
P>>Я всего лишь указал на концептуальный недостаток (который легко может перерасти в недостаток практический) решения, основанного на делегатах.
VD>Я не вижу никакого концептуального недостатка.
Я вроде попробовал пояснить...
VD>Я вижу нежелание принимать непривычных подходов. VD>Функцональное абстрагирование очень удобная вещь во многих случаях.
Вне всякого сомнения.
Только в данном случае этот подход IMHO концептуально неоптимальный. Хотя, возможно, в C# (при отсутствии шаблонов C++) реализация "правильного" (с моей точки зрения) подхода получилась бы слишком громоздкой и потому во многих случаях была бы неоправданной.
Здравствуйте, VladD2, Вы писали:
P>>Поясняю. Исполняться этот код не будет (так что императивность — это только форма, но никак не содержание), он интересует нас с точки зрения проверки/декларирования поддержки типом определенных операций.
VD>Будет не будут. Ты указывашь что делать, а не что нужно.
Не будьте формалистом... Я указываю, что нужна поддержка операций. Указанием "что делать" это не является — по крайней мере, с точки зрения программиста.
VD>Этот способ просто извращенческий. Это как всегда залатывание дыр языка.
Вообще-то, если почистить этот код (заменить "костыли" вроде void (*p)(T) = constraint; на нормальный синтаксис), то получится вполне осмысленная и понятная запись. Хотя и не имеющая вида "T поддерживает концепции X, Y и Z".
(С другой стороны, здесь опять — уже на этапе компиляции — всплывает описанная где-то рядом проблема неформальности "утиных интерфейсов". Хотя IMHO и не так остро. В общем, еще есть над чем подумать.)
P>>Вот если бы мы говорили "продвинутому" компилятору "проверь, что можно создавать объекты данного типа, присваивать их и т.п." — это была бы императивность.
VD>Ну, "мы" это уже давно говорим. Правда компилятору C# 2.0.
Не-а. "Вы" говорите "тип должен удовлетворять констрейнту", а не "проверь констрейнт и выдай ошибку при неудаче" — хотя первое и транслируется во второе компилятором.
VD> И что характерно совершанно декларативно.
Ну да. Но я-то про императивные проверки писал.
VD>>>Метапрограммирование в С++ является примером того "как не надо делать". Это пример полного извращенчиства и маразма.
P>>В определенных областях это, безусловно, верно. Но кое-что получилось довольно удачно.
VD>Проблема в том, что решение пригодное только "для кое-чего" не является полноценным.
Во-первых, я писал не про пригодность, а про удачность. Во-вторых, любое решение пригодно только для ограниченного класса задач.
VD>И это при том, что есть языки в которых есть полноценные решения.
VD>Внимание, вопрос! Если видно, что пользователи языка используют побочные эффекты для эмуляции метапрограммирования, то почему бы не ввести в язык полноценную его поддержку? Где драть вроде ясно...
Это вопрос к комитету... Скорее всего, дело в его децентрализованности (для сложных добавлений нужно принимать сложные решения и согласовывать объемные спецификации), недостатке ресурсов и определенной консервативности ("вообще говоря, C++ не про это").
(Кстати, у меня есть некоторые мысли насчет того, что использование этих "побочных эффектов" для МП не так уж и неправильно, но я пока воздержусь их излагать.)
P>>Кстати, какие (кроме Lisp-based)?
VD>Препроцессор ОКамла. Он пожалуй подходит больше всего, так как сам ОКамл является компилируемым статически типизированным языком.
Хм... Помнится, когда я смотрел ОКамл на этот счет, его МП-возможности мне не понравились. Надо будет глянуть еще раз...
P>>Какие именно сложности?
VD>Ты видел как выглядят констрэйны в C# 2.0?
Не видел.
VD> Они просты и понятны. А то что привел ты — это нагромождение кода.
Т.е. сложность в "нагромождении кода" (которое вроде было квалифицировано словами "почти идеально"?), происходящем от отсутствия в языке специального синтаксиса для констрейнтов?.. Если так — то вопрос "зачем" вообще не стоит — без "сложностей" пока просто нельзя.