WH>Здравствуйте, c-smile, Вы писали:
CS>>Вопрос №1: пассаж про new Tuple ... в теле цикла я не понял. WH>Если посмотришь внимательно то это не единственное место к которому можно докопаться. CS>>Зачем думатель это придумал? WH>Главное то что думатель вывел все типы, а то что думатель сделал несколько локальных ляпов так это детская болезнь. Просто у ребят физически не хватает ресурсов для того чтобы сделать оптимизацию таких вещей и по этому их компилятор генерирует код по принципу "что вижу то пою". WH>Уверен что к релизу они эти ляпы исправят.
Не уверен.
В условиях недетерминированного описания (типов в том числе) думатель
будет вынужден "стелить соломку".
Т.е. в принципе чем меньше информации имеет компилятор тем менее оптимальный
код он строит. Более универсальный — да.
VD>>>Получаем краткость скриптов, и мощь компилируемых языков. CS>>Такая компиляция это не мощь. WH>А что же? В программе не указано ни одного типа... тем не мение компилятор сгенерировал строго типизированный код. Если это не мошь тогда что же такое мощь?
Вопросы:
1) Что сделает думатель если увидит скажем такое:
hash[key] = flag? 1: "string";
2) C intellisense как я понимаю такой вывод типов дружить не будет?
Т.к. типы становятся известны только после построения syntax tree всей программы.
И философическая часть:
Зачем в принципе нужен такой выводитель типов?
Какие задачи он призван решить или облегчить их решение?
Какие есть средства "детерминизаци": "я хотел сказать А а думатель придумал Б".
Личное замечание:
Такая недетерминированность в C++ является источником очень неприятных и дурных ошибок.
Один раз очень долго искал в чем проблема. Оказалось в наличии двух конструкторов у
объекта: cls(int n) и cls(bool b). (или что-то подобное — не помню)
Я имел ввиду одно а думатель молча выводил другой тип... Причем разные думатели
(компиляторы) думали по разному.
Re: Философический вопрос про автоматический вывод типов.
Здравствуйте, c-smile, Вы писали:
CS>Личное замечание: CS>Такая недетерминированность в C++ является источником очень неприятных и дурных ошибок. CS>Один раз очень долго искал в чем проблема. Оказалось в наличии двух конструкторов у CS>объекта: cls(int n) и cls(bool b). (или что-то подобное — не помню) CS>Я имел ввиду одно а думатель молча выводил другой тип... Причем разные думатели CS>(компиляторы) думали по разному.
Вот еще один пример "из жизни" (я его, конечно, схематизировал), связанный с этой стороной Си++.
Компилятор спокойно приводит bool к float, как будто так и надо.
#include <stdio.h>
class Float {
float _float;
public:
Float(float x) : _float(x) { }
// следующая строка была закомментирована по ошибке (просто опечатка)
//operator float() { return _float; }
// в реальной программе bool() проверяет отличие Float от нуля
// чтобы обеспечить корректную работу конструкции if (F) ...operator bool() { return (_float != 0); }
};
int main()
{
Float F = 3.1415926536f; // Кто и шутя, и скоро пожелаетъ Пи узнать число, ужъ знаетъ.float x = F;
printf("%f\n", x); // Что напечаталось? Правильно, 1.000000return 0;
}
Но существует одно качество, которое нельзя купить, — это надежность. Цена надежности — погоня за крайней простотой. Это цена, которую очень богатому труднее всего заплатить.
Хоар
Re[2]: Философический вопрос про автоматический вывод типов.
Здравствуйте, AVC, Вы писали:
CS>>Один раз очень долго искал в чем проблема. Оказалось в наличии двух конструкторов у CS>>объекта: cls(int n) и cls(bool b). (или что-то подобное — не помню) CS>>Я имел ввиду одно а думатель молча выводил другой тип... Причем разные думатели CS>>(компиляторы) думали по разному.
AVC>Вот еще один пример "из жизни" (я его, конечно, схематизировал), связанный с этой стороной Си++. AVC>Компилятор спокойно приводит bool к float, как будто так и надо.
Люди, зачем вы валите все с больной головы на здоровую? Вот такой пример не скомпилируется, компилятор найдет обе ошибки:
В Nemerle семантика в данном случае похожа на C#(а может и вообще совпадает). Есть неявное приведение типов, но только для числовых типов(int, float, double, и т.п.) и таких проблемы как в C++ с неявным приведением нет и быть не может. Ни char, ни bool, ни что-либо подобное числовыми типами не считается и подобная ошибка абсолютно исключена(привести к числовым эти типы можно только насильно). Так что это проблема только C/C++.
Re: Философический вопрос про автоматический вывод типов.
Здравствуйте, c-smile, Вы писали:
CS>В условиях недетерминированного описания (типов в том числе) думатель CS>будет вынужден "стелить соломку".
Такий условий нет "бай-дизайн". Любое разночтение интерпретируется как ошибка. "Думатель" делает выводы только если ситуация полностью детерминирована.
CS>Т.е. в принципе чем меньше информации имеет компилятор тем менее оптимальный CS>код он строит. Более универсальный — да.
Так как ситуация всегда детерминирована, то компилятор всегда может оптимальный код. Лиш бы он умел это делать. Так что твои выводы не верны.
CS>Вопросы: CS>1) Что сделает думатель если увидит скажем такое: CS> hash[key] = flag? 1: "string";
Для Нэмерла этот код будет "звучать" так:
hash[key] = if (flag) 1 else"string";
и на него компилятор банально гавкнет:
expected int-, got string in computation branch: common super type of types [int, string] is a set of interfaces
то есть, просто не даст так сделать.
CS>2) C intellisense как я понимаю такой вывод типов дружить не будет?
А какая разница то кому делать вывод типов? Будет такой же вывод делать парсер интелисенса.
В первй строке он конечно ничего умного не предложит. Но в следующих уже предложет.
К тому же всегда можно задать тип при его создании. Только в отличии от большинства других языков однин раз.
def hash = Hashtable<string, int>();
а не
Hashtable<string, int> hash = Hashtable<string, int>();
как это сейчас происходит в С++ и C#.
CS> Т.к. типы становятся известны только после построения syntax tree всей программы.
Они приципиально до этого не доступны. Любой интелисенст парсет все файлы проекта и крайне плохо относится к наличию ошибок в них.
Собственно пока типы ключей и значений имеют которкие имена, то замусоривания не так видно. Но когда это длинные типы темблее сами содержащие длиннющие параметры типов, то выходит довольно ужасно выглядящий код. Например, объявление той же хэш-таблицы может переноситься на две строки, чтобы влезнь в правила форматирования заставляющие переносить строки по 80 символов. C#:
Dictionady<MyFirstClassWithLongName<List<MySecondClassWithLongName>>, List<MySecondClassWithLongName>> dic =
new Dictionady<MyFirstClassWithLongName<List<MySecondClassWithLongName>>, List<MySecondClassWithLongName>>();
dic.Add(var1, var2);
C++:
Dictionady<MyFirstClassWithLongName<List<MySecondClassWithLongName^>>^, List<MySecondClassWithLongName^>>^ dic^ =
new Dictionady<MyFirstClassWithLongName<List<MySecondClassWithLongName^>>^, List<MySecondClassWithLongName^>>^ ();
dic->Add(var1, var2);
Nemerle:
def dic = Dictionady();
dic.Add(var1, var2);
CS>И философическая часть:
CS>Зачем в принципе нужен такой выводитель типов?
Чтобы писать такой же краткий код как на динамически типизрованных языках, но при этом иметь все приемущества статически типизированных, в том числе быстрый код и интелисенс.
CS>Какие задачи он призван решить или облегчить их решение?
Очистить код от лишних конструкций сделав его более кратким и понятным. При этом как бы не запрещается описывать типы более часто.
Это как бы развитие идеии которую пытаются протлкнуть в следующую версию С++ (ключевое слово auto).
Собственно приведенный пример скорее демонстрация ума компилятора. Рельно же приемущество получается когда начинашь описывать вложенные методы. Например, я даже не знаю как типизированно описать следующую конструкцию:
А так спокойно описал. И выглядит кратко.
CS>Какие есть средства "детерминизаци": "я хотел сказать А а думатель придумал Б".
Компилятор ничего не выдувывает. Это ты думатель. А он дететриминованный конечный автомат.
Ты можешь помочь ему задв тип при объявлении переменой, а можешь положиться на его "разумность".
CS>Личное замечание: CS>Такая недетерминированность в C++ является источником очень неприятных и дурных ошибок.
В Нэмерле нет недетерминированностей. Точнее если и есть, то по шибке. Авторы их не планировали.
А С++ спроектирован так... Короче о нем просто не хочу говорить.
CS>Один раз очень долго искал в чем проблема. Оказалось в наличии двух конструкторов у CS>объекта: cls(int n) и cls(bool b). (или что-то подобное — не помню) CS>Я имел ввиду одно а думатель молча выводил другой тип... Причем разные думатели CS>(компиляторы) думали по разному.
Не пишите на дурно спроектированных языках и не будете искать шибки очень долго.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Философический вопрос про автоматический вывод типов.
Думаю твой пример на этом: AVC>Вот еще один пример "из жизни" (я его, конечно, схематизировал), связанный с этой стороной Си++.
можно было бы и закончить.
К тому же ты сам усугубил свою проблему создав неявное приведение к bool.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Философический вопрос про автоматический вывод типов.
typedef Dictionady<MyFirstClassWithLongName<List<MySecondClassWithLongName^>>^, List<MySecondClassWithLongName^>>^ MyDictionaryPtr;
...
MyDictionaryPtr dic^ = new MyDictionaryPtr;
VD>Собственно приведенный пример скорее демонстрация ума компилятора. Рельно же приемущество получается когда начинашь описывать вложенные методы. Например, я даже не знаю как типизированно описать следующую конструкцию: VD>
После программирования с RubyOnRails я думаю, что это не есть хорошо. Там так же классы-модели возвращают какие-то объекты, которые затем используются формами для отображения информации. И очень скоро без явного декларирования типов возвращаемых объектов напрочь забываешь, что окуда возвращается и как с этим можно работать. А уж поддерживать целостность всего этого дела можно только за счет обилия unit-тестов. Приведенный тобой пример очень похож на эту ситуацию.
VD>Не пишите на дурно спроектированных языках и не будете искать шибки очень долго.
Ага, а пока появятся хорошо спроектированные языки не программируйте ничего.
И совсем уж философский вопрос: неужели за все время развития программирования еще не было создано ни одного нормально спроектированного языка?
И что заставляет думать, что через некоторое время кажущийся нормально спроектированным язык не окажется объявленным дурно спроектированным?
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re: Философический вопрос про автоматический вывод типов.
Disclaimer: Nemerle знаю только на основе предыдущих постов, сказанное ниже оносится скорее к O`Caml. Думаю, это не будет оффтопиком, так как проблема обсуждается с глобальной точки зрения
CS>Не уверен. CS>В условиях недетерминированного описания (типов в том числе) думатель CS>будет вынужден "стелить соломку". CS>Т.е. в принципе чем меньше информации имеет компилятор тем менее оптимальный CS>код он строит. Более универсальный — да.
В том-то и дело, что компилятор выводит недостающую информацию. Например, он может вывести что ты кладешь в массив только числа и сгенерировать код работы с массивом, оптимизированный под работу с числами. В то же время в Java ты вынужден либо писать свою специализацию, либо терять производительность на боксинге.
Вообще, почитай про реконструкцию типов (например, алгоритм унификации типов Хиндли-Милнера). TAPL.
CS>Вопросы: CS>1) Что сделает думатель если увидит скажем такое: CS> hash[key] = flag? 1: "string";
В O`Caml алгоритм унификации (выведения типов) выдаст ошибку.
CS>2) C intellisense как я понимаю такой вывод типов дружить не будет? CS> Т.к. типы становятся известны только после построения syntax tree всей программы.
Во-первых, необязательно всей. Незнаю как в Nemerle, но в O'Caml можно давать явные аннотации типов. Во-вторых, IntelliSense может подсказывать те конструкции при введении которых алгоритм унификации выдает не пустое множество решений (т.е унификация типов возможна).
CS>И философическая часть:
CS>Зачем в принципе нужен такой выводитель типов? CS>Какие задачи он призван решить или облегчить их решение?
Проще писать программу (можно не задумываться о типах там, где это не нужно), компактнее код.
CS>Какие есть средства "детерминизаци": "я хотел сказать А а думатель придумал Б".
Аннотации типов, естественно. Где типы важны для тебя — ставишь аннотации. Где не важны — не ставишь и, соответственно, не ошибаешься в указании типа
CS>Личное замечание: CS>Такая недетерминированность в C++ является источником очень неприятных и дурных ошибок. CS>Один раз очень долго искал в чем проблема. Оказалось в наличии двух конструкторов у CS>объекта: cls(int n) и cls(bool b). (или что-то подобное — не помню) CS>Я имел ввиду одно а думатель молча выводил другой тип... Причем разные думатели CS>(компиляторы) думали по разному.
Во-первых, это немного другое. В твоем случае это больной subtyping и ad-hoc полиморфизм (aka overloading), насколько я понимаю. Но тоже имеет отношение к системе типов, а потому отслыаю опять к TAPL. Кстати, вот [http://lambda-the-ultimate.org/node/1113#comment-12147]тут[/url] (первое, что нашел в Google) есть мысль по этому поводу.
А во-вторых, вывод типов полностью детерминирован (это было бы странно, если бы он работал пользуясь "догадками" и "эвристиками", хотя не буду утверждать, что такого не бывает ). Открыв книгу, указанную выше, ты можешь найти описание алгоритма для ML-like языка.
Re[2]: Философический вопрос про автоматический вывод типов.
VD>expected int-, got string in computation branch: common super type of types [int, string] is a set of interfaces
VD>
VD>то есть, просто не даст так сделать.
Спасибо. Это я понял.
CS>>2) C intellisense как я понимаю такой вывод типов дружить не будет?
VD>А какая разница то кому делать вывод типов? Будет такой же вывод делать парсер интелисенса. VD>В первй строке он конечно ничего умного не предложит. Но в следующих уже предложет. VD>К тому же всегда можно задать тип при его создании. Только в отличии от большинства других языков однин раз. VD>
VD>def hash = Hashtable<string, int>();
VD>
VD>а не VD>Hashtable<string, int> hash = Hashtable<string, int>(); VD>как это сейчас происходит в С++ и C#.
Я не вижу принципиальной разницы в написании
Hashtable<string, int>() hash;
и
def hash = Hashtable<string, int>();
CS>> Т.к. типы становятся известны только после построения syntax tree всей программы.
VD>Они приципиально до этого не доступны. Любой интелисенст парсет все файлы проекта и крайне плохо относится к наличию ошибок в них.
Это очень дорогая операция парсить все файлы. Это не для GUI.
VD>Собственно пока типы ключей и значений имеют которкие имена, то замусоривания не так видно. Но когда это длинные типы темблее сами содержащие длиннющие параметры типов, то выходит довольно ужасно выглядящий код. Например, объявление той же хэш-таблицы может переноситься на две строки, чтобы влезнь в правила форматирования заставляющие переносить строки по 80 символов. C#: VD>
Несколько надуманный пример, имхо. Честно говоря такого безобразия я в своей практике не встречал.
Может из-за того что я ни stl ни boost не использую в быту?
CS>>И философическая часть:
CS>>Зачем в принципе нужен такой выводитель типов?
VD>Чтобы писать такой же краткий код как на динамически типизрованных языках, но при этом иметь все приемущества статически типизированных, в том числе быстрый код и интелисенс.
Еще раз с интеллисенсом не все так хорошо как ты написал. Запуск полномасштабного парсера (даже без кодогенерации)
на каждый введенный nmtoken это нереально.
На таких принципах можно и для скриптов intellisense строить. Что
кстати и сделано в VS. Там это правда работает для сугубо простых случаев.
CS>>Какие задачи он призван решить или облегчить их решение?
VD>Очистить код от лишних конструкций сделав его более кратким и понятным. При этом как бы не запрещается описывать типы более часто.
VD>Это как бы развитие идеии которую пытаются протлкнуть в следующую версию С++ (ключевое слово auto).
В принципе мотивация понятна.
Я просто думал что это решает некие принципиальные вещи.
Лично для меня явно определить тип всегда лучше — лишний checkpoint
который отлавливается в compiletime и сразу, а не в runtime.
Кстати Вальтер добавил в D auto т.е. такое вот работает:
auto i = 2+2;
Пока случая не представилось воспользоваться.
Re[3]: Философический вопрос про автоматический вывод типов.
Здравствуйте, eao197, Вы писали:
VD>>Не пишите на дурно спроектированных языках и не будете искать шибки очень долго.
E>Ага, а пока появятся хорошо спроектированные языки не программируйте ничего. E>И совсем уж философский вопрос: неужели за все время развития программирования еще не было создано ни одного нормально спроектированного языка? E>И что заставляет думать, что через некоторое время кажущийся нормально спроектированным язык не окажется объявленным дурно спроектированным?
Наблюдая плавное переливание Влада из C# в N# я тоже задаюсь этим вопросом.
И вообще нет идеальных языков для всего и вся.
Re[2]: Философический вопрос про автоматический вывод типов.
Здравствуйте, WFrag, Вы писали:
WF>Здравствуйте, c-smile, Вы писали:
WF>Disclaimer: Nemerle знаю только на основе предыдущих постов, сказанное ниже оносится скорее к O`Caml. Думаю, это не будет оффтопиком, так как проблема обсуждается с глобальной точки зрения
CS>>Не уверен. CS>>В условиях недетерминированного описания (типов в том числе) думатель CS>>будет вынужден "стелить соломку". CS>>Т.е. в принципе чем меньше информации имеет компилятор тем менее оптимальный CS>>код он строит. Более универсальный — да.
WF>В том-то и дело, что компилятор выводит недостающую информацию. Например, он может вывести что ты кладешь в массив только числа и сгенерировать код работы с массивом, оптимизированный под работу с числами. В то же время в Java ты вынужден либо писать свою специализацию, либо терять производительность на боксинге.
Еще раз мне представляется проблема несколько надуманной.
На Java я пишу немного в последнее время. А в C++ автоматический вывод типов
я из своей практики исключил. И лучше бы его там не было вообще.
WF>Вообще, почитай про реконструкцию типов (например, алгоритм унификации типов Хиндли-Милнера). TAPL.
Ага, спасибо. Но в другой жизни уже. В этой я чукча — писатель.
CS>>Вопросы: CS>>1) Что сделает думатель если увидит скажем такое: CS>> hash[key] = flag? 1: "string";
WF>В O`Caml алгоритм унификации (выведения типов) выдаст ошибку.
Почему? А если я так хочу и согласен на boxing например или на какой-нибудь variant?
CS>>2) C intellisense как я понимаю такой вывод типов дружить не будет? CS>> Т.к. типы становятся известны только после построения syntax tree всей программы.
WF>Во-первых, необязательно всей. Незнаю как в Nemerle, но в O'Caml можно давать явные аннотации типов. Во-вторых, IntelliSense может подсказывать те конструкции при введении которых алгоритм унификации выдает не пустое множество решений (т.е унификация типов возможна).
Проблема intellisense тут давеча обсуждалась а приложении к SELECT ... FROM.
Это оно как мне кажется, нет?
CS>>И философическая часть:
CS>>Зачем в принципе нужен такой выводитель типов? CS>>Какие задачи он призван решить или облегчить их решение?
WF>Проще писать программу (можно не задумываться о типах там, где это не нужно), компактнее код.
CS>>Какие есть средства "детерминизаци": "я хотел сказать А а думатель придумал Б".
WF>Аннотации типов, естественно. Где типы важны для тебя — ставишь аннотации. Где не важны — не ставишь и, соответственно, не ошибаешься в указании типа
"не ошибаешься в указании типа". Если я ошибусь мне компайлер скажет.
А в твоем случае скажет unittest. Который еще писать надо.
Но это так. Еще раз — мотивацию понимаю. Просто думал что это что-то принципиально новое позволяет делать...
Re[3]: Философический вопрос про автоматический вывод типов.
Здравствуйте, c-smile, Вы писали:
CS>Еще раз мне представляется проблема несколько надуманной. CS>На Java я пишу немного в последнее время. А в C++ автоматический вывод типов CS>я из своей практики исключил. И лучше бы его там не было вообще.
Интересно, как можно говорить о некоторой возможности если ты даже с ней не работал (впечатление такое сложилось)?
WF>>Вообще, почитай про реконструкцию типов (например, алгоритм унификации типов Хиндли-Милнера). TAPL.
CS>Ага, спасибо. Но в другой жизни уже. В этой я чукча — писатель.
..и даже не хочешь узнать, что это за фича и как она работает.
WF>>В O`Caml алгоритм унификации (выведения типов) выдаст ошибку.
CS>Почему? А если я так хочу и согласен на boxing например или на какой-нибудь variant?
В O`Caml disjoint union-ов нет. Но ничто не мешает использовать в данном случае joint union.
Если под "боксингом" ты имеешь ввиду полиморфизм (т.е когда в массиве хранится некий Object или т.н "Top"), то ситуация такая. (далее идут мои, возможно ошибочные, размышления). Вообще говоря, можно ввести тип Top, однако в силу статичности O`Caml его смысл несколько теряется (т.к ты все равно с этим типом потом ничего осмысленного не сделаешь).
CS>Проблема intellisense тут давеча обсуждалась а приложении к SELECT ... FROM. CS>Это оно как мне кажется, нет?
Не знаю, это все теоретические размышления. На самом деле нормальной подсказки для ML языков я действительно не видел (правда, особенно и не искал ). Может это и будет проблемой, может и нет.
WF>>Аннотации типов, естественно. Где типы важны для тебя — ставишь аннотации. Где не важны — не ставишь и, соответственно, не ошибаешься в указании типа
CS>"не ошибаешься в указании типа". Если я ошибусь мне компайлер скажет. CS>А в твоем случае скажет unittest. Который еще писать надо.
Нет. Тип выведется. И в худщем варианте, выведется более общий тип, чем ты указал бы.
CS>Но это так. Еще раз — мотивацию понимаю. Просто думал что это что-то принципиально новое позволяет делать...
Да, позволяет. Работать с очень сложными типами. Пример — монады (а еще лучше Arrows Хаскелля ). Посмотрел бы я на того маньяка, кто захочет везде явно типы указывать Ты указываешь типы для граничных случаев (там где ввод/вывод, например), а все остальные внутренние сложные типы выводятся автоматически.
Re[3]: Философический вопрос про автоматический вывод типов.
CS>Это очень дорогая операция парсить все файлы. Это не для GUI.
Ты видел resharper? Он не только парсит файлы, он производит куда более сложный анализ. Парсить файлы — единственный способ для нормального рефакторинга/intellisense. В Nemerle поддержка редакторов предпологается вообще с помощью встраивания компилятора(естественно не все его стадии, только парсинг и построение AST). Собственно какую-то раннюю версию этой библиотеки я видел в исходниках компилятора. Проблема со скоростью — не проблема на hi-end машинах(например vs2005 на других и работать толком не будет). Потом Nemerle и аналогичные языки рассчитаны на достаточно далекую перспективу, а закон Мура еще никто не отменял.
CS>Еще раз с интеллисенсом не все так хорошо как ты написал. Запуск полномасштабного парсера (даже без кодогенерации) CS>на каждый введенный nmtoken это нереально.
Это вполне реально и работает.
CS>Лично для меня явно определить тип всегда лучше — лишний checkpoint CS>который отлавливается в compiletime и сразу, а не в runtime.
Никто не говорит, что этого делать нельзя. Более того даже в Nemerle это иногда делать необходимо. Но если этого не делать в тех случаях, когда это можно, то ошибки всплывут именно в compiletime, а не в runtime. И я не видел еще ни одного случая, когда бы это было не так.
Re[3]: Философический вопрос про автоматический вывод типов.
Нет. Как и using. Но это тот же лишний код. Зачем он если без него очень даже неплохо получается?
E>После программирования с RubyOnRails я думаю, что это не есть хорошо.
Я тебе уже не раз говорил, что Руби хотя вещь и красивая, но далекая от совершенства. Не нужно по ней судить о других языках.
E> Там так же классы-модели возвращают какие-то объекты, которые затем используются формами для отображения информации. И очень скоро без явного декларирования типов возвращаемых объектов напрочь забываешь, что окуда возвращается и как с этим можно работать. А уж поддерживать целостность всего этого дела можно только за счет обилия unit-тестов. Приведенный тобой пример очень похож на эту ситуацию.
Хм. Нэмерл выводит типы. Это всеравно что вписывать их явно. Так что ошибок быть не может. Язык статически типизированный!
Когда я тебе говорил о том, что проблема Руби отсутствие статической типизации ты мне все время возражал и говрил, что все ОК, плюс есть юнит-тесты и т.п. Сейчас же сам себе возражаешь.
Сдается мне, что ты пытайся отстоять свое даже вопреки здравой логике.
Так вот схожесть Руби и Нэмерла ты правильно подметил. На обоих языках можно писать максимально кратко. Но ты упорно не хочешь понять, что отсутствие деклараций типов в этих языках достигается разными средствами. В Нэмерле — умом компилятора, а в Руби динамической типизацией.
VD>>Не пишите на дурно спроектированных языках и не будете искать шибки очень долго.
E>Ага, а пока появятся хорошо спроектированные языки не программируйте ничего.
Яве уже сто лет. C# 4. Так что самое время возиться с С++ и Руби. Их тандем позволяет сделть систему и запутаннее, и медленнее, и бажливее. Шучу конечно, но в каждой шутке...
E>И совсем уж философский вопрос: неужели за все время развития программирования еще не было создано ни одного нормально спроектированного языка?
Почти все новые языки лучше своих прототипов. С++ несравненно лучше С. C# ле... в общемя, ф промолчу.
Лучше скажу, что сейчас новые языки пытаются стать лучше чем свои предшественники и рано или поздно у кого-то это получится.
Бывает, конечно, что новый язык впитывает кучу проблем и становится хуже прототипов. Но бывает же и наоборот.
Нэмерл впитал в себя:
1. Антиграблевость и простоту применения C#.
2. Заимствовал лучшие вещи из синтаксиса С, Паскаля, C#, Питона и других.
3. Идеи функционального подхода из ML-клонов.
4. Макросы из клонов Лиспа.
Он поддерживает все известные мне парадигмы программирования. Причем делает это не случайно как С++ и не ограничено как многие языки, а намеренно и от того вроде как полно и не противоречиво.
На нем можно писать в функциональном стиле не хуже чем на МЛ. Он поддерживает и линивость, и одновременно yeld в чтиле Руби/Питона/Шарпа. Он намеренно поддерживает метапрограммирование. Причем делает это великолепно. Фнуциональные возможности упрощают создание макросов, а от того делают их применение доступнее для людей. Код в императивном стиле на нем мало отличим от такого же кода на C# только выглядит более кратно и если что нет проблем воспользоваться любой другой парадигмой.
Забавно, но когда я описывал, здесь неподалеку, то, что я хотел бы включить в C#, то описал большинство того, что уже есть в Нэмерле.
E>И что заставляет думать, что через некоторое время кажущийся нормально спроектированным язык не окажется объявленным дурно спроектированным?
А ничего и не заставляет. Когда я познакомился с С, я вообще ничего другого не видел, но по словам отца — это был самый современный и развитой язык на тот момент. Когда я задолбался тужится писать ОО-код на С и познакомился с С++ я был в щенячьем восторге от того как логично и красиво в нем реализован ООП! Шаблоны в те времена были еще далекти от того чем они стали сейчас. Мне они были не нужны. Но я все равно радовался как ребенок (возможно, потому что тогда я действительно был тогда почти ребенком и гомонов было через край) от раскрывшихся возможностей и невиданной мной до этого простотой.
Потом я радовался новым версиям С++ с шаблонами и вновь появившейся простоте. Тогда я еще не в силах был понять всю ущербность дизайна С++, а о многих концепциях вообще не знал.
Потом я радовался, изучая КОМ, так как получил в свои руки небывалую мощь компонетных технологий!
Далее я радовался, изучая Васик и Дельфи. Их компонентные модели были очень и очень впечатляющие. А визуальные дизайнеры форм в купе с компонентным подходом ускоряли создание ГУИ на порядки. Я вспоминал как недели убивал на приличный оконный интерфейс на С и с удовольствием наблюдал как намного более мощный интерфейс лепится из компонентов прямо на глазах.
Потом я примерно с твоим скепсисом наблюдал за появлением Явы. Я произвел пару тестов и выяснил, что скорость получаемого кода в десятки раз меньше чем у аналогичного на С++. Я не заметил в Яве мощной компонентной модели и заметил, что то на что ее нацеливают (создание апплетов для Web-а) не входит в круг моих интересов. Так я проморгал первую интересную вещь.
Я делал КОМ-компоненты на С++ и использовал их из Васика получая тем самым преимущества от гибкости С++ и скорости разработки Васика. Подспудно я понимал, что Дельфи в некотором роде является комплексной альтернативой, но количество багов в Дельфи, откровенно слабые библиотеки не связанные с ГУИ, и отсутствие некоторых вкусностей С++ заставили меня выбрать связку С++/Васик.
Далее я наблюдал за дотнетом. В дотнете я обнаружил C# который позволил мне делать все то что я раньше мог делать только на связке С++/Васик/КОМ на одном языке получая при этом куда более простые и безопасные решения. Дотнет и Шарп дали мне еще один повод для радости. Код на Шарпе был реально проще, а значит я смог делать куда больше за то же время.
Ранее я очень страдал, что даже самая крутая хреновина улучшающая комплит в VC++ 6,0 (забыл как ее помню только что фирма была про помидоры "Тамата") постоянно ошибалась на шаблонах С++ и не давала писать дефствительно быстро. Этих проблем не было на Васике, где комплит работает почти изумительно, но гибкость и производительность Васика была ниже плинтуса. В Шарпе же комплит стал еще круче чем в Васик, а язык очень даже сопоставим по гибкости с любимыми до этого плюсами. Вроде бы по отдельности все что было в Шарпе и дотнете я мог получить и ранее, но вместе этого не было нигде.
Так же стоит отметить и библиотеки. 80, если не больше, процентов времени работы на С++ мы уделяли разработке собственных библиотек. С Интернетом тогда было хреново, Буста еще не было, про разные Асе или КуТи мы просто не слышали. Все приходилось делать с нуля. Опыт применения чужого кода оказался горьким, так как в нем были баги, чужие баги связанные с нарушением типобезопасности искать в С++ ой как не просто. В общем, мы быстро приняли для сбея правило — все что используется должно быть написано нами и лежать в исходном коде! Так вот на Шарпе я впервые ощутил, что есть огромная полезная библиотека код которой не страшно использовать. Так же оказалось, что чужой код написанный на Шарпе не так страшно применять в своем коде. Ведь в нем невозможны ошибки связанные с типами и почти все грабли С++, а логические ошибки довольно легко обнаруживаются и устраняются или обходятся во время эксплуатации.
Еще одним достоинством, которое я не смог оценить сразу, но оценил потом было то, что дотнетные библиотеки легко декомпилировались. Сначало Анакрино, а потом и Рефлектор открыли для меня одну важную мысль. Отлаживаться имея возможность быстро найти код используемых библиотек — это очень большое преимущество. Используя С++ я не мог заглянуть в кишки КОМ-а и мы море времени проводили из-за того, что не верно поняли документацию, или в следствии того, что в недоступном коде был баг, а возможно просто что-то прощелкали, мы тратили тоже не мало времени. Теперь же, когда у меня в руках Рефлектор, я быстро могу найти нужный мне библиотечный метод и поглядеть его логику. Сделав это я могу понять в чем я был не прав или найти ошибку в чужом коде. Только недавно нашел ошибку в обертке над ListView. Я очень долго бы просидел над ее поиском если бы я не смог поглядеть ее код. Тут же, я быстро ее обнаружил, и смог понять, как ее легко обойти. На С++ даже имея исходники я не мог так быстро найти нужные мне места, а так как в большинстве случаев и исходников небыло, то был вообще каюк. Я конечно знаю, что сейчас есть разные Доксигены, но тогда их не было! Да и без исходников обходится.
ФЯ пожалуй первая вещь которую я оценил теоретически. Оказалось, что я и раньше частенько писал в ФЯ стиле на ИЯ даже не догадываясь об этом. Откровенно говоря, рассказы о том, что большинство ошибок в программах из-за модифицирующего присвоения меня не вдохновили. Ну, нет у меня в программах таких ошибок. Или почти нет. Но может быть я опять просто не оценил очередной виток облегчения. А вот декларативность записи я оценил. Я заметил, что декларативность можно достигать из без применения ФЯ и она всегда дает хороший результат. Забавно оказалось и то, что любимый мною SQL оказался тоже вроде как разновидностью ФЯ. По крайней мере, он был точно декларативным языком и видимо по этому он мне так нравился.
С SQL я тоже познакомился забавнейшим образом. Обучаясь программировать на С/С++ я быстро понял, что для решения стоящих передо мной задач мне нужно нечто обеспечивающее простую манипуляцию данными. Причем так чтобы этих могло быть много. В общем, мне была нужна СУБД. То что это называется БД, мен сказали добрые люди. Один знакомый отца дал мне библиотеку позволяющую манипулировать БД типа DBASE на С/С++ (вроде называлась CODBASE). Я довольно быстро научился вытягивать данные табличек, но как вынуть только их нужную часть, да еще и отсортированную нужным образом сразу не просек. После долгого копания я понял, что нужно использовать странные сущности вроде индексов и т.п. Короче нужно делать кучу работы о которой я не подозревал и которая по большому счету мне и на фиг не уперлась.
Я забросил эту идея и впервые решил, что нужно сделать свой велосипед. Такой движок, чтобы не нужно было делать лишних телодвижений для управления данными. Быстро поняв, что задача сложная, а мне нужно пока что куда менее универсальное решение я обошелся просто файлами.
Через некоторое время я познакомился с ребятами из маленькой конторы которые рассказали мне про то что есть такие штуки как SQL и SQL-серверы. А так же относительно дешевый SQL-сервер Gupta SqlBase и невероятное, по тем временам, визульаное средство SqlWindows. Это было время кода Васика или вообще небыл, или был Васик 1.0 настолько убогий, что с SqlWindows он никак не мог сравниться. Чуть спустя появилась NT и Эксес. Я быстро осознал, что будущее за серверами приложений, SQL-лем и средствами быстрой разработки вроде SqlWindows. Кстати, Дельфи появилась точно позже.
В общем, я чуть отвлекся... Познакомившись с ФЯ я обнаружил, что в них, таких не понятных и таких непривычных есть нечто привлекательное. Они действительно обладают чертами декларативности и код на них может быть значительно более кратким чем привычный мне императивный. Но та неинтуитивнасть которая присутствовала в функциональных примерах, дурацкая манера разворачивать смысл программы по сравнению с естественными языками и совершенно дурацкая манера называть переменные и функции так чтобы никто не догадался (с) операция "Ы", сильно смущали меня.
Так же смущало меня и то, что ФЯ пропагонидируют стиль явно не дружащий с высокой производительность. А та фанатичность с которой апологеты ФЯ борются против любых проявлений "императивщины" и так кривизна появляющаяся когда на традиционных ФЯ начинают писать в императивном стиле сильно смутили меня.
Но главное я осознал — это то, что и ФЯ есть рациональное зерно. А еще "более главное" , то что за декларативностью будущее! Пусть полный отказ от императивных конструкций — это утопия. И пусть пока еще нет ФЯ который я счел бы удобным для сбея, но в этом что-то есть!
Кстати, больше всего меня смущало в ФЯ, то что их принципы входят в противоречие с принципами ООП. А ООП я и сейчас считаю одним из самых мощных инструментов для решения сложных задач. Не, ну, правда, как идея о том, что "модификация состояния — это зло", может сочетаться с идеей, что "объекты имеют свое состояние модифицируемое посредством методов"? Слова вроде "так при модификации могут порождаться новые объекты" выглядят совсем не убедительно. Однако я же не фанатик ФЯ? Так почему я должен принимать идею о том, что модификация состояния — это зло? Темболее, что декларативность достигаемая в ФЯ отнюдь не заключена в немодифицируемости. Она скорее в другом. Она в том, что функции являются первоклассными сущностями, и в том, что с их помощью можно делать гибкую функциональную декомпозицию. В общем, функциональный взгляд на мир дает еще одно измерение.
Если подумать, то чем так хвастаются апологеты ФЯ:
1. Функции как первоклассные сущности.
2. Списки как первоклассные сущности (иными словами упрощенная работа со списками).
3. Использование рекурсии в программах.
4. Сопоставление с образцом.
5. Метапрограммирование.
Ничего не забыл?
Не являются по существу атрибутами ФЯ или функционального подхода в целом. Возможно они родились в среде ФЯ и красиво интегрированы в ФЯ, но это всего лишь стечение обстоятельств!
Так что без проблем можно создать гибридный подход позволяющий выбирать парадигму требуемую для решения текущей задачи.
Так вот Скала и Нэмерл ближе всех подошли к тому, что мне кажется перспективным на сегодня.
И пусть, не многие еще могут понять мощь которую несут эти языки. Пусть на их пути стоят такие непреодолимые препоны как:
1. Фанатизм приверженцев тех или иных имеющихся технологий.
2. Закостенелость мышления большинства.
3. Приверженность людей к своим привычкам. (О сколько раз я наблюдал, как люди понимают, что печатать методом слепой десятипальцовой печати намного эффективнее, но по тыркавшись бросающих попытки научиться ему).
4. Мощь гигантов индустрии вроде MS, Sun или IBM не до конца осознавших куда нужно двигаться. Причем, похоже, что они осознают куда нужно двигаться, но боятся, что факторы идущие в этом списке выше приведут их усилия в тупик.
Но движение в нужном направлении видно. Гиганты индустрии во всю развивают декларативные подходы. Они встраивают в свои модерновые языки декларативные конструкции (C# 1/2, Ява 1.5). Они поддерживают исследования в области ЯП. Они занимаются визуальными дизайнерами и ищут пути внедрения DSL-подхода в реальную жизнь. В общем, они двигаются вперед. Хотя, возможно, и не так быстро как хотелось бы.
Что же касается до того что в будущем могут появиться подходы, которые мы пока не видим, или в которых мы пока не уловили конструктивного зерна, так я этого не боюсь. Собственно для этого я и рассказывал все вышесказанное. Это будет всего лишь следующий шаг. Я только "за" новые шаги. И чем более радикально этот шаг упростит нашу жизнь, тем лучше.
Чудесь не бывает. Это я понял еще в жизни. И если кто-то сильно что-то хвалит не объясняя на чем базируются эти преимущества, то скорее всего это фигня. Из этого же правила следует и то, что супер-панацей нет. А есть только грамотный баланс. Так что моя задача сопоставить плюсы с минусами и выбрать то у чего этот самый баланс близок к оптимальному для меня.
ЗЫ
Многие считают меня фанатиком. Но они ошибаются. Я в каком-то смысле продажная шкура. Если я вижу что-то по совокупности характеристик лучшее чем то что мне нравилось до этого, то я легко бросаю старую игрушку и беру лучшее. Просто не так много вещей в мире которые действительно кумулятивно (по совокупности) лучше чем то, во что я играюсь сегодня. Возможно мне просто плохо объясняли, а возможно я просто не столь дальновидный. Но мне кажется дело все же не во мне. Я конечно люблю поспорить и увлекшись могу начать отстаивать и не верную позицию. Но выслушав аргументы и остыв я все же (по крайней мере хочется в это верить) способен оценить их и принять решение на основании логики, а не собственной вредности.
На сегодня я вижу перспективу за компонентными управляемыми средами вроде дотнета и Явы. За типобезопасностью, статической типизацией, декларативностью, метапрограммированием, и многим другим. И из всего что я вижу Нэмерле и Скала являются самыми перспективными вещами. Но я уже очень давно подсел на иглу под названием хорошая IDE (под которыми на сегодня я понимаю только два продукта VS, причем только 2005 или 2003 + ReSharper) и IDEA. Остальное не стоит даже обсуждения. Чуть-чуть сюда приблизился Эклипс. Но по многим характеристикам он уступает. В общем, без хорошей IDE моя производительность на C# значительно выше чем на супер пупер Нэмерле. Но я почти уверен, что со временем или C# впитает в себя все преимущества Нэмерла, или Нэмерле обзаведется поддержкой мощной IDE (для начала хватило бы хорошего комплита). Ну, или появится нечто лучше чем Шарп и Нэмерл вместе взятое обладающее офигительной IDE, а возможно и тем самым "чем-то новым о чем мы еще не знаем" и вот именно это и станет моим фаворитом на некоторое время.
А потом (если буду жив) я снова буду сидеть в форуме и бороться с закостенелыми фанатами устаревших технологий вроде C# 5.0 и Нэмерле 3.0 и они мне будут говорить, что я фанатик и вообще несдержанный идиот. Главное не влиться в стройные ряды рядов совсем экзотических извращений или в ряды старперов по духу защищающих пережитки прошлого.
Вот такая я бяка.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Философический вопрос про автоматический вывод типов.
Здравствуйте, VladD2, Вы писали:
VD>Хм. Нэмерл выводит типы. Это всеравно что вписывать их явно. Так что ошибок быть не может. Язык статически типизированный!
VD>Когда я тебе говорил о том, что проблема Руби отсутствие статической типизации ты мне все время возражал и говрил, что все ОК, плюс есть юнит-тесты и т.п. Сейчас же сам себе возражаешь.
VD>Сдается мне, что ты пытайся отстоять свое даже вопреки здравой логике.
нет принципиальной разницы. Без разглядывания подробностей реализации make_report нельзя сказать, что находится в Hash.
Только Nemerle будет давать по рукам во время компиляции (если будет явное нарущение, а то ведь он может и сам какие-то типы вывести). Это хорошо.
Есть! И приципиальная! В Нэмерле тип выражения известен во время компиляции со всеми вытекающими из этого проверками.
И вот еще что. Заметь! Ты сравнивашь скриптовый язык с языком который по всем параметрам кроме простоты или не уступает, или привосходит С++. А в простоте он его делает как катентка.
Не плохо, правда? Статически типизированный стрипт! Кстати, у Нэмерла есть нечто вроде интерпретатора.
E> Без разглядывания подробностей реализации make_report нельзя сказать, что находится в Hash.
Это в Руби нельзя. А в Нэмерле можно. Даже наоборот нельзя по другому.
E>Только Nemerle будет давать по рукам во время компиляции (если будет явное нарущение, а то ведь он может и сам какие-то типы вывести). Это хорошо.
Именно.
E>Но лучше, когда объявление метода будет вида: E>
Тебе уже раз 5 сказали, что в немерле вольности с типами допускаются только в рамках одного метода. Все глобальные сущьности, в том числе, методы, их параметры, свойства и поля обязаны обявляться явно. Сделано это именно в целях документирования, минимизации ошибок и ускорения компиляции. То есть весь код можно писать не обращая внимание на типы. А вот члены класса прийдется опиысывать полностью. И это правильно!
VD>>1. Антиграблевость и простоту применения C#.
E>Об этом сейчас я бы не стал судить. Макросы в Nemerle это отдельная и большая поляна для грабель.
Макросы писать не обязательно. И отлаженный макрос способен вызвать только те грабли которе ты сам лично туда зложил. Эдак и на C# можно граблей понавтыкать если, например, сделать неявных приведений к булеву типу у чего попало. Но люди же разумны.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Философический вопрос про автоматический вывод типов.
VD>>а не VD>>Hashtable<string, int> hash = Hashtable<string, int>(); VD>>как это сейчас происходит в С++ и C#.
CS>Я не вижу принципиальной разницы в написании
Принципиальная разница в том, чо мжно и без <string, int>, как ты мог заметить.
А так же в универсальности. def задает неизменяемую переменную которая может быть локальной функцией, ссылкой на тип...
VD>>Они приципиально до этого не доступны. Любой интелисенст парсет все файлы проекта и крайне плохо относится к наличию ошибок в них.
CS>Это очень дорогая операция парсить все файлы. Это не для GUI.
Я не виноват, что ты не занимался этим вопросом. Поверь на слово. Без прасинга всех файлов интелисенст не работает. Днугое дело, что никто не парсит все файлы на каждое нажатие клавиши на клаве. Конечно же полный парсино происходит при открытии проекта или его изменении извне. А при изменении содержимого функции по блокам отсекается изменившаяся функция и перепарсивается только ее содержимое.
CS>Несколько надуманный пример, имхо. Честно говоря такого безобразия я в своей практике не встречал.
А я встречал. Не раз приходилось делать юснги на используемые в хэш-таблицах типы. Ну, да в С++ "точек" чуть по меньше да и ООП там ен так часто по полной используют. Так что может эта проблема не так актуальная. Хотя точно сопсбствует более коротким, а стало быть менее информативным именам.
CS>Может из-за того что я ни stl ни boost не использую в быту?
Может.
CS>Еще раз с интеллисенсом не все так хорошо как ты написал.
Вывод типов не проблема для интелисенса. Вот макросы — длугое дело. Но вроде как работы над этим делом уже ведутся. Интелисенс делают прямо на базе компилятора.
CS> Запуск полномасштабного парсера (даже без кодогенерации) CS>на каждый введенный nmtoken это нереально.
Если его научить парсить отдельную функцию, то без проблем. И вообще, чем по-твоему отличается "полномасштабный парсер" от парсера для интелисенса? Это толко у С++ с этим проблемы в следствии кучи неоднозначностей и инклюдов.
CS>На таких принципах можно и для скриптов intellisense строить.
Нельзя. Вывод типов отустуствует. А без него не ясно что за тип имеет идентификатор. Если же можно сделать вывод типов, то не ясно зачем вообще нужна интерпретация и нинамическая типизация.
CS> Что CS>кстати и сделано в VS. Там это правда работает для сугубо простых случаев.
Если ты про ASP (то что было до дотнета) и про старую студию, то там как раз и использовался вывод типа. Правда так как скрипты позвляли это делать плохо, то и результат был очень ограниченным. Тут же гарантируется 100%-ный вывод типов.
CS>В принципе мотивация понятна. CS>Я просто думал что это решает некие принципиальные вещи.
А разве краткость кода как в Питоне и Руби при типизации строже чем в С++ — это не принципиальное решение?
CS>Лично для меня явно определить тип всегда лучше — лишний checkpoint CS>который отлавливается в compiletime и сразу, а не в runtime.
Дык всто тоже самое, только делать ничего не надо. Ести ты привык декларироваь типы, то продолжай это делать. Компилятору работы поубавится. А елси ты привык к скриптам, то получишь всо тоже самое, только без жертв всвязанных с динамической типизацией.
CS>Кстати Вальтер добавил в D auto т.е. такое вот работает: CS>auto i = 2+2;
Такое и в C# скоро появится. Согласись Нэмерл пошел сильно дальше.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Философический вопрос про автоматический вывод типов.
Здравствуйте, VladD2, Вы писали:
VD>И вот еще что. Заметь! Ты сравнивашь скриптовый язык с языком который по всем параметрам кроме простоты или не уступает, или привосходит С++. А в простоте он его делает как катентка.
Ты так уверен? Сколько кода ты написал на Nemerle чтобы об этом судить?
E>>Об этом сейчас я бы не стал судить. Макросы в Nemerle это отдельная и большая поляна для грабель.
VD>Макросы писать не обязательно. И отлаженный макрос способен вызвать только те грабли которе ты сам лично туда зложил.
Классная фраза. Эдак про што угодно сказать можно.
Макросы отличаются от обычного кода тем, когда и как они запускаются. Можно ли, например, их отладочными печатями проверять?
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[4]: Философический вопрос про автоматический вывод типов.
Здравствуйте, VladD2, Вы писали:
VD>ЗЫ
VD>Многие считают меня фанатиком. Но они ошибаются. Я в каком-то смысле продажная шкура. Если я вижу что-то по совокупности характеристик лучшее чем то что мне нравилось до этого, то я легко бросаю старую игрушку и беру лучшее. Просто не так много вещей в мире которые действительно кумулятивно (по совокупности) лучше чем то, во что я играюсь сегодня. Возможно мне просто плохо объясняли, а возможно я просто не столь дальновидный. Но мне кажется дело все же не во мне. Я конечно люблю поспорить и увлекшись могу начать отстаивать и не верную позицию. Но выслушав аргументы и остыв я все же (по крайней мере хочется в это верить) способен оценить их и принять решение на основании логики, а не собственной вредности.
По поводу твоего красочного жизнеописания хотелось бы уточнить два вопроса:
1. У тебя вообще образование связано с программированием? Или же ты в большей степени самоучка?
2. Ты так с легкостью переходил с одной технологии на другую... А как быть с проектами, которые развивались в рамках какой-нибудь технологии в течении нескольких лет?
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[3]: Философический вопрос про автоматический вывод типов.
Здравствуйте, WFrag, Вы писали:
WF>Если под "боксингом" ты имеешь ввиду полиморфизм (т.е когда в массиве хранится некий Object или т.н "Top"), то ситуация такая. (далее идут мои, возможно ошибочные, размышления). Вообще говоря, можно ввести тип Top, однако в силу статичности O`Caml его смысл несколько теряется (т.к ты все равно с этим типом потом ничего осмысленного не сделаешь).
В Немерле таких проблем нет. Вся динамическая поддержка дотнета в твоем распоряжении.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Философический вопрос про автоматический вывод типов.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, AVC, Вы писали:
VD>Думаю твой пример на этом: AVC>>Вот еще один пример "из жизни" (я его, конечно, схематизировал), связанный с этой стороной Си++. VD>можно было бы и закончить.
VD>К тому же ты сам усугубил свою проблему создав неявное приведение к bool.
Я имел в виду:
Вот еще один пример "из жизни" (я его, конечно, схематизировал), связанный с этой стороной Си++.
Приведенный пример связан с моделированием FPU другого процессора.
Код не мой, но ведь часто так и пишут на Си++.
Меня удивило только "равнодушие" компилятора.
Раз такая тема поднята применительно к Nemerle, IMHO, есть опасность, что в той или иной степени могут быть повторены ошибки Си++.
Но существует одно качество, которое нельзя купить, — это надежность. Цена надежности — погоня за крайней простотой. Это цена, которую очень богатому труднее всего заплатить.
Хоар
Re[5]: Философический вопрос про автоматический вывод типов.
Здравствуйте, eao197, Вы писали:
E>1. У тебя вообще образование связано с программированием? Или же ты в большей степени самоучка?
По образованию я юнист и бухгалтер. Неужели не похоже?
E>2. Ты так с легкостью переходил с одной технологии на другую... А как быть с проектами, которые развивались в рамках какой-нибудь технологии в течении нескольких лет?
Я не сказал бы, что это было с легкостью. Это был постепенный процесс. Часть его прошла когда особых проектов и не было. Вернее был, но он с лихвой окупился еще в середине 90-ых. А потом основной доход я получал от продажи журналов (в основном бухгалтерских), так что разработка не была основыным дохождом. Скорее она была основным расходом.
А вообще, все очень просто. Продукт который не выпущен на ранок за 2-3 года рискует оказаться провальным. Револющии и темболее эволюции даже в нашей бурно развивающейся индустрии происходят куда реже. Так что можно без проблем сдавать продукт и начинать новый на новом витке.
Так что я не вижу тут проблем. Те кто засиделся скорее огребут от конкурентов чем что-то до добются. Это я говорю как экономист. Конечно речь не идет о монстрах вроде МС и Сана. Они то могут себе повзолить и деять параллельных продуктов на совершенно разных принципах. Могут позволить себе писать ОС 15 лет подряд на С. У них есть на это деньги.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Философический вопрос про автоматический вывод типов.
Здравствуйте, eao197, Вы писали:
E>Ты так уверен? Сколько кода ты написал на Nemerle чтобы об этом судить?
Зато я таскал мешки с цементом! Это тоже в зачет идет!
VD>>Макросы писать не обязательно. И отлаженный макрос способен вызвать только те грабли которе ты сам лично туда зложил.
E>Классная фраза. Эдак про што угодно сказать можно.
Ну, более подробно расскажу когда напишу и отлажу сам хотя бы парачку.
E>Макросы отличаются от обычного кода тем, когда и как они запускаются. Можно ли, например, их отладочными печатями проверять?
Легко. Просто вызов вывода в косоль выводится во время компиляции. А вызов заключенный в <[ ]> попадает в генерируемый код. Собственно примеры есть на их сайте.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Философический вопрос про автоматический вывод типов.
Здравствуйте, AVC, Вы писали:
AVC>Раз такая тема поднята применительно к Nemerle, IMHO, есть опасность, что в той или иной степени могут быть повторены ошибки Си++.
По-моему, С++ стал таким примером, что даже Денис Ричи завязал с разработкой новых языков программирования.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Философический вопрос про автоматический вывод типов.
Здравствуйте, VladD2, Вы писали:
E>>1. У тебя вообще образование связано с программированием? Или же ты в большей степени самоучка?
VD>По образованию я юнист и бухгалтер. Неужели не похоже?
Похоже, но лучше знать наверняка
Поросто те вещи, про которые ты написал, даже в нашем провинциальном ВУЗе, даже в далекие 1990-1995 годы, рассказывалось на лекциях преподавателями или на переменках друзьями-коллегами, которые где-то подрабатывали. Была соответствующая атмосфера, в которой информация о старых и новых направлениях буквально витала в воздухе и только ленивый ее не анализировал и не усваивал.
Поэтому то, что для тебя бывало для открытием, для многих было всего лишь информационным фоном. Я не хочу сказать, что для меня никаких откровений не было, отнюдь. Но то, что я спокойнее воспринимал новые открытия, это очень вероятно. Может потому, что изначально этих открытий было больше. Я, например, радовался, когда появился Windows и был стороником Windows, даже агитировал за Windows когда был выбор между Windows и OS/2. Только вот OLE и COM-у я совершенно не обрадовался и всегда старался держаться подальше, так же как и от CORBA. Зато довольно быстро понял, что Java станет серьезным противником C++ и, поэтому, при каждом удобном случае старался провозгласить "Java must die!"
VD>А вообще, все очень просто. Продукт который не выпущен на ранок за 2-3 года рискует оказаться провальным.
Есть системы, рынок которых достаточно узок и малоизвестен. В качестве примеров можно взять системы для банковского процессинга, АСУТП, телекоммуникации. В таких нишах оперативное реагирование на технологии даже каждые пять лет уже не просто. А пять лет -- это не так уж мало. Например, Java появилась в 1995-1996 годах, но тогда она не была конкурентом C++. Через пять лет (в 2000-2001) уже можно было бы инициировать смену платформы с Java на C++, вполне. Но проходит еще пять лет и в качестве весьма серьезной альтернативы Jave выступает C#. А еще через пять лет альтернативой C# вполне может стать Nemerle.
Да вот, если время выпуска версии занимает 2-3 года, то смена мейнстрима раз в пять лет -- это слишком расточительно, имхо.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[6]: Философический вопрос про автоматический вывод типов.
VladD2,
> А вообще, все очень просто. Продукт который не выпущен на ранок за 2-3 года рискует оказаться провальным. Револющии и темболее эволюции даже в нашей бурно развивающейся индустрии происходят куда реже. Так что можно без проблем сдавать продукт и начинать новый на новом витке. > > Так что я не вижу тут проблем. Те кто засиделся скорее огребут от конкурентов чем что-то до добются. <...>
Эти рассуждения обычно неприменимы к продукту с долгим временем жизни. Очень много относительно небольших фирм построено вокруг нескольких продуктов, новые версии которых должны выходить регулярно. Позволить себе переписать все с нуля только ради перехода на очередную модную технологию они не могут, и, главное, никакого конкурентного преимущества от этого не получат, т.к. за время переписывания уже существующей функциональности их конкуренты напишут новую. Только когда продукт достигает пределов заложенной изначально архитектуры, и требует переписывания, можно задуматься о переходе на другую технологию. Но и в этом случае часто решение будет не в пользу такого варианта, т.к. будет существовать множество компонент, одно повторное использование которых может позволить реализовать новую архитектуру значительно быстрее, чем перевод всего этого на новую технологию. Плюс накопленный опыт уже работающих специалистов по сравнению с их переучиванием или наймом новых. Плюс известные
риски против неизвестных.
Если же речь идет о серии "одноразовых" продуктах, каждый из которых пишется, фактически с нуля или с использованием только общих/базовых компонентов, то, конечно, ситуация будет ближе к описанной тобой ранее.
Posted via RSDN NNTP Server 2.0
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[5]: Философический вопрос про автоматический вывод типов.
[ИМХО]
Влад, ну ведь эрудированный человек, писал на C/С++ и вот все строишь из себя С++ ненавистника.
Зачем ?
С++ это, как минимум, Веха в истории развтития языков программирования, такая как Java ( не C# ибо .Net есть попытка повторения успеха платформенно-независимой машины ).
Ну вот зачемв все так экранизировать ? ( В отношении себя и C++ естественно )
[/ИМХО]
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[2]: Философический вопрос про автоматический вывод типов.
Положа руку на сердце — согласен — это все очень хорошо и понятно.
Но как всегда — есть одно НО, а именно — автор кода — легко поймет что скрывается за "визуально не типизированным" выражением, а вот программист, которыёё будет этот код поддерживать ?
Дело в том, что как излишняя типизация есть зло, так и отсутсвие ьтаковой, ИМХО, есть тоже зло, ибо расслабляет программиста и как результат — код в котором тожде трудно понять чот и как с первого взгляда.
Да конечно есть высококвалифицированные программисты, коотрые такой код быстро раскусят, но согласитесь, все развитие ЯП идет по пути уменьшения проф.навыков програмист ( с целью минимизации расходов на разработку ), так что такая свобода — тоже не есть гуд.
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[4]: Философический вопрос про автоматический вывод типов.
Здравствуйте, WFrag, Вы писали:
CS>>Еще раз мне представляется проблема несколько надуманной. CS>>На Java я пишу немного в последнее время. А в C++ автоматический вывод типов CS>>я из своей практики исключил. И лучше бы его там не было вообще.
WF>Интересно, как можно говорить о некоторой возможности если ты даже с ней не работал (впечатление такое сложилось)?
Я не понял, с чем я не работал? С Nemerle — не работал. С O'Caml — тоже.
C C++ работаю.
WF>..и даже не хочешь узнать, что это за фича и как она работает.
Как она работает я знаю или, скажем так, понимаю как сделать.
Я не понимаю зачем.
WF>В O`Caml disjoint union-ов нет. Но ничто не мешает использовать в данном случае joint union.
А самый завлящщий discriminated union ?
Иногда надо.
CS>>"не ошибаешься в указании типа". Если я ошибусь мне компайлер скажет. CS>>А в твоем случае скажет unittest. Который еще писать надо.
WF>Нет. Тип выведется. И в худщем варианте, выведется более общий тип, чем ты указал бы.
Я как-то об этом узнаю?
WF>Да, позволяет. Работать с очень сложными типами. Пример — монады (а еще лучше Arrows Хаскелля ). Посмотрел бы я на того маньяка, кто захочет везде явно типы указывать Ты указываешь типы для граничных случаев (там где ввод/вывод, например), а все остальные внутренние сложные типы выводятся автоматически.
"Работать с очень сложными типами" как это связано с длиной
идентификатора типа? Что такое вообще "очень сложный тип" в твоем понимании?
Кроме того что не нужно писать типы явно что-нибудь еще
есть в автоматическом выводе типов?
Re[5]: Философический вопрос про автоматический вывод типов.
Здравствуйте, c-smile, Вы писали:
WF>>Интересно, как можно говорить о некоторой возможности если ты даже с ней не работал (впечатление такое сложилось)?
CS>Я не понял, с чем я не работал? С Nemerle — не работал. С O'Caml — тоже. CS>C C++ работаю.
С выводом типом по типу как в ML-языках.
WF>>..и даже не хочешь узнать, что это за фича и как она работает.
CS>Как она работает я знаю или, скажем так, понимаю как сделать. CS>Я не понимаю зачем.
Я отвечал зачем. Ниже написал еще раз. Плюс важное замечание
WF>>В O`Caml disjoint union-ов нет. Но ничто не мешает использовать в данном случае joint union.
CS>А самый завлящщий discriminated union ? CS>Иногда надо.
Ну это join union и есть, насколько я понимаю.
WF>>Нет. Тип выведется. И в худщем варианте, выведется более общий тип, чем ты указал бы.
CS>Я как-то об этом узнаю?
Что узнаешь? Ты можешь быть спокоен, что твоя программа непротиворечива с точки зрения используемой системы типов.
CS>"Работать с очень сложными типами" как это связано с длиной CS>идентификатора типа? Что такое вообще "очень сложный тип" в твоем понимании?
Скажем, композиция пары Haskell-евских функционалов высшего порядка и получится сложный тип. По-моему (маленькому) опыту такие типы начинают активно появляться там, где есть монады. Ну и вообще замечал, что при описании Haskell-овских eDSL-ей обычно на границе eDSL-я простые типы (фигура, время, цвет), а в самой реализации чего-нибудь сложного типы просто зубодробительные.
В моем понимании "очень сложный тип" — это когда много стрелочек Если в типе употребляется где-то больше 5 других типов, для меня это уже сложно.
Один из способов работы с такими объектами — отказаться от статической типизации (как и делают в скриптовых языках, например). Другой способ — вывод типов.
Подумал и вспомнил еще один момент. Причем наиболее важный
Еще один момент — это параметрический полиморфизм. Допустим, где-то в коде у тебя есть выражение map(func, lst), где map и func — функции, lst — некоторые параметры. Как ты можешь узнать, что это выражение корректно? Что тип элемента списка, сигнатура func и map — консистентны? При том, что map — полиморфная функция, она может работать со множеством разных параметров разных типов. Ты же не будешь к каждому подвыражению приписывать конкретный тип? Например, в случае выражения "map (\x -> x*2) [1, 2, 3]", тип map будет выведен как (int->int)->[int]->[int]. А в случае "map (\x -> x*2) ["1", "2", "3"]" будет ошибка унификации — тип не может быть выведен, т.е выражение неконсистентно.
Так что вывод типов — это может быть еще и часть алгоритма проверки типов. А то что он умеет выводить типы еще и для вводимых переменных, так это частный случай.
CS>Кроме того что не нужно писать типы явно что-нибудь еще CS>есть в автоматическом выводе типов?
Написал выше.
Re[7]: Философический вопрос про автоматический вывод типов.
IT,
> ПК> Эти рассуждения обычно неприменимы к продукту с долгим временем жизни.
> А именно?
Револющии и темболее эволюции даже в нашей бурно развивающейся индустрии происходят куда реже. Так что можно без проблем сдавать продукт и начинать новый на новом витке. Так что я не вижу тут проблем. Те кто засиделся скорее огребут от конкурентов чем что-то до добются.
Posted via RSDN NNTP Server 2.0
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[9]: Философический вопрос про автоматический вывод типов.
Здравствуйте, Павел Кузнецов, Вы писали:
>> ПК> Эти рассуждения обычно неприменимы к продукту с долгим временем жизни.
>> А именно?
ПК>
ПК>Револющии и темболее эволюции даже в нашей бурно развивающейся индустрии происходят куда реже. Так что можно без проблем сдавать продукт и начинать новый на новом витке. Так что я не вижу тут проблем. Те кто засиделся скорее огребут от конкурентов чем что-то до добются.
Мне классиков цитировать не надо Мне интересно знать о каком именно продукте идёт речь?
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[6]: Философический вопрос про автоматический вывод типов.
Здравствуйте, srggal, Вы писали:
S>Влад, ну ведь эрудированный человек, писал на C/С++ и вот все строишь из себя С++ ненавистника. S>Зачем ?
Звучит очень похоже на "Ведь энтилегентный человек, строем ходил не раз..."
Я не ненавистник. Я считаю С++ этапом. Этапом в истории, этапом в собственном развитии. И считаю, что этап это пройден. Согласен, что не для всех. Но для меня одноначно пройден.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Философический вопрос про автоматический вывод типов.
Здравствуйте, srggal, Вы писали:
S>Но как всегда — есть одно НО, а именно — автор кода — легко поймет что скрывается за "визуально не типизированным" выражением, а вот программист, которыёё будет этот код поддерживать ?
Для человека этот код типизирован. Он делает выводы не хуже чем компилятор, а точнее намного лучше. Важно тут то, что компилятор не дает человеку ошибиться и использовать нечто не по назначению.
В конце концов можно ведь и добавить описание типа, если это улучит восприятие. В приведенном мной примере все и так очевидно.
S>Дело в том, что как излишняя типизация есть зло, так и отсутсвие ьтаковой,
Это не отсуствие! В этом вся и разница.
S>Да конечно есть высококвалифицированные программисты, коотрые такой код быстро раскусят, но согласитесь, все развитие ЯП идет по пути уменьшения проф.навыков програмист ( с целью минимизации расходов на разработку ), так что такая свобода — тоже не есть гуд.
Развитие идет по пути упрощения решения сложных задач. Это не оболваниевание, это расширение возможностей. Ведь можно что-то оболванить и тем самым сделать доступным массам. А можно сделать отличную автоматику которая скроет сложность.
Простой пример из жизни. Есть лестницы, а есть лифты. На сегодня пользоватьс ялифтом не сложнее чем лестницой (даже наоборот). Но ведь лифт не является более простой сущьностью. Просто он снабжен автоматикой делающей пользование лифтом столь простым. Так вот лестница это простое и от того надежное решеие. Но пользуемся мы в основном лифтом, так как это тоже простое решение, но ко всему прочему оно позволяет нам не тратить лишних сил.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Философический вопрос про автоматический вывод типов.
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Эти рассуждения обычно неприменимы к продукту с долгим временем жизни. Очень много относительно небольших фирм построено вокруг нескольких продуктов, новые версии которых должны выходить регулярно. Позволить себе переписать все с нуля только ради перехода на очередную модную технологию они не могут, и, главное, никакого конкурентного преимущества от этого не получат, т.к. за время переписывания уже существующей функциональности их конкуренты напишут новую. Только когда продукт достигает пределов заложенной изначально архитектуры, и требует переписывания, можно задуматься о переходе на другую технологию. Но и в этом случае часто решение будет не в пользу такого варианта, т.к. будет существовать множество компонент, одно повторное использование которых может позволить реализовать новую архитектуру значительно быстрее, чем перевод всего этого на новую технологию. Плюс накопленный опыт уже работающих специалистов по сравнению с их переучиванием или наймом новых. Плюс известные ПК>риски против неизвестных.
Ни один продукт не является неразделимым монолитом. А если все-таки является, то его архитектору надо бить по рукам железной палкой.
Так что я не вижу ни малейших проблем в том, чтобы использовать новые технологии в новых подсистемах, или переписывать с их помощью особо проблематичные старые подсистемы.
... << RSDN@Home 1.1.4 stable rev. 510>>
Всех излечит, исцелит
добрый Ctrl+Alt+Delete
Re[8]: Философический вопрос про автоматический вывод типов.
Здравствуйте, Дарней, Вы писали:
Д>Ни один продукт не является неразделимым монолитом. А если все-таки является, то его архитектору надо бить по рукам железной палкой.
Д>Так что я не вижу ни малейших проблем в том, чтобы использовать новые технологии в новых подсистемах,
Например, механизмы коммуникаций между старыми подсистемами.
Д>или переписывать с их помощью особо проблематичные старые подсистемы.
А что, старые подсистемы по-определению проблематичные и нуждаются в переписывании?
Мне представляется, что долгоиграющий продукт с проблематичными подсистемами просто не выжил бы.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[8]: Философический вопрос про автоматический вывод типов.
Здравствуйте, IT, Вы писали:
ПК>>Эти рассуждения обычно неприменимы к продукту с долгим временем жизни.
IT>А именно?
А можно мне за Павла ответить? Ну, например, Base24-card.
Да и чего специализированные системы вспоминать. Можно, имхо, на MS Word посмотреть, Visual Studio, IE, Mozilla, Opera. Вряд ли их можно назвать продуктами с коротким временем жизни.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[9]: Философический вопрос про автоматический вывод типов.
Здравствуйте, eao197, Вы писали:
E>Например, механизмы коммуникаций между старыми подсистемами.
Это станет проблемой только в том случае, если механизм не продумывался заранее. (см пункт про битье по рукам)
Д>>или переписывать с их помощью особо проблематичные старые подсистемы.
E>А что, старые подсистемы по-определению проблематичные и нуждаются в переписывании?
именно так. Чем больше возраст кода, тем больше там "заплаток", подпорок, и просто ненужного кода. Рано или поздно любой модуль приходится переписывать. Всё, что нужно для этого — нормальная документация, которая подробно описывает интерфейс модуля и функционал.
E>Мне представляется, что долгоиграющий продукт с проблематичными подсистемами просто не выжил бы.
Это предположение, или точные данные?
... << RSDN@Home 1.1.4 stable rev. 510>>
Всех излечит, исцелит
добрый Ctrl+Alt+Delete
Re[10]: Философический вопрос про автоматический вывод типов
Здравствуйте, Дарней, Вы писали:
Д>Это станет проблемой только в том случае, если механизм не продумывался заранее. (см пункт про битье по рукам)
Архитектура изначально могла не расчитываться на интероперабельность с системами на других языках. Например, могло использоваться что-то, что хорошо работало в рамках одного языка. Скажем, собственный протокол на основе коммуникационных возможностей OS. Десять лет назад никто не использовал, скажем, XML-RPC или SOAP для взаимодействия компонентов.
Д>именно так. Чем больше возраст кода, тем больше там "заплаток", подпорок, и просто ненужного кода. Рано или поздно любой модуль приходится переписывать. Всё, что нужно для этого — нормальная документация, которая подробно описывает интерфейс модуля и функционал.
Это предположение или точные данные?
E>>Мне представляется, что долгоиграющий продукт с проблематичными подсистемами просто не выжил бы.
Д>Это предположение, или точные данные?
Э... экстраполяция собственного не очень большого опыта. Наверное точно выразился.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[9]: Философический вопрос про автоматический вывод типов.
Здравствуйте, eao197, Вы писали:
E>А можно мне за Павла ответить? Ну, например, Base24-card.
А вот не надо за Павла отвечать
E>Да и чего специализированные системы вспоминать. Можно, имхо, на MS Word посмотреть, Visual Studio, IE, Mozilla, Opera. Вряд ли их можно назвать продуктами с коротким временем жизни.
Я не понимаю таких аргументов. Точнее понимаю только из уст тех кто написал эти продукты. Иначе получается фигня, а не аргумент — раз студия на плюсах написана, значит и мы свой склад бракованных изделий тоже будем на плюсах писать
ЗЫ. И вообще, студия наполовину на шарпе написана.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[10]: Философический вопрос про автоматический вывод типов
Здравствуйте, IT, Вы писали:
IT>А вот не надо за Павла отвечать
E>>Да и чего специализированные системы вспоминать. Можно, имхо, на MS Word посмотреть, Visual Studio, IE, Mozilla, Opera. Вряд ли их можно назвать продуктами с коротким временем жизни.
IT>Я не понимаю таких аргументов. Точнее понимаю только из уст тех кто написал эти продукты. Иначе получается фигня, а не аргумент — раз студия на плюсах написана, значит и мы свой склад бракованных изделий тоже будем на плюсах писать
Дык, а разве я какие-то аргументы приводил? Просто перечислил продукты, которые не один год на рынке присутствуют. Выводы пусть каждый сам делает.
И тем более ничего не говорил про склад бракованных плюсовых изделий.
Вообще, складывается впечатление, что C# гарантирует отличный и безглючный софт. А вот C++ -- 100% гарантия обратного эффекта. Ну не бывает так.
IT>ЗЫ. И вообще, студия наполовину на шарпе написана.
Ничего удивительного, она же должна и шарп поддерживать.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[10]: Философический вопрос про автоматический вывод типов
Здравствуйте, eao197, Вы писали:
E>Да и чего специализированные системы вспоминать. Можно, имхо, на MS Word посмотреть, Visual Studio, IE, Mozilla, Opera. Вряд ли их можно назвать продуктами с коротким временем жизни.
Ну, вот возми к примеру Visual Studio. 5.0 и 6.0 — это два разных продукта. Очень разных! Так что совершенно не важно на чем они писались.
6.0 и 7.х (2003) тоже совершенно разные продукты. В 7.х не малый объем кода написан на C#. В 2005-ой студии объем дотнетного кода еще более увеличился, хотя она как раз является развитием 2003-ей.
Уже известно, что в будущем студия будет переписана целиком на нотнете...
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[10]: Философический вопрос про автоматический вывод типов
Здравствуйте, VladD2, Вы писали:
VD>Ну, вот возми к примеру Visual Studio. 5.0 и 6.0 — это два разных продукта. Очень разных! Так что совершенно не важно на чем они писались.
VD>6.0 и 7.х (2003) тоже совершенно разные продукты. В 7.х не малый объем кода написан на C#. В 2005-ой студии объем дотнетного кода еще более увеличился, хотя она как раз является развитием 2003-ей.
Вообще-то VS оказалась не удачным примером. Она слишком сильно на языки и технологии программирования завязана.
VD>Уже известно, что в будущем студия будет переписана целиком на нотнете...
Главное, что следующая версия gvim не будет переписана на дотнете
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[4]: Философический вопрос про автоматический вывод типов.
Здравствуйте, AVC, Вы писали:
. AVC>Меня удивило только "равнодушие" компилятора. AVC>Раз такая тема поднята применительно к Nemerle, IMHO, есть опасность, что в той или иной степени могут быть повторены ошибки Си++.
Вся беседа в целом кое-что мне напоминает. А именно — реакцию лордов на изобретение первого паровоза. Один опасался, что красный цвет трубы паровоза (греется до красна) будет нервировать стада коров, пасущихся рядом с трассой, и предлагал на всякий случай запретить паровоз. А второй — думал, что есть такая опасность, что паровоз не поедет — колеса-то в той или иной степени гладкие и скользкие, как и рельсы. И предлагал сделать колеса зубчатыми. Штоб цеплялись.
Господа, неужели сложно почитать про вывод типов? Не уподобляйтесь английским лордам, короче .
Re[10]: Философический вопрос про автоматический вывод типов
Здравствуйте, VladD2, Вы писали:
VD>Уже известно, что в будущем студия будет переписана целиком на нотнете...
Откуда дровишки? Я не слышал о планах переписывать; слышал о планах переносить. Т.е. значительные куски кода собирались оставить теми же, но перекомпилировать в режиме C++/CLI.
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[5]: Философический вопрос про автоматический вывод типов.
Здравствуйте, c-smile, Вы писали:
WF>>..и даже не хочешь узнать, что это за фича и как она работает.
CS>Как она работает я знаю или, скажем так, понимаю как сделать. CS>Я не понимаю зачем.
Затем же, зачем в С++ есть шаблоны. Делается это для того, чтобы компилятор вывел общий тип.
Возьми шаблонную функцию С++. Типы ее аргументов не выводятся, они проверяются при инстанцировании в каждом конкретном случае. Теперь предствь, что компилятор может вывести параметризованный тип из контекста употребления для любой функции, и тебе не надо писать template. Так что любая функция у тебя обладает параметрическим полиморфизмом без лишних теложвижений с твоей стороны. Вот зачем в языках группы ML делается вывод типов. А зачем это делает Немерле — не знаю. Если за этим самым — то хорошо.
Re[11]: Философический вопрос про автоматический вывод типов
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Откуда дровишки?
От тех кто говорил с ее разработчиками.
ПК> Я не слышал о планах переписывать; слышал о планах переносить. Т.е. значительные куски кода собирались оставить теми же, но перекомпилировать в режиме C++/CLI.
Я рад за то, что ты понимаешь, что не мог слышать все на свете.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: Философический вопрос про автоматический вывод типов
Здравствуйте, eao197, Вы писали:
E>Вообще, складывается впечатление, что C# гарантирует отличный и безглючный софт. А вот C++ -- 100% гарантия обратного эффекта. Ну не бывает так.
Заметьте! Не я это первый сказал!
Речь не о глючном / безглючном. Выше по ветке Паша делает весьма смелое заявление:
> Так что я не вижу тут проблем. Те кто засиделся скорее огребут от конкурентов чем что-то до добются. <...>
Эти рассуждения обычно неприменимы к продукту с долгим временем жизни.
Вот мне и интересно, какой именно продукт Паша имеет ввиду, т.к. у меня на этот счёт совсем другое мнение. И заключается оно в том, что чем дольше время жизни проекта, тем раньше надо переходить на новые технологии.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[11]: Философический вопрос про автоматический вывод типов
Здравствуйте, Cyberax, Вы писали:
>> ЗЫ. И вообще, студия наполовину на шарпе написана. C>Там на Шарпе только мелкие и сравнительно автономные вещи типа панелей свойств.
А Microsoft.VSDesigner namespace — это, по-твоему, недоразумение?
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[11]: Философический вопрос про автоматический вывод типов
Здравствуйте, eao197, Вы писали:
E>Архитектура изначально могла не расчитываться на интероперабельность с системами на других языках. Например, могло использоваться что-то, что хорошо работало в рамках одного языка. Скажем, собственный протокол на основе коммуникационных возможностей OS. Десять лет назад никто не использовал, скажем, XML-RPC или SOAP для взаимодействия компонентов.
XML в данном случае — это худший выбор из всех возможных. Есть очень много куда более легковесных технологий — C-api, COM и аналоги, командная строка, MMF, пайпы, сокеты и т.д. и т.п.
E>Это предположение или точные данные?
это как раз точные данные
... << RSDN@Home 1.1.4 stable rev. 510>>
Всех излечит, исцелит
добрый Ctrl+Alt+Delete
Re[12]: Философический вопрос про автоматический вывод типов
>> Так что я не вижу тут проблем. Те кто засиделся скорее огребут от конкурентов чем что-то до добются. <...>
IT>Эти рассуждения обычно неприменимы к продукту с долгим временем жизни.
IT>Вот мне и интересно, какой именно продукт Паша имеет ввиду, т.к. у меня на этот счёт совсем другое мнение. И заключается оно в том, что чем дольше время жизни проекта, тем раньше надо переходить на новые технологии.
Я говорил о продуктах, которые уже достаточно долго живут, но очередные релизы которых, тем не менее, должны регулярно выходить. Примеры eao197 привел. Могу и я сколько-то добавить (например, см. ссылку в моем профайле на MetaCommunications, там products), но что это поменяет?
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[13]: Философический вопрос про автоматический вывод типов
P.S.
ПК>Я говорил о продуктах, которые уже достаточно долго живут, но очередные релизы которых, тем не менее, должны регулярно выходить. Примеры eao197 привел.
Кстати, примеры на продукты больших компаний далеко не так показательны, т.к. большая компания легче, чем маленькая, может позволить себе выпускать продукты с заметно меньшей регулярностью. Маленькая компания без выпуска очередных версий (*) в течение пары лет "загнется" наверняка.
(*) Или новых продуктов, но мы-то о маленьких компаниях, выпускающих большие долгоиграющие продукты, коих много не сделаешь...
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[13]: Философический вопрос про автоматический вывод типов
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Я говорил о продуктах, которые уже достаточно долго живут, но очередные релизы которых, тем не менее, должны регулярно выходить. Примеры eao197 привел. Могу и я сколько-то добавить (например, см. ссылку в моем профайле на MetaCommunications, там products), но что это поменяет?
Вы же сами потихоньку мигрируете, по-крайней мере штамп .NET на двух продуктах я увидел
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[14]: Философический вопрос про автоматический вывод типов
Здравствуйте, IT, Вы писали:
ПК>> Примеры eao197 привел. Могу и я сколько-то добавить (например, см. ссылку в моем профайле на MetaCommunications, там products), но что это поменяет?
IT> Вы же сами потихоньку мигрируете, по-крайней мере штамп .NET на двух продуктах я увидел
.NET используется только для Web. В продукт входит N приложений, в т.ч. и Web, вот штамп и стоит...
Да даже если бы и "мигрировали", согласись, это бы очень сильно отличалось от "можно без проблем сдавать продукт и начинать новый на новом витке".
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[15]: Философический вопрос про автоматический вывод типов
Hello, "IT"
>>> ЗЫ. И вообще, студия наполовину на шарпе написана. > C>Там на Шарпе только мелкие и сравнительно автономные вещи типа панелей свойств. > > А Microsoft.VSDesigner namespace — это, по-твоему, недоразумение?
Еще скажи, что в System.Data.dll это компилятор C# создал namespace <CppImplementationDetails> и namespace <CrtImplementationDetails>
Posted via RSDN NNTP Server 2.0
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[6]: Философический вопрос про автоматический вывод типов.
Здравствуйте, Gaperton, Вы писали:
G>Здравствуйте, c-smile, Вы писали:
WF>>>..и даже не хочешь узнать, что это за фича и как она работает.
CS>>Как она работает я знаю или, скажем так, понимаю как сделать. CS>>Я не понимаю зачем.
G>Затем же, зачем в С++ есть шаблоны. Делается это для того, чтобы компилятор вывел общий тип.
G>Возьми шаблонную функцию С++. Типы ее аргументов не выводятся, они проверяются при инстанцировании в каждом конкретном случае.
Да ну? Ты ничего не перепутал?
G>Теперь предствь, что компилятор может вывести параметризованный тип из контекста употребления для любой функции, и тебе не надо писать template. Так что любая функция у тебя обладает параметрическим полиморфизмом без лишних теложвижений с твоей стороны.
Всё -- шаблон -- это плохая идея. Например потому, что при выводе типов шаблонов функций не работают неявные конверсии типов.
Здравствуйте, Шахтер, Вы писали:
Ш>Здравствуйте, Gaperton, Вы писали:
G>>Здравствуйте, c-smile, Вы писали:
WF>>>>..и даже не хочешь узнать, что это за фича и как она работает.
CS>>>Как она работает я знаю или, скажем так, понимаю как сделать. CS>>>Я не понимаю зачем.
G>>Затем же, зачем в С++ есть шаблоны. Делается это для того, чтобы компилятор вывел общий тип.
G>>Возьми шаблонную функцию С++. Типы ее аргументов не выводятся, они проверяются при инстанцировании в каждом конкретном случае.
Ш>Да ну? Ты ничего не перепутал?
Ну да. Я — ничего не перепутал. Еще что-нибудь сказать есть, кроме междометий?
G>>Теперь предствь, что компилятор может вывести параметризованный тип из контекста употребления для любой функции, и тебе не надо писать template. Так что любая функция у тебя обладает параметрическим полиморфизмом без лишних теложвижений с твоей стороны.
Ш>Всё -- шаблон -- это плохая идея. Например потому, что при выводе типов шаблонов функций не работают неявные конверсии типов.
Это не идея. Это я на яблоках, прибегая к аналогиям, объясняюю, на что похож вывод типов в языках с системой Хиндли-Милнера. С расчетом на то, что до знающего С++ человека дойдет, зачем это надо. А ты все перепутал. В любом случае — если так не понятно, значит уже не вдолбить никак. По крайней мере, у меня идей больше нет, как объяснить.
Re[5]: Философический вопрос про автоматический вывод типов.
Здравствуйте, VladD2, Вы писали:
AVC>>Раз такая тема поднята применительно к Nemerle, IMHO, есть опасность, что в той или иной степени могут быть повторены ошибки Си++.
VD>По-моему, С++ стал таким примером, что даже Денис Ричи завязал с разработкой новых языков программирования.
AFAIK, в 90-х Ритчи создал язык Limbo (для системы Inferno ).
Использовать Си++ он "почему-то" не стал.
Этот язык сильно отличается от Си++ (и Си ) : type-safe, сборка мусора, модульность, может использоваться на машинах без memory-protection...
Ну прямо как Обе...
Впрочем, ой, что это я! На RSDN же полагается верить, что именно Вирт завидует успехам Ритчи и Страуструпа...
Но существует одно качество, которое нельзя купить, — это надежность. Цена надежности — погоня за крайней простотой. Это цена, которую очень богатому труднее всего заплатить.
Хоар
Re[6]: Философический вопрос про автоматический вывод типов.
Здравствуйте, AVC, Вы писали:
AVC>AFAIK, в 90-х Ритчи создал язык Limbo (для системы Inferno ). AVC>Использовать Си++ он "почему-то" не стал. AVC>Этот язык сильно отличается от Си++ (и Си ) : type-safe, сборка мусора, модульность, может использоваться на машинах без memory-protection... AVC>Ну прямо как Обе...
как странно, в слове "Лисп" совсем нет таких букв
... << RSDN@Home 1.1.4 stable rev. 510>>
Всех излечит, исцелит
добрый Ctrl+Alt+Delete
Re[7]: Философический вопрос про автоматический вывод типов.
Здравствуйте, VladD2, Вы писали:
VD>Я тебе уже не раз говорил, что Руби хотя вещь и красивая, но далекая от совершенства. Не нужно по ней судить о других языках.
E>> Там так же классы-модели возвращают какие-то объекты, которые затем используются формами для отображения информации. И очень скоро без явного декларирования типов возвращаемых объектов напрочь забываешь, что окуда возвращается и как с этим можно работать. А уж поддерживать целостность всего этого дела можно только за счет обилия unit-тестов. Приведенный тобой пример очень похож на эту ситуацию.
VD>Хм. Нэмерл выводит типы. Это всеравно что вписывать их явно. Так что ошибок быть не может. Язык статически типизированный!
Думается мне, что eao197 говорил про то, как ты полезешь как-нибудь в исходники, которые ты писал год-полтора назад, и увидишь такую вот безличную картину.
Как, без поддержки IDE, ты вспомнишь, кто что возвращает?
--
Re[6]: Философический вопрос про автоматический вывод типов.
AVC wrote: > Использовать Си++ он "почему-то" не стал.
Тогда С++ еще был "в детстве", так что неудивительно.
> Этот язык сильно отличается от Си++ (и Си ) : type-safe, сборка мусора, > модульность, может использоваться на машинах без memory-protection...
Там не сборка мусора, а подсчет ссылок. С++ тоже замечательно
используется без защиты памяти.
Из от С++ отличных фич Limbo и системы Inferno: поддержка параллелизма и
распределенности на уровне языка (в виде каналов), более сильная
типизация, другой синтаксис, динамическая подгрузка кода. В начале 90-х
это было вполне приличным набором.
Однако, современный С++ большую часть фич Limbo реализует в виде библиотек.
Posted via RSDN NNTP Server 2.0
Sapienti sat!
Re[5]: Философический вопрос про автоматический вывод типов.
Здравствуйте, Сергей Туленцев, Вы писали:
СТ>Думается мне, что eao197 говорил про то, как ты полезешь как-нибудь в исходники, которые ты писал год-полтора назад, и увидишь такую вот безличную картину. СТ>Как, без поддержки IDE, ты вспомнишь, кто что возвращает?
Обычно типы можно посмотреть безо всяких IDE, достаточно интерпретатора.
Re[5]: Философический вопрос про автоматический вывод типов.
Здравствуйте, Сергей Туленцев, Вы писали:
СТ>Думается мне, что eao197 говорил про то, как ты полезешь как-нибудь в исходники, которые ты писал год-полтора назад, и увидишь такую вот безличную картину.
Да, именно об этом. Причем, как показала практика, забывается все уже буквально через пару дней
В статически типизированных языка так же можно устроить себе подобные приключения, если, например, написать:
Вроде и типы все знаешь, а что это такое и почему -- вопрос.
Но я действительно упустил из виду, что в Nemerle все, что идет из метода наружу, должно декларироваться.
СТ>Как, без поддержки IDE, ты вспомнишь, кто что возвращает?
Применительно к Nemerle меня больше всего забавляет другое -- вроде бы и язык интересный, и многое обещает, и многим нравится. Но препятствием служит отсутствие IDE!
По мне, так если язык действительно хороший (теплый взгляд в сторону C++ и Ruby), так на нем даже в Notepade (не говоря уже про vim и emacs) программировать можно.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[6]: Философический вопрос про автоматический вывод типов.
Здравствуйте, Programmierer AG, Вы писали:
PA>Обычно типы можно посмотреть безо всяких IDE, достаточно интерпретатора.
Чтобы посмотреть типы в run-time, необходимо, как минимум, работающее окружение. Т.е. некий тестовый стенд, на котором ты можешь запустить тестовый прогон и поставить точку прерывания в нужном месте.
Если же речь идет о статически типизированных языках, т.к. C++ (Java, C#), то для просмотра типа тебе достаточно иметь заголовочные файлы.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[6]: Философический вопрос про автоматический вывод типов.
E>Да, именно об этом. Причем, как показала практика, забывается все уже буквально через пару дней E>В статически типизированных языка так же можно устроить себе подобные приключения, если, например, написать:
Языки с автоматическим выводом типов — статически типизируемые, попрошу не путать . E>
E>Вроде и типы все знаешь, а что это такое и почему -- вопрос.
ПО-моему, функция построения отчета по каким-то параметрам (кстати, это целая проблема — придумывать названия параметрам типа args, settings, options, params,...).
E>Применительно к Nemerle меня больше всего забавляет другое -- вроде бы и язык интересный, и многое обещает, и многим нравится. Но препятствием служит отсутствие IDE!
На IDE внимание акцентирует только Влад, не надо обобщать. E>По мне, так если язык действительно хороший (теплый взгляд в сторону C++ и Ruby), так на нем даже в Notepade (не говоря уже про vim и emacs) программировать можно.
Намекнуть, чем пользуются программисты на Лиспе, ML, Erlang, ...?
Re[7]: Философический вопрос про автоматический вывод типов.
Здравствуйте, Programmierer AG, Вы писали:
PA>Языки с автоматическим выводом типов — статически типизируемые, попрошу не путать .
Я и не путаю
Но, насколько я понял, в Nemerle в nested functions можно не указывать типы параметрам и возвращаемому значению. В таких случаях запись в Nemerle визуально не сильно отличается от записи в Ruby или Python. Разница только в том, в какой момент времени тебя предупредят об ошибке, если ты ошибся -- во время компиляции или исполнения. Но на момент написания кода подсказок-то нет (разве что IDE будет очень умная).
PA>ПО-моему, функция построения отчета по каким-то параметрам (кстати, это целая проблема — придумывать названия параметрам типа args, settings, options, params,...).
Ага, вопрос в том, что является ключем в первом map (имя клиента или имя сервиса), а что во вложенном (имя сервиса или имя клиента).
PA>На IDE внимание акцентирует только Влад, не надо обобщать.
Отвечу в обратном порядке.
E>Если же речь идет о статически типизированных языках, т.к. C++ (Java, C#), то для просмотра типа тебе достаточно иметь заголовочные файлы.
Статически типизируемые языки — это те, в которых типы известны на этапе компиляции, соответственно компилятор дает по рукам при ошибках типизации. Независимо от того, выводятся типы автоматически или вбиваются вручную.
E>Чтобы посмотреть типы в run-time, необходимо, как минимум, работающее окружение. Т.е. некий тестовый стенд, на котором ты можешь запустить тестовый прогон и поставить точку прерывания в нужном месте.
Да нету никаких рантаймов, тестовых прогонов и точек прерывания.
На примере ОКамла.
Разработка ведется в стиле REPL. В процессе разработки нового модуля периодически скармливаем текст интерпретатору. И тут же видим типы всех значений (в т.ч. функций), определенных в модуле. Во время активной разработки достаточно ml-файла (некий аналог .cpp-файла) — т.к. есть вывод типов, то и интерфейс модуля выводится автоматически. Затем, после того, как модуль устаканится, можно добавить mli-файл, в котором явно указываются все экспортируемые значения и их типы.
Еше раз — отсутствие фич (в данном случае вывода типов) нельзя выдавать за преимущество. Если пугает опасность забыть типы функций в модуле — всегда есть возможность добавить аннотации типов. Но языки, которые требуют вводить типы на каждом шагу, как справку из ЖЭКа, морально устарели.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[7]: Философический вопрос про автоматический вывод типов.
Здравствуйте, Дарней, Вы писали:
AVC>>Этот язык сильно отличается от Си++ (и Си ) : type-safe, сборка мусора, модульность, может использоваться на машинах без memory-protection... AVC>>Ну прямо как Обе...
Д>как странно, в слове "Лисп" совсем нет таких букв
Кроме того, Limbo — императивный язык...
"Человек — двуногое существо без перьев и с плоскими ногтями." (c) Платон
Но существует одно качество, которое нельзя купить, — это надежность. Цена надежности — погоня за крайней простотой. Это цена, которую очень богатому труднее всего заплатить.
Хоар
Re[8]: Философический вопрос про автоматический вывод типов.
Здравствуйте, Programmierer AG, Вы писали:
PA>На примере ОКамла.
Вот, тебе, как разработчику build-системы, может быть интересна работа конкурентов: http://svn.metaprl.org/viewcvs/mojave/omake/src/
Думаю, в .mli-файлах все понятно, без интерпретатора, что опровергает тезис о невозможности понять что-либо в программах на языках с выводом типов без IDE . С другой стороны, если ты сопровождаешь систему, то компилятор и интерпретатор таки должны быть под рукой.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[8]: Философический вопрос про автоматический вывод типов.
Здравствуйте, Programmierer AG, Вы писали:
E>>Если же речь идет о статически типизированных языках, т.к. C++ (Java, C#), то для просмотра типа тебе достаточно иметь заголовочные файлы. PA>Статически типизируемые языки — это те, в которых типы известны на этапе компиляции, соответственно компилятор дает по рукам при ошибках типизации. Независимо от того, выводятся типы автоматически или вбиваются вручную.
Но ты же сам написал ниже, что нужно иметь какой-то код, с помощью которого компилятор (интерпритатор) подскажет тебе типы во время разработки. Собственно, об этом я и говорил.
E>>Чтобы посмотреть типы в run-time, необходимо, как минимум, работающее окружение. Т.е. некий тестовый стенд, на котором ты можешь запустить тестовый прогон и поставить точку прерывания в нужном месте.
PA>Да нету никаких рантаймов, тестовых прогонов и точек прерывания.
Ок. Методику работы понял.
PA>Еше раз — отсутствие фич (в данном случае вывода типов) нельзя выдавать за преимущество. Если пугает опасность забыть типы функций в модуле — всегда есть возможность добавить аннотации типов. Но языки, которые требуют вводить типы на каждом шагу, как справку из ЖЭКа, морально устарели.
Может быть (хотя я пока так не думаю).
Но вот если взглянуть с другой стороны:
std::auto_ptr< io_controller_t > c = make_io_controller( params );
c->flush_all();
Ведь здесь есть факт двойного соглашения -- с одной стороны, make_io_controller обязуется отдать мне объект, который может быть приведен к std::auto_ptr<io_controller_t>. С другой стороны, я явно объявляю, что в этом месте мне нужен именно std::auto_ptr<io_controller_t>, а не что-нибудь другое. Поэтому компилятор бьет меня по рукам при нарушении соглашения с любой из сторон.
Если бы у меня была конструкция:
auto c = make_io_controller( params );
c->flush_all();
то при смене типа возвращаемого значения у make_io_controller я об этом даже не узнаю -- компилятор просто сделает c нужного типа и все.
Например, такой сценарий: make_io_controller стал возвращать не auto_ptr, а io_controller_t*. Если мой код об этом не узнает, то я не буду удалять объекты io_controller_t.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[9]: Философический вопрос про автоматический вывод типов.
Здравствуйте, eao197, Вы писали:
E>Но вот если взглянуть с другой стороны: E>
E>std::auto_ptr< io_controller_t > c = make_io_controller( params );
c->>flush_all();
E>
E>Ведь здесь есть факт двойного соглашения -- с одной стороны, make_io_controller обязуется отдать мне объект, который может быть приведен к std::auto_ptr<io_controller_t>. С другой стороны, я явно объявляю, что в этом месте мне нужен именно std::auto_ptr<io_controller_t>, а не что-нибудь другое. Поэтому компилятор бьет меня по рукам при нарушении соглашения с любой из сторон. E>Если бы у меня была конструкция: E>
E>auto c = make_io_controller( params );
c->>flush_all();
E>
E>то при смене типа возвращаемого значения у make_io_controller я об этом даже не узнаю -- компилятор просто сделает c нужного типа и все. E>Например, такой сценарий: make_io_controller стал возвращать не auto_ptr, а io_controller_t*. Если мой код об этом не узнает, то я не буду удалять объекты io_controller_t.
Это особенности C++. Попробуй придумать пример, не связанный с ручным управлением памятью и приведением типов .
Если серьезно, вернемся к классическим определениям. АТД определяется множеством операций, которые над ним можно выполнять. flush_all и есть такая операция. Поэтому менять тип make_io_controller как угодно не удастся.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[10]: Философический вопрос про автоматический вывод типов
Здравствуйте, Programmierer AG, Вы писали:
PA>Это особенности C++. Попробуй придумать пример, не связанный с ручным управлением памятью и приведением типов .
Приведение типов как раз возможно в языках со сборкой мусора, например, множественное наследование интерфейсов.
PA>Если серьезно, вернемся к классическим определениям. АТД определяется множеством операций, которые над ним можно выполнять. flush_all и есть такая операция. Поэтому менять тип make_io_controller как угодно не удастся.
А тебе не кажется, что это уже duck typing начинается?
Т.е., если я сменю тип возвращаемого значения на другой, в котором есть метод flush_all (возможно случайно), то все нормально?
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[8]: Философический вопрос про автоматический вывод типов.
Здравствуйте, eao197, Вы писали:
E>Но, насколько я понял, в Nemerle в nested functions можно не указывать типы параметрам и возвращаемому значению. В таких случаях запись в Nemerle визуально не сильно отличается от записи в Ruby или Python. Разница только в том, в какой момент времени тебя предупредят об ошибке, если ты ошибся -- во время компиляции или исполнения. Но на момент написания кода подсказок-то нет (разве что IDE будет очень умная).
Как мне думается, особых мозгов от IDE это не потребует, так как все равно придется пользовать компилятор как библиотеку.
Но ведь есть еще и макросы, меняющие синтаксис. Вот тут надо будет много думать.
--
Re[8]: Философический вопрос про автоматический вывод типов.
Здравствуйте, eao197, Вы писали:
E>Но, насколько я понял, в Nemerle в nested functions можно не указывать типы параметрам и возвращаемому значению. В таких случаях запись в Nemerle визуально не сильно отличается от записи в Ruby или Python.
Ключевое — визуально. Разница существенная. E>Разница только в том, в какой момент времени тебя предупредят об ошибке, если ты ошибся -- во время компиляции или исполнения.
Этого недостаточно?
По-моему, до появления generic'ов в дотнете и яве это был один из очень сильных аргументов в пользу STL против соответствующих библиотек дотнета и явы.
В C++ вообще очень любят как можно больше делать на этапе компиляции, и это правильно — вспомним CT-assert'ы, concept check libraries и т.д. Ты сам это прекрасно знаешь, не лукавь . E>Но на момент написания кода подсказок-то нет (разве что IDE будет очень умная).
Для качественных подсказок IDE должна выполнять львиную долю работы компилятора или быть с компилятором интегрирована, и в данном случае ничего не меняется. Когда я использую злые шаблоны с частичными специализациями, вложенные типы и пространства имен, я тоже часто остаюсь без подсказки.
PA>>На IDE внимание акцентирует только Влад, не надо обобщать. E>Не только
Это особенность Windows-developer'ов, которые (включая меня) давно сидят на игле ИДЕ. Т.к. Немерле позиционируется как замена Шарпу, целевая аудитория у него такая — привыкшая к Студии, это не хорошо и не плохо, это факт. Вон Vermicious Knid, с другой стороны, пишет и не жалуется, получается как-будто здорово. Так что как аргумент против Немерла и вывода типов это не проходит.
PA>>Намекнуть, чем пользуются программисты на Лиспе, ML, Erlang, ...? E>Думаю, что emacs-ом, но неужели VisualStudio?
Угадал !
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[11]: Философический вопрос про автоматический вывод типов
eao197 wrote: > А тебе не кажется, что это уже duck typing начинается? > Т.е., если я сменю тип возвращаемого значения на другой, в котором есть > метод flush_all (возможно случайно), то все нормально?
А тут нам помогут концепты
Posted via RSDN NNTP Server 2.0
Sapienti sat!
Re[9]: Философический вопрос про автоматический вывод типов.
Здравствуйте, Programmierer AG, Вы писали:
E>>Но, насколько я понял, в Nemerle в nested functions можно не указывать типы параметрам и возвращаемому значению. В таких случаях запись в Nemerle визуально не сильно отличается от записи в Ruby или Python. PA>Ключевое — визуально. Разница существенная.
Когда я пишу код, мне важно именно "визуальная" составляющая -- то, что мне видно в исходниках/документации.
E>>Разница только в том, в какой момент времени тебя предупредят об ошибке, если ты ошибся -- во время компиляции или исполнения. PA>Этого недостаточно?
Достаточно для чего?
Чтобы совершить ошибку в коде и написать не правильное формирование тела отчета? Код уже написан. Вот что главное. И если мне компилятор скажет, что код не правильный, мне его придется переписывать точно так же, как если об ошибке сообщит unit-test.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[11]: Философический вопрос про автоматический вывод типов
PA>>Это особенности C++. Попробуй придумать пример, не связанный с ручным управлением памятью и приведением типов . E>Приведение типов как раз возможно в языках со сборкой мусора, например, множественное наследование интерфейсов.
При множественном наследовании интерфейсов ситуация (утечка памяти из-за неправильного объявления типа), которую ты описал в примере, невозможна. Во-вторых, языки со сборкой мусора!=Java. В-третьих, мы говорили о возможных опасностях вывода типов. Жду другого примера .
PA>>Если серьезно, вернемся к классическим определениям. АТД определяется множеством операций, которые над ним можно выполнять. flush_all и есть такая операция. Поэтому менять тип make_io_controller как угодно не удастся. E>А тебе не кажется, что это уже duck typing начинается?
Я предпочитаю теримн generic programming (как мне кажется, об утиной типизации только ruby-сообщество говорит). E>Т.е., если я сменю тип возвращаемого значения на другой, в котором есть метод flush_all (возможно случайно), то все нормально?
Если это ненормально, добавляем тип вручную. Если нормально, оставляем обобщенную реализацию и позволяем компилятору сделать грязную работу. Все просто .
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[5]: Философический вопрос про автоматический вывод типов.
Здравствуйте, Сергей Туленцев, Вы писали:
СТ>Думается мне, что eao197 говорил про то, как ты полезешь как-нибудь в исходники, которые ты писал год-полтора назад, и увидишь такую вот безличную картину. СТ>Как, без поддержки IDE, ты вспомнишь, кто что возвращает?
Сдается мне, что из кода и так все очевидно. Мне не нужно никаких других подсказок кроме знания о том, что int.Parse преобразует строку в число. Остальное мой мозг выведет все автоматически лучше любого компилятора. Ну, а в местах где это не так очевидно имеет смысл явно указать тип рпи объявлении переменной.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[10]: Философический вопрос про автоматический вывод типов
Здравствуйте, eao197, Вы писали:
E>>>Но, насколько я понял, в Nemerle в nested functions можно не указывать типы параметрам и возвращаемому значению. В таких случаях запись в Nemerle визуально не сильно отличается от записи в Ruby или Python. PA>>Ключевое — визуально. Разница существенная. E>Когда я пишу код, мне важно именно "визуальная" составляющая -- то, что мне видно в исходниках/документации.
В исходниках и документации содержится ровно то, что мы туда вносим. Если мы хотим там что-от видеть — мы беремся за клавиатуру и принимаемся стучать(еще раз рекомендую посмотреть на описания интерфейсов модулей в реальной программе на O'Caml). Но мы, труженики клавы и монитора, лучше других должны понимать, что наши любимые компьютеры служат для автоматизации рутинных действий и для повышения производительности нашего труда за счет освобождения мозгов для творческой работы. Если я пишу простую функцию вроде
let rec member list x =
match list with
[] -> false
head::tail -> if head=x then true
else member tail x;;
мне явные аннотации типов яснее код не сделают, и вбивать я их буду, проклиная тупой язык на чем свет стоит; а при чтении этого кода мне придется каждый раз отфильтровывать "синтаксический оверхед" от смысловой составляющей.
PA>>Этого недостаточно? E>Достаточно для чего? E>Чтобы совершить ошибку в коде и написать не правильное формирование тела отчета?
Я не знаю, о каких ошибках ты говоришь, и как они связаны именно с выводом типов. Не хочу флеймить по этому поводу, это похоже именно на боязнь паровозов, о которой писал Гапертон.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[12]: Философический вопрос про автоматический вывод типов
Здравствуйте, Programmierer AG, Вы писали:
PA>При множественном наследовании интерфейсов ситуация (утечка памяти из-за неправильного объявления типа), которую ты описал в примере, невозможна.
Смотри ширше (ширее). При множественном наследовании интерфейсов смена типа может сделать доступными методы из другого интерфейса, который не должен был бы быть доступен в данном месте.
PA> Во-вторых, языки со сборкой мусора!=Java.
А разве в C# нет множественного наследования интерфейсов?
PA> В-третьих, мы говорили о возможных опасностях вывода типов. Жду другого примера .
Если возвращается объект, реализующий несколько интерфейсов, то мы получаем доступ сразу ко всем из них. Если этот объект затем еще куда-то передается, то опять передается его реальный тип, а не интерфейс.
E>>А тебе не кажется, что это уже duck typing начинается? PA>Я предпочитаю теримн generic programming (как мне кажется, об утиной типизации только ruby-сообщество говорит).
Не только, такой же duck typing и в Python-е доступен.
E>>Т.е., если я сменю тип возвращаемого значения на другой, в котором есть метод flush_all (возможно случайно), то все нормально? PA>Если это ненормально, добавляем тип вручную.
Вот смысл в том, что ненормальность определится не в момент компиляции, а во время unit-тестов.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[6]: Философический вопрос про автоматический вывод типов.
static Dictionary<ZoomedFont.ZoomedFontKey, ZoomedFont> _fontMap =
new Dictionary<ZoomedFont.ZoomedFontKey, ZoomedFont>(
new ZoomedFontKey.ZoomedFontKeyComparer());
Хотел было описать Dictionary<ZoomedFont.ZoomedFontKey, ZoomedFont> в юсинге, да не тут то было. ZoomedFontKey — это вложенный приватный класс и за пределами ZoomedFont его не видно. Если бы вывод типов позволил бы мне хотя бы не писать "Dictionary<ZoomedFont.ZoomedFontKey, ZoomedFont>" два раза, я уже был бы рад.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: Философический вопрос про автоматический вывод типов.
Здравствуйте, Сергей Туленцев, Вы писали:
СТ>Как мне думается, особых мозгов от IDE это не потребует, так как все равно придется пользовать компилятор как библиотеку. СТ>Но ведь есть еще и макросы, меняющие синтаксис. Вот тут надо будет много думать.
Дык жто же этот самый компилятор не сможет с макросами разобраться?
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: Философический вопрос про автоматический вывод типов
Здравствуйте, Programmierer AG, Вы писали:
PA>(еще раз рекомендую посмотреть на описания интерфейсов модулей в реальной программе на O'Caml).
Посмотрел, похоже на h-файлы. Если это автоматом генерируется, то классно.
PA>мне явные аннотации типов яснее код не сделают, и вбивать я их буду, проклиная тупой язык на чем свет стоит; а при чтении этого кода мне придется каждый раз отфильтровывать "синтаксический оверхед" от смысловой составляющей.
В таком примере — да. Да только не часто лично мне приходится абстрактными списками оперировать. А вот чем-то подобным:
чуть ли не каждый день.
PA>Я не знаю, о каких ошибках ты говоришь, и как они связаны именно с выводом типов. Не хочу флеймить по этому поводу, это похоже именно на боязнь паровозов, о которой писал Гапертон.
Ошибка была простая -- возвращался Hash, где ключем было имя клиента, а значением -- другой Hash, в котором ключем было имя услуги, а значением -- количество транзакций. Поскольку ключи везде String-и, то я, перепутав, написал вывод отчета, который считал, что в первом хэше ключем является имя услуги, а во вложенных хешах -- имя клиента. Соответственно, не так считалось общее количество транзакций по клиенту. А все из-за того, что лень было тип сделать -- Report и методы getter-ы для него.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[7]: Философический вопрос про автоматический вывод типов.
VD> static Dictionary<ZoomedFont.ZoomedFontKey, ZoomedFont> _fontMap =
VD> new Dictionary<ZoomedFont.ZoomedFontKey, ZoomedFont>(
VD> new ZoomedFontKey.ZoomedFontKeyComparer());
VD>
VD>Хотел было описать Dictionary<ZoomedFont.ZoomedFontKey, ZoomedFont> в юсинге, да не тут то было. ZoomedFontKey — это вложенный приватный класс и за пределами ZoomedFont его не видно. Если бы вывод типов позволил бы мне хотя бы не писать "Dictionary<ZoomedFont.ZoomedFontKey, ZoomedFont>" два раза, я уже был бы рад.
Языками нормальными нужно пользоваться:
typedef Dictionary< ZoomedFont::ZoomedFontKey, ZoomedFont > Dict;
static Dict _fontMap = new Dict( new ZoomedFontKey::ZoomedFontKeyComparer() );
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[7]: Философический вопрос про автоматический вывод типов.
VladD2 wrote: > Хотел было описать Dictionary<ZoomedFont.ZoomedFontKey, ZoomedFont> в > юсинге, да не тут то было. ZoomedFontKey — это вложенный приватный класс > и за пределами ZoomedFont его не видно. Если бы вывод типов позволил бы > мне хотя бы не писать "Dictionary<ZoomedFont.ZoomedFontKey, ZoomedFont>" > два раза, я уже был бы рад.
Вам бы помогли typedef'ы
Posted via RSDN NNTP Server 2.0
Sapienti sat!
Re[8]: Философический вопрос про автоматический вывод типов.
G>Ну да. Я — ничего не перепутал. Еще что-нибудь сказать есть, кроме междометий?
Есть -- вообще-то в С++ при вызове шаблона функции поисходит вывод типа. Лет уже 15 как.
G>Это не идея. Это я на яблоках, прибегая к аналогиям, объясняюю, на что похож вывод типов в языках с системой Хиндли-Милнера. С расчетом на то, что до знающего С++ человека дойдет, зачем это надо. А ты все перепутал. В любом случае — если так не понятно, значит уже не вдолбить никак. По крайней мере, у меня идей больше нет, как объяснить.
Хамить не надо. Не умеешь объяснять доходчиво свои мысли -- лучше не пиши ничего.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Сергей Туленцев, Вы писали:
СТ>>Думается мне, что eao197 говорил про то, как ты полезешь как-нибудь в исходники, которые ты писал год-полтора назад, и увидишь такую вот безличную картину. СТ>>Как, без поддержки IDE, ты вспомнишь, кто что возвращает?
VD>Сдается мне, что из кода и так все очевидно. Мне не нужно никаких других подсказок кроме знания о том, что int.Parse преобразует строку в число. Остальное мой мозг выведет все автоматически лучше любого компилятора. Ну, а в местах где это не так очевидно имеет смысл явно указать тип рпи объявлении переменной.
Блин, мысли роятся, а облечь в слова не могу.
Кстати, новость не по топику: с недавних пор стала возможной конструкция
.
using(def x = SomeClass())
{
}
Раньше же приходилось писать так:
def x = SomeClass();
using(x)
{
}
Интересно, это оператор присваивания теперь возвращает значение? Или просто сделали исключение для юзинга. Пойду в исходниках посмотрю.
--
Re[10]: Философический вопрос про автоматический вывод типов
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Сергей Туленцев, Вы писали:
СТ>>Как мне думается, особых мозгов от IDE это не потребует, так как все равно придется пользовать компилятор как библиотеку. СТ>>Но ведь есть еще и макросы, меняющие синтаксис. Вот тут надо будет много думать.
VD>Дык жто же этот самый компилятор не сможет с макросами разобраться?
Дык, я не про то. Вот есть у тебя макрос while. Ну или поядреней — using.
Ты видишь using, а после прохода компилятором по этому месту там совершенно другой код.
А IDE, чтобы правильно и по месту показывать ошибки должна как-то с этим разбираться.
--
Re[7]: Философический вопрос про автоматический вывод типов.
Здравствуйте, Сергей Туленцев, Вы писали:
СТ>Интересно, это оператор присваивания теперь возвращает значение? Или просто сделали исключение для юзинга. Пойду в исходниках посмотрю.
Нет ничего криминального в том, что этот оператор возвращает значение. Источником проблем является тот факт, что некоторые (не будем показывать пальцем ) языки неявно приводят к bool все что под руку попадется.
... << RSDN@Home 1.1.4 stable rev. 510>>
Всех излечит, исцелит
добрый Ctrl+Alt+Delete
Re[13]: Философический вопрос про автоматический вывод типов
Здравствуйте, TK, Вы писали:
>> А Microsoft.VSDesigner namespace — это, по-твоему, недоразумение?
TK>Еще скажи, что в System.Data.dll это компилятор C# создал namespace <CppImplementationDetails> и namespace <CrtImplementationDetails>
Какая разница? До тех пор пока это на .NET это может быть хоть C#, хоть C++/CLI, хоть его предок-уродец MC++. У нас тут как всегда началось всё с одного, съехало на другое, а аргументы про третье.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[12]: Философический вопрос про автоматический вывод типов
Здравствуйте, eao197, Вы писали:
E>Здравствуйте, Programmierer AG, Вы писали:
PA>>(еще раз рекомендую посмотреть на описания интерфейсов модулей в реальной программе на O'Caml). E>Посмотрел, похоже на h-файлы. Если это автоматом генерируется, то классно.
Акцент был на то, что если хочется иметь код, документирующий интерфейс модуля, его можно создать, но это не является обязательным. Получить автоматически интерфейс из реализации — раз плюнуть, только после этого его обычно редактируют, чтобы убрать лишние детали реализации (служебные функции, определения типов, которые мы хотим спрятать, и т.д.) и добавить комментарии. Если бы он совсем автоматом генерировался, смысла бы в нем не было.
E>В таком примере — да. Да только не часто лично мне приходится абстрактными списками оперировать.
На самом деле мне тоже, все уже есть в библиотеке. Но простые вспомогательные функции ты пишешь каждый день, и в каждой вручную указываешь очевидные типы.
E>А вот чем-то подобным:
А теперь помечтаем, и удалим все лишнее, не теряя типобезопасности:
Красота!!
Неужели не согласен, что твоя функция пугает не потому, что она такая "системная", а потому, что все типы (с длинными "системными" именами) введены вручную?
E>Ошибка была простая -- возвращался Hash, где ключем было имя клиента, а значением -- другой Hash, в котором ключем было имя услуги, а значением -- количество транзакций. Поскольку ключи везде String-и, то я, перепутав, написал вывод отчета, который считал, что в первом хэше ключем является имя услуги, а во вложенных хешах -- имя клиента. Соответственно, не так считалось общее количество транзакций по клиенту. А все из-за того, что лень было тип сделать -- Report и методы getter-ы для него.
Т.е. грубо говоря, передали сантиметры вместо килограммов, когда и сантиметры, и килограммы были представлены значениями типа float. Если ты знаешь язык, который выявляет такие ошибки, дай знать . К выводу типов это отношения не имеет — ты эту ошибку получил без вывода типов.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[8]: Философический вопрос про автоматический вывод типов.
Здравствуйте, Дарней, Вы писали:
Д>Здравствуйте, Сергей Туленцев, Вы писали:
СТ>>Интересно, это оператор присваивания теперь возвращает значение? Или просто сделали исключение для юзинга. Пойду в исходниках посмотрю.
Д>Нет ничего криминального в том, что этот оператор возвращает значение. Источником проблем является тот факт, что некоторые (не будем показывать пальцем ) языки неявно приводят к bool все что под руку попадется.
Я так удивился потому, что раньше прочитал в документации, что оператор присвоения возвращает void, равно как и инкремент/декремент.
Стало быть, нельзя писать конструкций вида:
a = b = c;
d = ++e;
Зачем оно так было сделано — не знаю (особенно, если неявного приведения к bool нет), но верю, что были причины.
--
Re[8]: Философический вопрос про автоматический вывод типов.
Здравствуйте, Programmierer AG, Вы писали:
PA>А теперь помечтаем, и удалим все лишнее, не теряя типобезопасности:
<... красивый (без иронии) код поскипан ...> PA>Красота!!
Вот тебе красота, а мне жутко. Глядя на свой исходный код я понимал, что где возвращается и с кем я работаю. А здесь...
В общем, либо я не привык, либо я не пробовал
(кстати, за красоту всегда приходится расплачиваться, чем в данном случае?).
PA>Т.е. грубо говоря, передали сантиметры вместо килограммов, когда и сантиметры, и килограммы были представлены значениями типа float. Если ты знаешь язык, который выявляет такие ошибки, дай знать . К выводу типов это отношения не имеет — ты эту ошибку получил без вывода типов.
Если мне не отшибает память, в Modula-2 и Ada, а так же D, можно было назначать псевдонимы именам типов (вводить подтипы). При этом подтипы дальше существовали как отдельные типы, их нельзя было просто так смешивать с другими типами. Что-то вроде:
Здравствуйте, eao197, Вы писали:
E>(кстати, за красоту всегда приходится расплачиваться, чем в данном случае?).
Пока что придется расплачиваться отсутствием индустриальной поддержки, редкостью кадров, иногда — более низкой производительностью. Но все это не связано с выводом типов .
E>Если мне не отшибает память, в Modula-2 и Ada, а так же D, можно было назначать псевдонимы именам типов (вводить подтипы). При этом подтипы дальше существовали как отдельные типы, их нельзя было просто так смешивать с другими типами. Что-то вроде:
В C++ это тоже можно обойти, завернув данные в структуру, просто писанины больше. В ML есть 2 варианта: использовать вариантный тип или инкапсулировать тип в модуль. E>Все. Просто и надежно.
В большинстве случаев не так просто и надежно. Часто с данными производят какие-то вычисления (из пароля с именем юзера вполне можно посчитать какой-то хэш, ширину умножить на высоту и получить площадь и т.д.) — если типы намеренно делаются несовместимыми, работать с ними становится неудобно, в какой-то момент из обертки все равно нужно получить значения родных типов, и в этот момент их можно опять перепутать. Думаю, потому в большинстве библиотек, которые я видел, точки конструируются из пар чисел, а не из несовместимых типов XCoord, YCoord, а имя юзера и пароль передаются как строки.
И чтобы беседа окончательно не ушла в сторону, настойчиво резюмирую — вывод типов здесь не при чем.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[15]: Философический вопрос про автоматический вывод типов
Здравствуйте, Programmierer AG, Вы писали:
E>>Если мне не отшибает память, в Modula-2 и Ada, а так же D, можно было назначать псевдонимы именам типов (вводить подтипы). При этом подтипы дальше существовали как отдельные типы, их нельзя было просто так смешивать с другими типами. Что-то вроде: PA>В C++ это тоже можно обойти, завернув данные в структуру, просто писанины больше.
Т.е., фактически, не применимо на практике.
PA>В большинстве случаев не так просто и надежно. Часто с данными производят какие-то вычисления (из пароля с именем юзера вполне можно посчитать какой-то хэш, ширину умножить на высоту и получить площадь и т.д.) — если типы намеренно делаются несовместимыми, работать с ними становится неудобно, в какой-то момент из обертки все равно нужно получить значения родных типов, и в этот момент их можно опять перепутать.
Так в том-то и дело, что все моменты смешения подтипов требуют явного приведения типов. А это сразу бросается в глаза (по аналогии с рекомендацией использовать static_cast вместо приведения в стиле C в C++). И таких моментов, имхо, набирается не много.
PA> Думаю, потому в большинстве библиотек, которые я видел, точки конструируются из пар чисел, а не из несовместимых типов XCoord, YCoord, а имя юзера и пароль передаются как строки.
А тебе часто приходилось работать с Modula-2 или Ada библиотеками?
PA>И чтобы беседа окончательно не ушла в сторону, настойчиво резюмирую — вывод типов здесь не при чем.
Да я совершенно не против вывода типов. И уверен, что они всегда выводятся как нужно. (Это как всегда в программировании: программа всегда в точности делает то, что ей сказали. Другое дело, что программист не всегда понимает, что именно он говорит )
Я просто высказываю свое впечатление об одной из сторон программирования без явной декларации типов: только глядя на код не всегда понятно, с чем имеешь дело. В случае с OCaml на помощь привлекаются mil-файлы. В случае Ruby -- исходники того, что ты применяешь. Но, если показать человеку, который не совсем в теме, код:
Здравствуйте, Сергей Туленцев, Вы писали:
СТ>Дык, я не про то. Вот есть у тебя макрос while. Ну или поядреней — using. СТ>Ты видишь using, а после прохода компилятором по этому месту там совершенно другой код. СТ>А IDE, чтобы правильно и по месту показывать ошибки должна как-то с этим разбираться.
Хм. Ошибки вообще показывает компилятор. Если они врутри макроса, то он должен показать на макрос. Тут как раз все просто.
Друное дело с комплитом. Макросы могут добавлять, удалять или менять AST. Хорошо бы чтобы при этом IDE отображала реальную картину в реальном времени. Ну, например, добавил я атрибут [XmlSerialize] который приводит к добавлению в класс двух методов — SaveXml() и LoadXml(). Вот хотелось бы, чтобы IDE позволяло эти методы закомплитить.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Философический вопрос про автоматический вывод типов.
Здравствуйте, Cyberax, Вы писали:
C>Вам бы помогли typedef'ы
Мне бы помог вывод типов. А typedef перед единственным использованием особо ничем помочь не сможет. Хотя в общем, действительно нечто вроде локального и совсем глобального (на проект) using-а было бы удобно иметь.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: Философический вопрос про автоматический вывод типов.
Здравствуйте, Шахтер, Вы писали:
Ш>Здравствуйте, Gaperton, Вы писали:
G>>Ну да. Я — ничего не перепутал. Еще что-нибудь сказать есть, кроме междометий?
Ш>Есть -- вообще-то в С++ при вызове шаблона функции поисходит вывод типа. Лет уже 15 как.
Под выводом типа во всей ветке имеется в виду вывод типа в функции вне конектса вызова. Этого в С++ нет. Лет 15 как. И еще лет 15 не будет. О том, что проверка типов выполняется при инстанциации (то что там происходит, выводом типов назвать язык не поворачивается), я написал. Хватит цепляться к словам.
G>>Это не идея. Это я на яблоках, прибегая к аналогиям, объясняюю, на что похож вывод типов в языках с системой Хиндли-Милнера. С расчетом на то, что до знающего С++ человека дойдет, зачем это надо. А ты все перепутал. В любом случае — если так не понятно, значит уже не вдолбить никак. По крайней мере, у меня идей больше нет, как объяснить.
Ш>Хамить не надо. Не умеешь объяснять доходчиво свои мысли -- лучше не пиши ничего.
Если ты не считаешь объяснения "доходчивым" — это не трагедия, и вовсе не повод объяснений не давать. Извини, я объясняю свои мысли так, как умею. И спрашивать у тебя разрешения на объяснения не собираюсь, как и спорить с тобой. Кто хочет понять — поймет, или задаст конкретный уточняющий вопрос. Ему я объясню.
Re[10]: Философический вопрос про автоматический вывод типов
Здравствуйте, Gaperton, Вы писали:
G>Под выводом типа во всей ветке имеется в виду вывод типа в функции вне конектса вызова. Этого в С++ нет. Лет 15 как. И еще лет 15 не будет. О том, что проверка типов выполняется при инстанциации (то что там происходит, выводом типов назвать язык не поворачивается), я написал. Хватит цепляться к словам.
Конечно, вывода типов в духе ML или, пуще того, Haskell, в C++ нет и не будет.
Но справедливости ради следует признать, что при инстанциации шаблонов выполняется не только проверка типов, а нечто большее — подходящая функция или перегруженный оператор при компиляции повыражения выбирается на основании правил перегрузки, на основании ее типа определяется тип подвыражения с вызовом, и процесс повторяется рекурсивно — тип результирующего выражения может получиться довольно сложным, и семантика выражения зависит именно от выведенных таким образом типов — наиболее ярко это проявляется в expression templates. Конечно, сравнивать C++ с ФЯ, где вся программа является выражением, смысла нет.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[11]: Философический вопрос про автоматический вывод типов
Здравствуйте, Programmierer AG, Вы писали:
PA>Конечно, вывода типов в духе ML или, пуще того, Haskell, в C++ нет и не будет. PA>Но справедливости ради следует признать, что при инстанциации шаблонов выполняется не только проверка типов, а нечто большее — подходящая функция или перегруженный оператор при компиляции повыражения выбирается на основании правил перегрузки, на основании ее типа определяется тип подвыражения с вызовом, и процесс повторяется рекурсивно — тип результирующего выражения может получиться довольно сложным, и семантика выражения зависит именно от выведенных таким образом типов — наиболее ярко это проявляется в expression templates. Конечно, сравнивать C++ с ФЯ, где вся программа является выражением, смысла нет.
Признавать или не признавать тут нечего. Я неплохо знаю С++, 6 лет на нем пишу, знаю, что это так и есть , и не имею ни малейшего желания обсуждать С++. Потому что в этой ветке под "автоматическим выводом типов" понимается совсем другое. А именно — то, как это делается в Nemerle и ML (вывод параметрического типа функции/выражения вне контекста вызова, без явных аннотаций типа).
То, что в С++ "тоже есть, с таким же названием, но только совсем не то" — второстепенный и не относящийся к делу момент.
Re[12]: Философический вопрос про автоматический вывод типов
Здравствуйте, VladD2, Вы писали:
VD>Кстати, больше всего меня смущало в ФЯ, то что их принципы входят в противоречие с принципами ООП. А ООП я и сейчас считаю одним из самых мощных инструментов для решения сложных задач.
Оно так и есть. Как электронщик я провожу четкую аналогию ООП с цифровой электроникой, а ФЯ — с аналоговой. Причем, сходство методов проектирования, шаблонов проектирования, способов декомпозиции и т.д. в обоих случаях просто потрясающее м/у программной индустрией и аппаратной. Складывается впечатление, что ПО-отрасль "в лоб" переняла наработки железячников по принципам (общему видению), подходам к разработке и способами манипулирования абстракциями. (И кстати, цифровые системы обработки сигналов по архитектуре с "высоты птичьего полета" более близки, все-таки, к аналоговым системам)
VD>"объекты имеют свое состояние модифицируемое посредством методов"? Слова вроде "так при модификации могут порождаться новые объекты" выглядят совсем не убедительно. Однако я же не фанатик ФЯ? Так почему я должен принимать идею о том, что модификация состояния — это зло? Темболее, что декларативность достигаемая в ФЯ отнюдь не заключена в немодифицируемости. Она скорее в другом. Она в том, что функции являются первоклассными сущностями, и в том, что с их помощью можно делать гибкую функциональную декомпозицию. В общем, функциональный взгляд на мир дает еще одно измерение.
Нет, все проще. Есть структурная (топологическая) декомпозиция (основа ООП), и есть функциональная (активно используемая при имплементации ООП). И они прекрасно уживаются и дополняют друг друга. (А с высоты причьего полета — являются одним и тем же. ИМХО — функциональность идет на первом месте, но мы ее реализуем с помощью "устройств"/объектов). Изменение состояний в "объектах" происходят в результате воздествия внешних сигналов. Однако, сами эти сигналы неплохо обрабатываются функциональными методами. Мне кажется вовсе непротиворечивой система, состоящая из "объектов", которые обмениваются сигналами (вызывают методы друг-друга, или реагируют на события друг/друга, последнее ближе к идеалу), причем на пути этих сигналов стоят всевозможные преобразователи функционального типа. Да и сами "кишки" объектов запросто могут быть выполнены как ячейки для хранения состояний, запись и извлечение информации в которые (из которых), или обновление значения в которых происходит после обработки внешних/внутренних сигналов функциональным образом.
В электронике эти два подхода уживаются великолепно и абсолютно гармонично, и, почему-то, никто не фанатеет за чисто-функциональный или чисто "объектный" стиль. Подобная тяга у некоторых программистов лишь в одну из сторон мне лично непонятна.
Более того, функциоанльные объекты (всякие фильтры, регуляторы, нелинейные преобразователи и т.д.) — это тоже объекты. Они могут иметь св-ва (параметры) и менять свое поведение в зависимости от этих параметров. (Близко к аналогии curring-functions в ФЯ).
--------
Идеальная программная система (похожая на электронные схемы ) — это набор объектов со св-вами и событиями БЕЗ публичных методов и набор функциональных объектов. Да, именно. У объектов — только св-ва и события. Объекты объединяются топологически путем подключения к событиями друг/друга. (Сами собятия могут обрабатываться/трансформироваться функциональным образом, причем как с помощью внешних, то бишь потенциально заменяемых функциональных объектов, так и с помощью внутренних, являющихся частью имплементации объекта... но это я уже повторяюсь).
Re[4]: Философический вопрос про автоматический вывод типов.
Здравствуйте, vdimas, Вы писали:
V>Идеальная программная система (похожая на электронные схемы ) — это набор объектов со св-вами и событиями БЕЗ публичных методов и набор функциональных объектов. Да, именно. У объектов — только св-ва и события. Объекты объединяются топологически путем подключения к событиями друг/друга. (Сами собятия могут обрабатываться/трансформироваться функциональным образом, причем как с помощью внешних, то бишь потенциально заменяемых функциональных объектов, так и с помощью внутренних, являющихся частью имплементации объекта... но это я уже повторяюсь).
А вот с этого места по подробней пожалуйста. Как это может выглядеть? Жилательно с псевдокодом.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[16]: Философический вопрос про автоматический вывод типов
Здравствуйте, IT, Вы писали:
ПК>>.NET используется только для Web. В продукт входит N приложений, в т.ч. и Web, вот штамп и стоит...
IT>Ну так с веба обычно всё плохое и начинается Сначала веб, потом серверок на .NET перепишите, а там и юайщики подтянутся
Знаешь, пока ЮАЙщикам на дотнет рановато, ей-богу. Блин, мне все-таки пришлось начать писать свою мини-либу для иерархий windowless-конролов, не дождавшись следующего поколения GUI на дотнете...
Ну а веб и сервачок — вполне...
Re[7]: Философический вопрос про автоматический вывод типов.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, eao197, Вы писали:
VD>Пример из кода который пишу прямо сейчас: VD>
VD> static Dictionary<ZoomedFont.ZoomedFontKey, ZoomedFont> _fontMap =
VD> new Dictionary<ZoomedFont.ZoomedFontKey, ZoomedFont>(
VD> new ZoomedFontKey.ZoomedFontKeyComparer());
VD>
А почему не так?:
static Dictionary<ZoomedFontKey, ZoomedFont> _fontMap =
new Dictionary<ZoomedFontKey, ZoomedFont>(
ZoomedFontKey.Comparer);
Если охота оставить ZoomedFont::ZoomedFontKey приватным классом, то _fontMap просится внутрь класса ZoomedFont, т.е. сам ZoomedFont надо снабдить статическими методами регистрации и использования экземплярами ZoomedFont. Если же охота сделать _fontMap внешним объектом, то можно было бы сделать ZoomedFontKey internal. Т.е. есть куча способов сократить запись.
А наиболее правильным представляется вообще так:
public class ZoomedFont {
...
private class Dictionary : Dictionary<ZoomedFontKey, ZoomedFont> {
public Dictionary() : base(ZoomedFontKey.Comparer) {}
}
Re[9]: Философический вопрос про автоматический вывод типов.
Здравствуйте, VladD2, Вы писали:
VD>Мне бы помог вывод типов. А typedef перед единственным использованием особо ничем помочь не сможет. Хотя в общем, действительно нечто вроде локального и совсем глобального (на проект) using-а было бы удобно иметь.
Я выкручиваюсь с помощью наследования от стандартных коллекций. Кстати, это неплохо помогает дополнительной декомпозиции (иногда требуется нечто более осмысленное, чем просто добавить/извлечь/найти) и к тому же позволяет насильно подавать нужные компареры и пр. параметры в конструкторы базового класса.
Re[10]: Философический вопрос про автоматический вывод типов
Здравствуйте, vdimas, Вы писали:
V>Я выкручиваюсь с помощью наследования от стандартных коллекций. Кстати, это неплохо помогает дополнительной декомпозиции (иногда требуется нечто более осмысленное, чем просто добавить/извлечь/найти) и к тому же позволяет насильно подавать нужные компареры и пр. параметры в конструкторы базового класса.
Я тоже... иногда... Но не всегда это приемлемо. От int не шибко понаследушся.
Кстати, в C# мне как раз больше всего не нравится, то что принцип "все является объектом" несколько не доведен до конца. Пергрузка операторов кривовата. Невозможность расширять функциональность value- и seale-тпов тоже не радует.
В общем, неплохо было бы ввести нечто вроде внешних интерфейсов и "особенностей". Первый должны являться чем-то похожим на концепты из будущего стандарта плюсов, а вторые это подключение реализации. Ведь как было бы здорво сделать нечто вроде:
interface IAdd<T>
{
T Add(T other);
}
// Применяется везде гда int используется в качестве параметра типа.
// Так как int выэлью-тип, то все вызовы инлайнятся и никаких
// непроизводительных расходов не возникает.
traits IntAdd<int> : IAdd<int>
{
int _value;
piblic IntAdd(int value) { _value = value; }
piblic int Add(int other) { return _value + other; }
}
...
class A
{
static T Sum<T>(IList<T> list, Func<T, T> adder)
where T: IAdd
{
T sum = defaulte(T);
foreach (T value in list)
sum = sum.Add(value);
return sum;
}
static void Main()
{
Console.WriteLine(Sum(int[] { 1, 3, 9 }));
Console.WriteLine(Sum(double[] { 3.2, 1.3, 2.0 }));
}
}
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Философический вопрос про автоматический вывод типов.
Здравствуйте, vdimas, Вы писали:
V>Нет, все проще. Есть структурная (топологическая) декомпозиция (основа ООП), и есть функциональная (активно используемая при имплементации ООП). И они прекрасно уживаются и дополняют друг друга.
Не очень то все хорошо уживается. Берем простой пример реализацию Set-а. Реализация его функциональном стиле неминуемо будет не эффективной. Ведь или мы будем вынуждены использовать связанные стписки, или будем пресоздавать внутнеррий контейнер при добавлении каждого элемента.
Так, что есть задачи которые принципильно не могут решаться в функциональном виде эффективно.
По сути функциональное программирование названо не врено. Его следовало бы назвать "Программирование Ориентированные на вычисление выражений". Пока мы занимаемся вычислениями мы можем эффективно записывать код в виде выражений. Но как только мы начинаем вести речь о состоянии, то сразу приходим к модификации памяти и следовательно к отказу от ориентации на выражения. Держась за догмы мы вынуждены копировать объекты, и как следствие неменуемо теряем в производительности.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Философический вопрос про автоматический вывод типов.
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, vdimas, Вы писали:
V>>Идеальная программная система (похожая на электронные схемы ) — это набор объектов со св-вами и событиями БЕЗ публичных методов и набор функциональных объектов. Да, именно. У объектов — только св-ва и события. Объекты объединяются топологически путем подключения к событиями друг/друга. (Сами собятия могут обрабатываться/трансформироваться функциональным образом, причем как с помощью внешних, то бишь потенциально заменяемых функциональных объектов, так и с помощью внутренних, являющихся частью имплементации объекта... но это я уже повторяюсь). WH>А вот с этого места по подробней пожалуйста. Как это может выглядеть? Жилательно с псевдокодом.
Сейчас нафантазирую:
Итак. Давай действительно попытаемся представить, почему электронщики умудряются делать довольно сложные устройства "не написав ни строчки кода", т.е. не изготавливая самих мискросхем и прочих деталей, а только лишь топологически соединяя их и выставляя им режимы работы (присваивая значения св-вам). Очевидно от того, что компоненты аппаратуры представлены как наборы пинов — входных и выходных, таких, что эти пины можно по всячески соединять (избегая разве что КЗ )
какие бывают выходные пины:
1. "непрерывного" характера, т.е. такие, на которых в любой момент времени можно получить текущее значение (ближе к аналоговой электронике)
Работать с такими пинами можно по способу pull, т.е. "тянуть" из них значение.
2. сигнального типа, т.е. такие, на которых появляются достоверные сигналы лишь в определенные моменты времени (по такту таймера или в результате прохождения и обработки других внешних сигналов/тактов — ближе к цифровой электронике)
такие пины могут работать как push, т.е. являться источником или распространителем сигнала (события).
Выходной пин первого типа можно описать так:
public interface IValuePin<T> {
T Value { get;}
}
Соответственно, парный ему входной "пин" — это просто св-во объекта соотв. типа:
public class SomeClass {
private IValuePin<int> _input1;
public IValuePin<int> Input1 {
get { return null; }
set {
if(_input1!=value) {
_input1 = value;
OnPin1Changed();
}
}
}
protected void OnPin1Changed() { /* ... */ }
};
(OnPin1Changed — весьма такой опциональный момент...)
Почему бы "просто не соединить" get_XXX св-во одного компонента с set_YYY св-вом другого компонента? Потому как не существует способа "простого" соединения обычных св-в м/у собой. Весь этот DataBinding в дотнете пляшет как раз вокруг обсуждаемых здесь вещей. но пляшет тупо, коряво, неочевидно и вообще он зашел не с той стороны, напрямую унаследовав биндинг из VB. Для передачи значений м/у св-вами в DataBinding сейчас используются "дополнительные" нотифицирующие события, которые должны отвечать определенным name conventions... для нашего случая в Databinding надо было бы добавить событие "XXXChanging" — для нотификации о необходимости валидации и "XXXChanged" для собственно запуска механизма передачи данных.
Фиг с ним, продолжаем!
В нашей схеме ничего такого не требуется, потому как пины спроектированы именно для того, чтобы напрямую подключаться к друг-другу, без рефлексии, проперти-дескрипторов и всяких неочевидных name conventions.
Пин второго типа можно описать примерно так:
public interface ISignalPin<T> {
event Action<T> Signal;
}
Соответственно, входной пин для второго варианта — это публичное св-во типа Action<T>:
public class AnotherClass {
protected void OnPin1(double value) { }
public Action<double> Pin1 {
get { return OnPin1; }
}
}
Но это только один из путей для реализации второго варианта. Выходной пин — это может быть просто некое произвольное событие. Соответствующий ему входной пин — это соответствующие по типу св-во делегат, аналогично реализованному в классе AnotherClass.
Именно тут кстати, может возникнуть вопрос — а нахрена выставлять св-ва делегаты в виде пинов, если открытые публичные методы можно использовать с тем же успехом, т.е. использовать их как входные "пины" сигналов. Разница здесь в том, что в этом случае мы можем легко организовать "КЗ", т.е. вне ведома компонента подать на его входной пин, то бишь публичный метод, несколько несогласованных сигналов от разных источников. Пусть согласованием сигналов занимается сам компонент внутри себя и выставляет столько входных пинов, на сколько реально был спроектирован. Например, в реализации класса AnotherClass каждый раз создается новый входной пин при вызове get_Pin1, т.е. допускается произвольное кол-во подключений. Однако, можно было создать закешировать лишь один экземпляр делегата внутри класса и возвращать именно его.
В самом начале обсуждения подумалось — но ведь должны же быть публичные методы хотя бы для манипулирования структурой, например для воссоздания иерархии окошек в GUI, где банально требуются коллекции и методы по управлению содержимым коллекций... продолжая прикалываться можно предложить такое:
Ты даже можешь подключиться к выходному пину Count, и будешь знать, когда кол-во элементов изменилось.
В принципе, никто не мешает сделать комбинированный пин:
public interface ISignalValuePin<T> : ISignalPin<T>, IValuePin<T> {}
В коллекциях св-во Count могло быть именно такого комбинированного типа. Т.е. мы сможем в любой момент прочитать значение св-ва, точно так же как подписаться на сигнал об изменении оного.
Вот еще разминка к такой коллекции:
public delegate bool Predicate<T>(T value);
public class Filter<T> : ISignalPin<T> {
Predicate<T> _predicate;
public Filter(Action<T> action, Predicate<T> p) {
_predicate = p;
Signal += action;
}
public Predicate<T> Predicate {
get { return _predicate; }
set { _predicate = value; }
}
void OnInput(T value) {
if (_predicate(value))
Signal(value);
}
public Action<T> Input {
get { return OnInput; }
}
public event Action<T> Signal;
}
/** filter demonstration */public class Device {
ICollection<int> _collection;
private void ActionNotNegative(Action<int> action) {
_collection.ForEach(
new Filter<int>(action, delegate(int i) { return i > 0; }).Input
);
}
};
Для ForEach можно лепить произвольные наборы фильтров и предикатов. Схема немного упрощена, вообще-то надо было бы использовать IValuePin<Predicate<T>> Predicate { get; } и IValuePin<Action<T>> Input { get; }
Тогда тело приватного метода Device::ActionNotNegative могло бы сформировано чисто "топологическим" образом без кодирования.
-------
пока хватит — это для затравки. Много еще чего можно придумать, еще обыграть нотификаторы, другие предикаты, многовходовые фильтры и процессоры сигналов (Convert<T1, T2>) и пр и пр. Интересно, а получиться ли составлять (не писать) программы, если нашлепать приличное кол-во подобных кирпичиков на основе неких подобных соглашений?
Из кирпичиков нижнего уровня можно выкладывать кирпичики высокого уровня и т.д.
--------
Визуальный дизайнер мог бы отличать обычные св-ва от входных и выходных пинов по сигнатурам и реализуемым интерфейсам:
IValuePin<T> { get; set; } // входной пин
IValuePin<T> { get; } // выходной пин
Action<T> { get; } // входной пин
ISignalPin<T> { get; } // выходной пин
ISignalValuePin<T> { get; } // комбинированный выходной пин
Re[6]: Философический вопрос про автоматический вывод типов.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, vdimas, Вы писали:
V>>Нет, все проще. Есть структурная (топологическая) декомпозиция (основа ООП), и есть функциональная (активно используемая при имплементации ООП). И они прекрасно уживаются и дополняют друг друга.
VD>Не очень то все хорошо уживается. Берем простой пример реализацию Set-а. Реализация его функциональном стиле неминуемо будет не эффективной. Ведь или мы будем вынуждены использовать связанные стписки, или будем пресоздавать внутнеррий контейнер при добавлении каждого элемента. VD>Так, что есть задачи которые принципильно не могут решаться в функциональном виде эффективно.
А зачем реализовывать Set в функциональном стиле???? Ты все-таки не понял мою мысль. Те "объекты" программируемых абстракций, которые априори имеют состояния (и ячейки памяти, их хранящие), не могут быть выражены в чисто-функциональном стиле. Я рассматриваю функциональный стиль как фильтрацию, процессинг сигналов и т.д. Этот стиль замечательно пригоден для функциональной декомпозиции и является отличным дополнением при реализации абстракций реального мира, которые все-таки, легче представлять в виде объектов с памятью (состоянием), как наилучшим образом соотвествующих этим объектам.
VD>По сути функциональное программирование названо не врено. Его следовало бы назвать "Программирование Ориентированные на вычисление выражений". Пока мы занимаемся вычислениями мы можем эффективно записывать код в виде выражений. Но как только мы начинаем вести речь о состоянии, то сразу приходим к модификации памяти и следовательно к отказу от ориентации на выражения.
Да не надо ни на что ориентироваться. Вот у тебя стоит задача модифицировать специальным сложным образом 21-ю ячейку памяти объекта в сложной зависимости от значений других 20-ти. Для написания процедуры модификации лучше всего подходит именно функциональный стиль. Результат последней вычисления последней ф-ии закидываешь в требуемую ячейку. Где нестыковка? Только в том, что некоторые считают, что это отходит от догм?
Функциональный стиль, ИМХО, должен на всю катушку использоваться для имплементации моделей ООП (ОО — модель, ФС — вычисления, производимые в процессе жизни модели, что не так? Модель должна согласованно переходить из состояние в состояние, а сами ф-ии переходов... да именно, могут и должны быть выражены в виде ф-ий).
VD>Держась за догмы мы вынуждены копировать объекты, и как следствие неменуемо теряем в производительности.
Вообще-то, это все действительно догмы. Почему функциональные языки именно копируют объекты? Из-за банальной гарантии согласованного изменения значений. Таким образом они лишь гарантируют, что данный экземпляр значения существует лишь в текущем потоке исполнения и ему не грозит несогласованное изменение. Т.е. тут даже речь не просто о модификации памяти, а об ограничении этой модификации локальным контекстом. Но как раз именно этот момент скорее из разряда обеспечения безопасности/верифицируемости/оптимизируемости, чем из разряда функционального программирования. Например, ты запросто можешь писать на Лиспе в чисто-функционалдьном стиле, не используя императивных расширений, и при этом писать код, который модифицирует общедоступные объекты в памяти (как собственно на нем и пишут).
Далее. на том же Haskell есть бинды к GUI. Что это означает? Это означает, что где-то в памяти все-таки находятся общие объекты. А ф-ии Haskell передают/копируют друг-другу не сами объекты, а их прокси/хендлы. Вот тебе, блин, большая разница и способы уклонения от догм на блюдечке прямо от "производителей" этих догм.
Re[17]: Философический вопрос про автоматический вывод типов
Здравствуйте, vdimas, Вы писали:
V>А зачем реализовывать Set в функциональном стиле????
Незнаю. Я многого не знаю. Вот, к примеру, не знаю зачем цитировать все что к делу не относится, но ты же это делашь? Вот точно так же не знаю зачем реализовывать Set в функциональном стиле. Но прицедентов видел не мало.
V> Ты все-таки не понял мою мысль. Те "объекты" программируемых абстракций, которые априори имеют состояния (и ячейки памяти, их хранящие), не могут быть выражены в чисто-функциональном стиле.
Я значит не понял? Ты точлько что повторил мою мысль и объяснил мне, что я не понял какую-то твою мысль. Прямо как в том анегтоте про грузинов "спортэ мужчины!...".
V> Я рассматриваю функциональный стиль как фильтрацию, процессинг сигналов и т.д. Этот стиль замечательно пригоден для функциональной декомпозиции и является отличным дополнением при реализации абстракций реального мира, которые все-таки, легче представлять в виде объектов с памятью (состоянием), как наилучшим образом соотвествующих этим объектам.
Чистый функциональный подход декларирует полный отказ от модифицирующих присвоений. А не чистый по сути уже не является функциональным. Тут уже можно скорее говорить о применении функционального стиля в тех частях программы где это безболезненно походит. Собственно на поверку это оказываются именно рассчетные части поддающиеся закладке в выражение.
VD>>По сути функциональное программирование названо не врено. Его следовало бы назвать "Программирование Ориентированные на вычисление выражений". Пока мы занимаемся вычислениями мы можем эффективно записывать код в виде выражений. Но как только мы начинаем вести речь о состоянии, то сразу приходим к модификации памяти и следовательно к отказу от ориентации на выражения.
V>Да не надо ни на что ориентироваться. Вот у тебя стоит задача модифицировать специальным сложным образом 21-ю ячейку памяти объекта в сложной зависимости от значений других 20-ти.
Так у меня задачи никогда не ставлись. Задачи ставятся по другому. Есть объект и есть его состояние. Изменение состояния эффективно отражается присвоением значений. А это отрицается догмами ФЯ.
V> Для написания процедуры модификации лучше всего подходит именно функциональный стиль.
Модификация автоматически приводит к тому, что мы нарушаем каноны функционального подхода. Что ты там понимаш себе под стилями я даже обсуждать не хочу. Я говорию о другом. Я говорю, о том, что чисто-функциональный подход — это догма приводящая к странным компромисам.
V> Результат последней вычисления последней ф-ии закидываешь в требуемую ячейку.
Это и есть императивный подход.
V> Где нестыковка? Только в том, что некоторые считают, что это отходит от догм?
Нестыковка в том, что функциональный подход отрицает "закидывание в ячейку". Вместо этого я должен скопировать все что связано с этой ячейкой и породить новый объект.
V>Функциональный стиль, ИМХО, должен на всю катушку использоваться для имплементации моделей ООП (ОО — модель, ФС — вычисления, производимые в процессе жизни модели, что не так?
Я не знаю кто такие имплементации. А повторять банальности уже устал.
V> Модель должна согласованно переходить из состояние в состояние, а сами ф-ии переходов... да именно, могут и должны быть выражены в виде ф-ий).
Функции я без проблем могу иметь в императивном коде. Функциональный подход же отрицает модификацию на всех стадиях. Или это уже не ФП. Это еже гибрид. Причем, заметь, я не только за такой гибрид. И по сути я с тобой согласен. Вот только это не ФП. ФП же подразумевает, что модификаций нет вообще. Правда любая реальная реализация даже самых чистых ФЯ обязательно оставляет лазейку для нарушения своих принцпов (вроде монад в Хаскеле). Но это дело десятое. Главное, что при пропаганде ФП без зазрения совести идут расуждения, о том, что модификация некой структуры вроде Set-а приводит к порождению нового Set-а. И мол, умный компилятор сом разберется не произвести ли незаметной модификации (так сказать, за кулисами). Но это в общем-то надежда на случай. Да и не ясно зачем все это.
VD>>Держась за догмы мы вынуждены копировать объекты, и как следствие неменуемо теряем в производительности.
V>Вообще-то, это все действительно догмы. Почему функциональные языки именно копируют объекты? Из-за банальной гарантии согласованного изменения значений. Таким образом они лишь гарантируют, что данный экземпляр значения существует лишь в текущем потоке исполнения и ему не грозит несогласованное изменение.
А, ну, да. Это видимо догмы у меня о ФЯ. А не в ФЯ. Ясно. Всегда проще найти недостаток в оппоненте, чем в его словах.
V>Т.е. тут даже речь не просто о модификации памяти, а об ограничении этой модификации локальным контекстом. Но как раз именно этот момент скорее из разряда обеспечения безопасности/верифицируемости/оптимизируемости, чем из разряда функционального программирования.
Нет уж. Многие программы не могут быть выражены в виде одного выражения как это постулируеют принцыпы ФП. Есть и объекты разделяемые разными потоками. Есть и глобальные сущьности. Есть и банально осязаемые вещи вроде форм. Просто глупо представлять, что при изменении свойства формы создается какая-то копия формы, а старая уничтожается за ненадобность. От того слова типа, что умный компилятор что-то там соптимизирует мнея уже не волнуют. Для меня маразматичны сами рассуждения, о копировании объектов с целью модификации их состояния.
Это я извенясю подмена причины следствием.
Объект есть объект. Он существует во времени и изменяет свое состояние. Объект == экземпляр. И не нужно выдумывать концепций нарушающих это.
Конечно есть неизменяемые объекты над которыми можно производить вычисления получая новые копии этих объектов. Такие объекты не редкость в мире ООП. Те же строки или шрифты в дотнете является тому прекрасным подтверждением. Но кроме таких объектов есть еще формы, словари и тысячи других классов объектов для которых идея неизменяемости неприминима.
И лично я толко за если для работы с незименяемыми объектами будет тот самый ФС (стиль, т.е.). Но я против искуственный извращений при работе с теми самыми изменяемыми объектами.
К тому же я не вижу проблем в модифицирующих присвоениях. Они скорее мешают несбалансированной идеолгии нежели реально являеются проблемой сами.
V> Например, ты запросто можешь писать на Лиспе в чисто-функционалдьном стиле, не используя императивных расширений, и при этом писать код, который модифицирует общедоступные объекты в памяти (как собственно на нем и пишут).
Нет не могу. Любое изменение состояние есть уход от тех самых догм ФП. А то, что так делают — это лишь доказательство ошибочности этих догм.
V>Далее. на том же Haskell есть бинды к GUI. Что это означает?
Что в Хаскель встроены лазейки позволющие забить на догмы и таки умудриться вывернутся. Просто Хаскеле пытается демонстрировать особую чистоту рядов и вместо того, чтобы допустить императивные конструкции вводит слабо-понятную (точноее вообще не понятную) идею монад. Как следствие возникает необходимость объяснять, что такое монады на уровне буддийских обрадов и пистики.
V> Это означает, что где-то в памяти все-таки находятся общие объекты. А ф-ии Haskell передают/копируют друг-другу не сами объекты, а их прокси/хендлы. Вот тебе, блин, большая разница и способы уклонения от догм на блюдечке прямо от "производителей" этих догм.
Это способы поддержания догм. Мне кажется, что ФЯ слишком идеологизированны, или даже скорее религизированы. Они превращаются в форменную веру. Программист как монах должен во что-то уверовать и чем-то пожертвовать чтобы приобщиться к миру верующих и достичь просветления.
А не проще ли смотреть на все прогматично? ФЯ есть огромное затяжное исследование. В нем было сделано немало наработок. Многие из них были очень успешными. Так почему бы не совместить эти нароботки с наработками в других областях и не получить те самые гибриды. Далее остается только перестать фыркать и создать четкое видение использования такого гибрида. Разобраться для решения каких задач лучше подходит тот или иной подход и применять наиболее подходящие для решения конкретных подзадачь подходы.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Философический вопрос про автоматический вывод типов.
Здравствуйте, VladD2, Вы писали:
VD>Не очень то все хорошо уживается. Берем простой пример реализацию Set-а. Реализация его функциональном стиле неминуемо будет не эффективной. Ведь или мы будем вынуждены использовать связанные стписки, или будем пресоздавать внутнеррий контейнер при добавлении каждого элемента. VD>Так, что есть задачи которые принципильно не могут решаться в функциональном виде эффективно.
Брось, в стандартной библиотеке всех ФЯ, которые я видел, есть чисто функциональная реализация множеств на чем-то вроде AVL- или Red-Black деревьев, в чем проблема?
VD>По сути функциональное программирование названо не врено. Его следовало бы назвать "Программирование Ориентированные на вычисление выражений". Пока мы занимаемся вычислениями мы можем эффективно записывать код в виде выражений. Но как только мы начинаем вести речь о состоянии, то сразу приходим к модификации памяти и следовательно к отказу от ориентации на выражения. Держась за догмы мы вынуждены копировать объекты, и как следствие неменуемо теряем в производительности.
Уже неоднократно говорилось, что реализация ФЯ может в случаях, когда это возможно, не делать лишних копий. Концептуально программа вычисляет новое множество, полученное из старого добавлением элемента, а физически происходит модификация памяти.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[8]: Философический вопрос про автоматический вывод типов.
VladD2,
VD>Это способы поддержания догм. Мне кажется, что ФЯ слишком идеологизированны, или даже скорее религизированы. Они превращаются в форменную веру. Программист как монах должен во что-то уверовать и чем-то пожертвовать чтобы приобщиться к миру верующих и достичь просветления.
Рубишь с плеча, ажно щепки летят во все стороны Lambda-вычисления (и как следствия функциональные языки) — это раздел математики. Математика — точная наука.
VladD2,
VD>Функции я без проблем могу иметь в императивном коде. Функциональный подход же отрицает модификацию на всех стадиях. Или это уже не ФП. Это еже гибрид.
Называй как хочешь, но прозрачность ссылок — это свойство языка, то есть (абстрактной) нотации, в большой степени характена именно для ФЯ. Реализация может быть (и будет, ибо архитектура x86) императивной. Во многих случаях будет тот же mutable state, только за шторками. Поясню:
A1 = modify(A0).
Если A0 ниже нигде не используется, то многие современные ФЯ (если не все) просто делают модификацию A0.
Если используется и A0, и A1, то можно предложить целую кучу путей:
1. Хранить и A0, и A1, для ссылки A0 использовать A0, для A1 -> A1
2. Хранить A0, и diff(A0,A1), для ссылки A0 использовать A0, для A1 - вычисление A0 + diff
3. То же самое, что и 2, только хранить A1.
4. Хранить некий промежуточный A_, diff(A0, A_), diff(A1, A_);
A0 -> A_ + diff(A0, A_), A1 -> A_ + diff(A1, A_)
Теоретических проблем для оптимизации нет, нужны только практические воплощения идей.
Наконец, функции с математической точки зрения — это преобразования. Элементы множества A отображаются на множество B. Всё.
Функции не обязаны заниматься созданием, копированием и какими-бы ни было манипуляции с областями памяти (которые называют объектами, что тоже является сильным сужением философского понятия "объект"). То, как реализуются функции в ЯП — это издержки реализации, не больше.
Здравствуйте, Programmierer AG, Вы писали:
PA>Брось, в стандартной библиотеке всех ФЯ, которые я видел, есть чисто функциональная реализация множеств на чем-то вроде AVL- или Red-Black деревьев, в чем проблема?
В том, что или они все же не чисто функциональные, или значительно менее эффективны нежели их императивные аналоги.
К тмоу же использование деревьев для Set-ов — это не лучшее решение. Тут нужно использовать хэш-таблицы.
PA>Уже неоднократно говорилось, что реализация ФЯ может в случаях, когда это возможно, не делать лишних копий.
Ключевые слова здесь "когда это возможно". К тому же таким продвинутым поведением обладают далеко не все компиляторы/рантаймы. Между тем совершенно не ясно в чем проблема использовать то же Set в императивном виде.
PA> Концептуально программа вычисляет новое множество, полученное из старого добавлением элемента, а физически происходит модификация памяти.
Физически получается так, что ради догм люди вынуждены получать не эффективные решения.
Ну, нет никаких проблем в модификации значений переменных если язык оберегает от реальных проблем.
Функциональный стиль мог бы стать хорошим дополнением в арсенале программиста, а сегодня он скорее является догмой и уделом едениц.
Все что нужно изменить — это заменить догму "модификация памяти — это зло", на более мягкое "многие вещи можно эффективно решать без модификации памяти".
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Философический вопрос про автоматический вывод типов.
Здравствуйте, VladD2, Вы писали:
VD>В том, что или они все же не чисто функциональные, или значительно менее эффективны нежели их императивные аналоги.
Устроим шустрик?
VD>К тмоу же использование деревьев для Set-ов — это не лучшее решение. Тут нужно использовать хэш-таблицы.
Эо уже вопрос десятый, ты говорил, что функциональные множества от рождения неэффективны. На C++, C# и Яве направо и налево применяются множества на деревьях.
PA>>Уже неоднократно говорилось, что реализация ФЯ может в случаях, когда это возможно, не делать лишних копий. VD>Ключевые слова здесь "когда это возможно".
Вызовы функций инлайнятся, когда это возможно. Засовывают переменную в регистр, когда это возможно. Заменяют хвостовую рекурсию циклом, когда это возможно. Аналогия просматривается?
VD> К тому же таким продвинутым поведением обладают далеко не все компиляторы/рантаймы. Между тем совершенно не ясно в чем проблема использовать то же Set в императивном виде.
Можно, используют. В том же Окамле есть хэш-таблицы, для практических целей их очень даже можно применять.
Просто в идеале от побочных эффектов хотелось бы избавиться, каша-то заварена именно для того, чтобы программы имели формальную семантику, позволяли статический анализ, автоматическое распараллеливание, верификацию и т.д. В угоду практичности, т.е. применимости языка сейчас, жертвуют долгосрочными целями.
А то, что чистые ф. языки не распространены, это хорошо, т.к. не приходится комитетам по 10 лет заседать, чтобы добавить сборку мусора, например. Это тестовые стенды для всех передовых идей в области проектирования ЯП, которые к тому же некоторые умудряются успешно применять сейчас. Ни о каких догмах речь не идет. Цель — не запретить эффекты и состояние вообще, а найти подходящую модель для них.
VD>Физически получается так, что ради догм люди вынуждены получать не эффективные решения.
Никто никого не вынуждает, и догмы, повторюсь, нет. А чисто функциональные деревья и списки очень даже пригодны и эффективны для ряда задач.
VD>Функциональный стиль мог бы стать хорошим дополнением в арсенале программиста, а сегодня он скорее является догмой и уделом едениц. VD>Все что нужно изменить — это заменить догму "модификация памяти — это зло", на более мягкое "многие вещи можно эффективно решать без модификации памяти".
Где эта догма высечена в камне, и зачем ее менять? Ведь в прогрессивных (на сегодня) ОКамле и Немерле так и сделано. Мало того, в Лиспе и стандартном МЛ то же самое — комбинируй функциональный стиль с императивным по самое не хочу. При должном умении программы получаются эффективные и выразительные, все довольны. Одно но: не все проблемы решены — автоматически параллелить нельзя, функции с побочными эффектами от чистых функций не отличить, и т.д и т.п. Поэтому исследования продолжаются, поэтому есть Хаскель, Clean и будут другие языки. Зачем с ними бороться?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[9]: Философический вопрос про автоматический вывод типов.
Здравствуйте, Lazy Cjow Rhrr, Вы писали:
LCR>Рубишь с плеча, ажно щепки летят во все стороны
Отнюдь. Просто излагаю что вижу.
LCR> Lambda-вычисления (и как следствия функциональные языки) — это раздел математики. Математика — точная наука.
Согласен. Причем тут ФЯ и их религия? Как видишь лямбды нефигово себя чувствуют в казалось бы насковзь императивных языках вроде C#. В С++ от них тоже никто бы не отказался.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: Философический вопрос про автоматический вывод типов.
Здравствуйте, Lazy Cjow Rhrr, Вы писали:
LCR>VladD2,
VD>>Функции я без проблем могу иметь в императивном коде. Функциональный подход же отрицает модификацию на всех стадиях. Или это уже не ФП. Это еже гибрид.
LCR>Называй как хочешь, но прозрачность ссылок — это свойство языка, то есть (абстрактной) нотации, в большой степени характена именно для ФЯ.
Дык и называю. И утверждаю, что "прозрачность ссылок" возводится в ФЯ в разряд догм.
LCR> Реализация может быть (и будет, ибо архитектура x86) императивной. Во многих случаях будет тот же mutable state, только за шторками. Поясню:...
Ненадо мне пояснять. Я все и так понимаю. Более того, я только за "низменяемость" если она ничего не стоит. Вот только в теории ФЯ все порят оговорки типа "во многих случаях". Не всегда можно действительно "за кулисами" превратить неэффективню операцию копирования в эффектинв модификации.
Между тем, если состояние нужно, то нет смысла с ним боросться.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: Философический вопрос про автоматический вывод типов
Странный у тебя был ответ. Я вообще-то не столько спорил с тобой, сколько соглашался в этих вопросах.
V>>Вообще-то, это все действительно догмы. Почему функциональные языки именно копируют объекты? Из-за банальной гарантии согласованного изменения значений. Таким образом они лишь гарантируют, что данный экземпляр значения существует лишь в текущем потоке исполнения и ему не грозит несогласованное изменение.
VD>А, ну, да. Это видимо догмы у меня о ФЯ. А не в ФЯ. Ясно. Всегда проще найти недостаток в оппоненте, чем в его словах.
Это ты не туда заехал. Я знаю, что догмы не у тебя, и лишь попытался обсуждать их причины (с тобой). Прочти этот абзац еще раз.
Ты упустил важный момент в моем посте. Я говорил еще о функциональной декомпозиции, которая существует наряду со структурной. У тебя ОЧЕНЬ БОЛЬШАЯ часть программы может быть выражена в том самом "чисто-функциональном" стиле. Но вот клиентом этой части может быть обычная императивная программа. И не надо говорить, что это уже будет не ФП. На определенном уровне декомпозиции у тебя может быть самый наичистейший ФП, а уж после того, как "чисто-функциональная" функция вернула результат, ей не все-равно ли, что с этим результатом делают?
V>>Т.е. тут даже речь не просто о модификации памяти, а об ограничении этой модификации локальным контекстом. Но как раз именно этот момент скорее из разряда обеспечения безопасности/верифицируемости/оптимизируемости, чем из разряда функционального программирования.
VD>Нет уж. Многие программы не могут быть выражены в виде одного выражения как это постулируеют принцыпы ФП. Есть и объекты разделяемые разными потоками. Есть и глобальные сущьности. Есть и банально осязаемые вещи вроде форм.
Блин, ты о чем? Я попытался обсуждать, разложить по полочкам причины догм, а не спорить с тобой, вообще-то. со всем этим я и так согласен. А главная причина догм весомая — общее увеличение надежности и верифицируемости программ. И в своем предыдущем посте высказывал мнение, что такой подход надо использовать на всю катушку. Я ведь тоже считаю, что моделировать задачи реального мира чаще всего лучше именно с помощью такой пары абстракций как "экземпляр" и "состояние". Однако, при этом настаиваю на применении наработок из лагеря ФЯ.
VD>Просто глупо представлять, что при изменении свойства формы создается какая-то копия формы, а старая уничтожается за ненадобность. От того слова типа, что умный компилятор что-то там соптимизирует мнея уже не волнуют. Для меня маразматичны сами рассуждения, о копировании объектов с целью модификации их состояния.
Да, да и еще раз да. Я с тобой не спорил, повторю.
VD>К тому же я не вижу проблем в модифицирующих присвоениях. Они скорее мешают несбалансированной идеолгии нежели реально являеются проблемой сами.
Модифицирующие присвоения тянут за собой еще несколько вещей:
— несогласованность изменений (всвязи с этим, мы не можем себе позволить агрессивную оптимизацию алгоритма на внутренних регистрах процессора)
— косвенная адресация (адресация по ссылке — источник половины всех сбоев)
В ФЯ даже если адресация физически выполнена как косвенная компилятором, с т.з. программиста мы работаем непосредственно со значением, т.е. нет шансов совершать ошибки адресации.
VD>А не проще ли смотреть на все прогматично? ФЯ есть огромное затяжное исследование. В нем было сделано немало наработок. Многие из них были очень успешными. Так почему бы не совместить эти нароботки с наработками в других областях и не получить те самые гибриды. Далее остается только перестать фыркать и создать четкое видение использования такого гибрида. Разобраться для решения каких задач лучше подходит тот или иной подход и применять наиболее подходящие для решения конкретных подзадачь подходы.
Хм... Очевидно, ты тоже не столько споришь, сколько соглашаешься
Я вижу возможность гладкого совмещения в активном использовании функциональной декомпозиции.
Re[9]: Философический вопрос про автоматический вывод типов.
LCR>Рубишь с плеча, ажно щепки летят во все стороны Lambda-вычисления (и как следствия функциональные языки) — это раздел математики. Математика — точная наука.
Скорее, это единственный раздел, который УДАЛОСЬ хорошо формализовать. Опять же, за счет нескольких простых допущений, которые оказались верны для замыканий.
Re[9]: Философический вопрос про автоматический вывод типов.
Здравствуйте, Programmierer AG, Вы писали:
VD>>В том, что или они все же не чисто функциональные, или значительно менее эффективны нежели их императивные аналоги. PA>Устроим шустрик?
Можно. Быстрая сортировка устроит?
VD>>К тмоу же использование деревьев для Set-ов — это не лучшее решение. Тут нужно использовать хэш-таблицы. PA>Эо уже вопрос десятый, ты говорил, что функциональные множества от рождения неэффективны. На C++, C# и Яве направо и налево применяются множества на деревьях.
В C# и Яве испльзуются в основном структуры на базе хэширования. Но это действительно дело десятое.
PA>Вызовы функций инлайнятся, когда это возможно. Засовывают переменную в регистр, когда это возможно. Заменяют хвостовую рекурсию циклом, когда это возможно. Аналогия просматривается?
Нет. Не просамтривается. Одно дело технические оптимизации. И совсем другое алгоритмические. Зачем мне понижать эффективность заменяя точно эффективную структуру на возможно эффективную структуру? Причем зачем это делать если я не вижу проблем от использования императивных конструкций для получения этой эффективности?
PA>Можно, используют. В том же Окамле есть хэш-таблицы, для практических целей их очень даже можно применять.
Вот о том и речь. Только вот с ОКамлом есть небольшая проблемка. Императивный стиль на нем выглядит уж больно убого. А вот в Нэмерле очень даже ничего.
PA>Просто в идеале от побочных эффектов хотелось бы избавиться, каша-то заварена именно для того, чтобы программы имели формальную семантику, позволяли статический анализ, автоматическое распараллеливание, верификацию и т.д. В угоду практичности, т.е. применимости языка сейчас, жертвуют долгосрочными целями.
Еще раз. Побочные эффекты — это самоцель фанатов ФП. Мне они не мешают. Я готов сам решать нужны они мне и если не нужны, то как их избегать (в ФС или ИС). Если я считаю, что эффективность не упадет, то выберу ФС так как этот стиль потенциально более компактен и безопасен. Если же, например, профайлер мне показал, что код стал узким местом, то я просто перейду к императивному стилю и добьюсь нужной эффективности.
Вот такой расклад мне подходит. А во что бы то не стало использовать ФС я не хочу. Мне нужа гибкость, а не оптимальность по одному критерию.
PA>А то, что чистые ф. языки не распространены, это хорошо, т.к. не приходится комитетам по 10 лет заседать, чтобы добавить сборку мусора, например. Это тестовые стенды для всех передовых идей в области проектирования ЯП, которые к тому же некоторые умудряются успешно применять сейчас. Ни о каких догмах речь не идет. Цель — не запретить эффекты и состояние вообще, а найти подходящую модель для них.
Мне все же кажется, что чистые ФЯ — это порождения догм. Одно то, что они существуют очнь давно, но не смогли завоевать серьезной популярности настораживает.
VD>>Физически получается так, что ради догм люди вынуждены получать не эффективные решения. PA>Никто никого не вынуждает, и догмы, повторюсь, нет. А чисто функциональные деревья и списки очень даже пригодны и эффективны для ряда задач.
Еще раз. Если пригодны, то можно и попользоваться. Вот только пригодны не всегда.
PA>Где эта догма высечена в камне, и зачем ее менять?
Почти в любом туториале по ФЯ. Причем обоснования почему модификация памяти это зло так и не приводится. Только заявление.
Точно так же никгде в статьях или других источниках по ФЯ не говориться почему в ФЯ все завязано на списки.
PA> Ведь в прогрессивных (на сегодня) ОКамле и Немерле так и сделано.
Не сказал бы что ОКамл прогрессивный на сегодня. Он конечно обладает достаточными императивными конструкциями, но вот уйти от "духа ФЯ" он так и не смок. Отсюда он крайне плохо будет восприниматься морем императивщиков. К тмоу же он имеет тучу других догм. Отсуствие перегрузки методов. Типизированные операторы. Отсутствие динамических типов. Весма странные и не ясные консрукции. В общем, это не тот язык который примут те кто сегодня сидит на С/Паскаль-подобых языках.
PA> Мало того, в Лиспе и стандартном МЛ то же самое — комбинируй функциональный стиль с императивным по самое не хочу.
Не совсем та. Императивный стиль на МЛ выглядит совсем ужасно.
Понимаш ли в чем дело. Нэмерл тем и подкупает, что являсь по суди ФЯ он предоставляет почти полную эмуляцию пмперативного C#. Так что я могу легко пересадить на него программиста привыкшего к С++/C# и потихоничку показывать ему это "другой мир". А на МЛ я вынужден засунуть его в полностью чуждую ему среду.
Ну, не поймет паттерн-матчинг 99% программистов. Погляди на реакцию на Нэмерел! Ведь большинство людей смотрит на него как на эдакий C# с макросами. И надо признать, что это тоже правильных взгляд, так как уже C# с макросами это больше чем C# без оных. Но главное, что это уже является побуждающим фатором для перехода. А там уже можно познакомиться с фичами Нэмерла как с "мелкими улучшениями". Ну, сначала вывод типов. Здорово ведь не писать не нужных деклараций? Потом паттернм матчинг. Далее глядишь силу функций высшего порядка народ осознает (которые в прочем уже доступны в C#, но на которую никто не обращает внимания) и силу рекурсии за оторую уже не нужно платить так дорого как в C#.
В общем, я вижу как такой язык можно внедрить в массы. А вот лоны МЛ и темболее Лиспа я вообще не верю, что можно в массы продвинуть. Это так и будет уделом фанатиков.
PA> При должном умении программы получаются эффективные и выразительные, все довольны.
Должное умение — это тоже минус. Надо, чтобы люди без оного могли хотя бы повторить то что они уже далают на C# и ему подобных языках. А на МЛ-клонах это практически невозможно.
PA> Одно но: не все проблемы решены — автоматически параллелить нельзя, функции с побочными эффектами от чистых функций не отличить, и т.д и т.п. Поэтому исследования продолжаются, поэтому есть Хаскель, Clean и будут другие языки. Зачем с ними бороться?
Бороться ни с чем не надо. Есть и ладно. Я могу ошибаться, но ни один из ФЯ за исключением модерновых Скалы и Нэмерла в массы не пойдут (по описанным причинам).
А параллелизм в ФЯ пока что тоже мечат. Скорее на первых порах он будет достигнут спец-конструкциями котоыре опять таки проще ввести в язык через макросы. Ну, а там видно будет. Думаю пройдет еще не один виток исследований пока легкий параллелизм не станет достоянием масс.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Философический вопрос про автоматический вывод типов.
Вот все же разумно пишешь, чего-ж тебя в других-то местах заносит?
Здравствуйте, VladD2, Вы писали: VD>В том, что или они все же не чисто функциональные, или значительно менее эффективны нежели их императивные аналоги.
+1
VD>Физически получается так, что ради догм люди вынуждены получать не эффективные решения.
Уже осталось очень мало функциональных сред, которые столь строги в этом вопросе.
( Другое дело, что в большинстве сред есть возможность писать строго. Например, если требуется "доказуемый алгоритм", но никто же не заставляет... )
В том эе erlang-е например вообще есть "словари процессов", которые один в один "свойства" в терминах императивно-объектной модели. Когда есть желание — можно вообще в чисто объектной парадигме писать.
И в других системах такое есть. В том или ином виде.
VD>Ну, нет никаких проблем в модификации значений переменных если язык оберегает от реальных проблем.
+1
VD>Функциональный стиль мог бы стать хорошим дополнением в арсенале программиста, а сегодня он скорее является догмой и уделом едениц.
Самое забавное, что догма он не для функциональщиков... а для неофитов и сторонних наблюдателей.
Большинство реальных больших поектов — смешанные. Напимер у нас в проекте, в чисто функциональном стиле написана только бизнес-логика веб-севисов. Во всех остальных местах присутсвуют императивно-объектные механизмы.
VD>Все что нужно изменить — это заменить догму "модификация памяти — это зло", на более мягкое "многие вещи можно эффективно решать без модификации памяти".
+1
Re[10]: Философический вопрос про автоматический вывод типов
VladD2,
VD>Ненадо мне пояснять. Я все и так понимаю.
Я стараюсь свои мысли выражать чётче, и не вижу здесь криминала. В твоём понимании материала я не сомневаюсь .
VD> Более того, я только за "низменяемость" если она ничего не стоит. Вот только в теории ФЯ все порят оговорки типа "во многих случаях". Не всегда можно действительно "за кулисами" превратить неэффективню операцию копирования в эффектинв модификации.
Согласен, пока не всегда... Приходится переходить к императивному способу.
Но есть и хорошие новости. Например, _гарантируется_, что хвостовая рекурсия свернётся в цикл. Гарантируется, что в ситуациях типа
State1 = modify(State, Data).
State будет модифицирован. Так что здесь оборот "во многих случаях" можно заменить "всегда". Эти 2 случая очень распространены, поэтому ситуация в ФЯ не так плачевна, как кажется.
Кроме того, у функциональщиков с опытом приходят навыки сведения многих алгоритмов к виду, гарантирующему оптимизацию, и поэтому код хорошего функционального программиста по эффективности не хуже императивного.
У императивщиков таких навыков нет, зато есть множество навыков, скажем, по ограничению влияния побочных эффектов (почему глобальные переменные плохой тон?, почему нужна инкапсуляция?).
Короче, они друг друга никогда не поймут
VD>Между тем, если состояние нужно, то нет смысла с ним боросться.
Да, конечно.
Здравствуйте, VladD2, Вы писали:
VD>>>В том, что или они все же не чисто функциональные, или значительно менее эффективны нежели их императивные аналоги. PA>>Устроим шустрик? VD>Можно. Быстрая сортировка устроит?
Драсьте ! Мы о чем говорили? О множествах, реализованных на сбалансированных деревьях.
На остальную часть твоего послания не отвечаю, сорри, что-то духу нет. Останемся при своем мнении.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[10]: Философический вопрос про автоматический вывод типов
Здравствуйте, vdimas, Вы писали:
LCR>>Рубишь с плеча, ажно щепки летят во все стороны Lambda-вычисления (и как следствия функциональные языки) — это раздел математики. Математика — точная наука. V>Скорее, это единственный раздел, который УДАЛОСЬ хорошо формализовать. Опять же, за счет нескольких простых допущений, которые оказались верны для замыканий.
Т.е. как это — удалось, за счет каких допущений, каких замыканий? Лямбда-исчисление именно родилось для формализации оснований математики, затем было применено для исследования проблем вычислимости. Оказалось, что оно эквивалентно машинам Тьюринга. И только потом нашлись энтузиасты, которые на его базе построили языки программирования. А то, что анонимные функции в языках вроде Шарпа называют лямбда-функциями — не более, чем метафора.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[11]: Философический вопрос про автоматический вывод типов
Здравствуйте, Programmierer AG, Вы писали:
VD>>>>В том, что или они все же не чисто функциональные, или значительно менее эффективны нежели их императивные аналоги. PA>>>Устроим шустрик? VD>>Можно. Быстрая сортировка устроит? PA>Драсьте !
Привет.
PA> Мы о чем говорили? О множествах, реализованных на сбалансированных деревьях.
Я говорил, о том, что ФП не всегда обеспечивает сравнимой с императивным скорости выполнения. Реализация быстрой сортировки это прекрасно демонстрирует.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: Философический вопрос про автоматический вывод типов
Здравствуйте, Lazy Cjow Rhrr, Вы писали:
LCR>Согласен, пока не всегда... Приходится переходить к императивному способу.
Ну, вот и не нужно этого бояться. А посему нужно обеспечить удобный императивный синтаксис, чтобы люди не чувствовали дискомфорт от работы на императивном расширении.
LCR>Но есть и хорошие новости. Например, _гарантируется_, что хвостовая рекурсия свернётся в цикл.
Здорово. Это позволяет использовать рекурсию без боязни потерять в производительности. Не более того. Никаких других выводов из этого сделать нельзя. Рекурсия не отрицает модификации памяти.
LCR>Кроме того, у функциональщиков с опытом приходят навыки сведения многих алгоритмов к виду, гарантирующему оптимизацию, и поэтому код хорошего функционального программиста по эффективности не хуже императивного.
Это снова пошла реклама. Оптимизацией пусть занимается компилятор. А вот я могу обеспечить алгоритмическую эффективность и не хочу жертвоать ею ради соблюдения стиля.
Более того. Я не считаю ту же рекурсию приципиально более декларативной нежели циклы. К примеру, конструкция foreach зачастую выглядит куда более понятно нежели концевая рекурсия. И по фигу мне, что внутри переменная модифицируется. Как ты правильно подметил, компилятор тоже порой переписыват код так, что он начинает модифицировать переменные. Ничего страшного в этом нет.
Апологеты ФЯ слишком сильно переоценивают влияние немодифицируемости переменных в общем надежности программы.
LCR>У императивщиков таких навыков нет, зато есть множество навыков, скажем, по ограничению влияния побочных эффектов (почему глобальные переменные плохой тон?, почему нужна инкапсуляция?).
Инкапсуляция есть инкапсуляция. Она нужна для выражения абстракции.
LCR>Короче, они друг друга никогда не поймут
Если они догматики, то конечно. А так... нет проблем.
VD>>Между тем, если состояние нужно, то нет смысла с ним боросться. LCR>Да, конечно.
Ну, а тогда румно забить на догмы и брать лучше из всех парадигм. Если вычисления хорошо укладываются в выражения, то использовать ФС, если надо эмулировать объекты, использовать ОО-стиль с модификацией состояния. Тогда и сам предмет спора уйдет.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[18]: Философический вопрос про автоматический вывод типов
Здравствуйте, IT, Вы писали:
V>>Знаешь, пока ЮАЙщикам на дотнет рановато, ей-богу.
IT>Интересно, и чем я на прошлом проекте в Banc Of America Securities занимался?
Тем же чем и я в Филипсе на прошлом. Применял сырой и кривой в реализации инструмент. Дотнет-бинд на ГУИ от MS на ее собственные нативные вынь-контролы выполнен бездарно. Реальные тормоза в ГУИ не от особенностей VM.Net, а от необоснованных синхронизаций на каждый чих, от путанной системы взаимоотношений ГУИ-элементов и данных, отображаемых ими. От тормознутой и прожорливой реализации системы embedded-ресурсов, от полнейшей "глупости" системы локализации в Windows.Forms, которые в сочетании с тормознутым менеджером ресурсов дают потрясающий "кумулятивный эффект", на который обращают внимание многие, пользуясь ГУИ, нарисованным в дотнете. Я уже где-то здесь говорил, что субъективно ГУИ на дотнете работает примерно с той же скоростью, что и нативные приложения на каком-нить пне 150-200МГц максимум, т.е. аналогично технике 8-ми летней давности.
Изучение внутренностей виндоуз-форм наводит на мысль, что все это имело примерно такой приоритет во время разработки: "лишь бы было", т.е. похоже, что их интересовал сам факт работоспособности, а не технические показатели разработанного бинда.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[11]: Философический вопрос про автоматический вывод типов
Здравствуйте, VladD2, Вы писали:
VD>В общем, неплохо было бы ввести нечто вроде внешних интерфейсов и "особенностей". Первый должны являться чем-то похожим на концепты из будущего стандарта плюсов, а вторые это подключение реализации. Ведь как было бы здорво сделать нечто вроде: VD>[c#] VD>interface IAdd<T> VD>{ VD> T Add(T other); VD>}
[поскипан код]
для того, что ты хочешь надо вводить констрейны для дженериков не на основе интерфейсов, а на основе неких контрактов. Тогда можно было бы требовать не реализации интерфейса, а наличия, например, перегруженных операторов +, -, *, / и т.д.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[19]: Философический вопрос про автоматический вывод типов
Здравствуйте, vdimas, Вы писали:
V>Тем же чем и я в Филипсе на прошлом. Применял сырой и кривой в реализации инструмент. Дотнет-бинд на ГУИ от MS на ее собственные нативные вынь-контролы выполнен бездарно.
Баиндинг после обработки напильником вполне работоспособная вещь. Что касается нативных контролов, то с этим хуже. Я бы даже сказал — плохо. Совсем.
V>Изучение внутренностей виндоуз-форм наводит на мысль, что все это имело примерно такой приоритет во время разработки: "лишь бы было", т.е. похоже, что их интересовал сам факт работоспособности, а не технические показатели разработанного бинда.
Не удивлюсь, если это так. С другой стороны, Джаве понадобилось 10 лет, что обзавестись более менее приличными гуями. Дотнет вышел только 2.0. Кстати, надо глянуть что там с гуями. По идее должно быть побыстрее.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[20]: Философический вопрос про автоматический вывод типов
Здравствуйте, IT, Вы писали:
IT>Не удивлюсь, если это так. С другой стороны, Джаве понадобилось 10 лет, что обзавестись более менее приличными гуями. Дотнет вышел только 2.0. Кстати, надо глянуть что там с гуями. По идее должно быть побыстрее.
Поздравляю Вас, господин соврамши.
Если не ошибаюсь — Джава появилась (стала доступной публике) в 95-м году. А Swing (JFC) появился 98-м году. В 99-м году вошел в состав JDK 1.2
Далее. SWT появился где-то в 2000-м году. Он изначальна был быстрый.
Так что насчет 10 лет — это все неправда. Насчет скорострельности — ерунда. На JDK 1.3 все уже летало. Конечно, на пне-200 это все будет тормозить, но на PIII-600 уже все абсолютно без проблем. Естественно, если памяти хватает, все-таки управляемая среда.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[21]: Философический вопрос про автоматический вывод типов
Здравствуйте, denis_krg, Вы писали:
IT>>Не удивлюсь, если это так. С другой стороны, Джаве понадобилось 10 лет, что обзавестись более менее приличными гуями. Дотнет вышел только 2.0. Кстати, надо глянуть что там с гуями. По идее должно быть побыстрее.
_>Поздравляю Вас, господин соврамши.
Вот сейчас возьму и забаню
_>Если не ошибаюсь — Джава появилась (стала доступной публике) в 95-м году. А Swing (JFC) появился 98-м году. В 99-м году вошел в состав JDK 1.2 _>Далее. SWT появился где-то в 2000-м году. Он изначальна был быстрый.
Свин? Быстрый? Введите Вия! (ну тут типа прыгает нечисть с бубнами и чуваку открывают консервные банки)
_>Так что насчет 10 лет — это все неправда. Насчет скорострельности — ерунда. На JDK 1.3 все уже летало. Конечно, на пне-200 это все будет тормозить, но на PIII-600 уже все абсолютно без проблем. Естественно, если памяти хватает, все-таки управляемая среда.
Осталось только доставить в зал самого обвиняемого
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[22]: Философический вопрос про автоматический вывод типов
Здравствуйте, IT, Вы писали:
IT>Вот сейчас возьму и забаню
Что-то ты так эмоцонально среагировал ))). Не бери в голову, просто факты проверяй и все.
IT>Свин? Быстрый? Введите Вия! (ну тут типа прыгает нечисть с бубнами и чуваку открывают консервные банки)
Быстрый. Я считаю, что быстрый. Медленнее, конечно, чем WinAPI, но все-таки. То есть рисование не является тормозом. Тормоза обычно идут в другом месте. Поэтому я и говорю — быстрый.
_>>Так что насчет 10 лет — это все неправда. Насчет скорострельности — ерунда. На JDK 1.3 все уже летало. Конечно, на пне-200 это все будет тормозить, но на PIII-600 уже все абсолютно без проблем. Естественно, если памяти хватает, все-таки управляемая среда.
IT>Осталось только доставить в зал самого обвиняемого
Кого ты предлагаешь в роли обвиняемого? )))
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[12]: Философический вопрос про автоматический вывод типов
Здравствуйте, vdimas, Вы писали: V>для того, что ты хочешь надо вводить констрейны для дженериков не на основе интерфейсов, а на основе неких контрактов. Тогда можно было бы требовать не реализации интерфейса, а наличия, например, перегруженных операторов +, -, *, / и т.д.
Нет. Для того, что он хочет, нужно выбросить идею со статическими мемберами для операторов на помойку истории, и перейти к системе арифметических интерфейсов. См. напр. object.Equals(object, object), object.Equals(object), IEquatable<T> и пр.
Реализация новых типов констреинтов чревата большим геморроем на уровне джита, и не дает никаких преимуществ по сравнению с предлагаемой схемой.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[13]: Философический вопрос про автоматический вывод типов
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, vdimas, Вы писали: V>>для того, что ты хочешь надо вводить констрейны для дженериков не на основе интерфейсов, а на основе неких контрактов. Тогда можно было бы требовать не реализации интерфейса, а наличия, например, перегруженных операторов +, -, *, / и т.д. S>Нет. Для того, что он хочет, нужно выбросить идею со статическими мемберами для операторов на помойку истории, и перейти к системе арифметических интерфейсов.
Согласен только лишь с замечанием насчет статичности операторов — неудобно ИМХО
S>Реализация новых типов констреинтов чревата большим геморроем на уровне джита, и не дает никаких преимуществ по сравнению с предлагаемой схемой.
Очень даже дает преимущества. Тебе не нужно будет вводить новые интерфейсы и соответственно их имплементацию в типах там, где реально нужен лишь контракт на сигнатуры. А геморрой на уровне джита УЖЕ решен, ведь для value-типов производится вызов constrain-методов БЕЗ боксинга. О чем это говорит? Налицо факт, что для value-типов интерфейсы в constrain используются именно как контракты на сигнатуры, а не как базовая сущность и джит прекрасно разруливает этот момент. А то, что реально эти value-типы сейчас обязаны реализовать указанные в constrain интерфейсы — не более чем ненужный побочный эффект. Реально-то интерфейсы в подобных моментах не используются по прямому назначению (для организации "бинарной совместимости" то бишь).
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[14]: Философический вопрос про автоматический вывод типов
Здравствуйте, vdimas, Вы писали: V>Очень даже дает преимущества. Тебе не нужно будет вводить новые интерфейсы и соответственно их имплементацию в типах там, где реально нужен лишь контракт на сигнатуры.
Термин "реально" в данном контексте мне вообще непонятен. Кроме того, мне непонятно, почему ты считаешь, что "контракт на сигнатуры" лучше интерфейса. С учетом того, что интерфеёс и есть контракт на сигнатуры. V> А геморрой на уровне джита УЖЕ решен, ведь для value-типов производится вызов constrain-методов БЕЗ боксинга. О чем это говорит? Налицо факт, что для value-типов интерфейсы в constrain используются именно как контракты на сигнатуры, а не как базовая сущность и джит прекрасно разруливает этот момент.
Нет. Налицо факт, что джит просто оптимизирует боксинг там, где видит точный тип. V>А то, что реально эти value-типы сейчас обязаны реализовать указанные в constrain интерфейсы — не более чем ненужный побочный эффект. Реально-то интерфейсы в подобных моментах не используются по прямому назначению (для организации "бинарной совместимости" то бишь).
Используются, и еще как. Ты пойми, что сам по себе констреинт — это всего лишь побочный эффект от встраивания сигнатуры вызова в MSIL. Пока что MSIL не позволяет вставить запись "вызови мне какой-нибудь метод с вот такой сигнатурой". Джит не занимается биндингом сигнатур; это делает компилятор. Именно компилятору нужен констреинт — чтобы он понял, какой metodref складывать в MSIL. Перевод операторов на интерфейсы позволяет обойтись тем же ядром фреймворка, без его переработки.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[15]: Философический вопрос про автоматический вывод типов
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, vdimas, Вы писали: V>>Очень даже дает преимущества. Тебе не нужно будет вводить новые интерфейсы и соответственно их имплементацию в типах там, где реально нужен лишь контракт на сигнатуры. S>Термин "реально" в данном контексте мне вообще непонятен. Кроме того, мне непонятно, почему ты считаешь, что "контракт на сигнатуры" лучше интерфейса. С учетом того, что интерфеёс и есть контракт на сигнатуры.
Интерфейс — это еще и бинарная совместимость, и приведения типов и т.д. Зачастую это все не нужно, особенно в паттернах "template method".
V>> А геморрой на уровне джита УЖЕ решен, ведь для value-типов производится вызов constrain-методов БЕЗ боксинга. О чем это говорит? Налицо факт, что для value-типов интерфейсы в constrain используются именно как контракты на сигнатуры, а не как базовая сущность и джит прекрасно разруливает этот момент. S>Нет. Налицо факт, что джит просто оптимизирует боксинг там, где видит точный тип.
Ну? Осталось совсем чуть-чуть чтобы сделать вывод... С помощью чего у него это выходит?
V>>А то, что реально эти value-типы сейчас обязаны реализовать указанные в constrain интерфейсы — не более чем ненужный побочный эффект. Реально-то интерфейсы в подобных моментах не используются по прямому назначению (для организации "бинарной совместимости" то бишь). S>Используются, и еще как. Ты пойми, что сам по себе констреинт — это всего лишь побочный эффект от встраивания сигнатуры вызова в MSIL. Пока что MSIL не позволяет вставить запись "вызови мне какой-нибудь метод с вот такой сигнатурой". Джит не занимается биндингом сигнатур; это делает компилятор. Именно компилятору нужен констреинт — чтобы он понял, какой metodref складывать в MSIL. Перевод операторов на интерфейсы позволяет обойтись тем же ядром фреймворка, без его переработки.
Да знаю я как оно работает и на переработку ядра и намекаю. А на самом деле в MSIL можно вложить произвольный methodref уже сейчас (т.е. несуществующего метода несуществующего типа несуществующей сборки).
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[16]: Философический вопрос про автоматический вывод типов
Здравствуйте, vdimas, Вы писали: V>Интерфейс — это еще и бинарная совместимость, и приведения типов и т.д. Зачастую это все не нужно, особенно в паттернах "template method".
Да-да-да, но нас интересует исключительно ценный мех. V>Ну? Осталось совсем чуть-чуть чтобы сделать вывод... С помощью чего у него это выходит?
Вот тут уж я не знаю. Наверное, с помощью некоторого анализа. V>Да знаю я как оно работает и на переработку ядра и намекаю.
А я не вижу смысла вносить в ядро функциональность, которую можно реализовать на более высоком уровне. Ну вот объясни мне, зачем это делать? Ну кроме как "шоб було"? V>А на самом деле в MSIL можно вложить произвольный methodref уже сейчас (т.е. несуществующего метода несуществующего типа несуществующей сборки).
Задачи вложить несуществующий metodref не стоит. Стоит задача положить референс на метод фактического типа генерик параметра, который имеет некоторую фиксированную сигнатуру. На том уровне заблуждений, который я сейчас имею, я не вижу способа это сделать, оставаясь в рамках существующей модели.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[17]: Философический вопрос про автоматический вывод типов
Здравствуйте, Sinclair, Вы писали:
V>>Ну? Осталось совсем чуть-чуть чтобы сделать вывод... С помощью чего у него это выходит? S>Вот тут уж я не знаю. Наверное, с помощью некоторого анализа.
С помощью отказа от "бинарной" совместимости. т.е. механизм у нас уже как бы есть и геммороя никакого не будет. Осталось приделать интерфейс к этому механизму в виде доп. сущностей VM.Net (напомню, речь об отказе от приведения к интерфейсам, т.е. от боксирования для value-типов)
V>>Да знаю я как оно работает и на переработку ядра и намекаю. S>А я не вижу смысла вносить в ядро функциональность, которую можно реализовать на более высоком уровне. Ну вот объясни мне, зачем это делать? Ну кроме как "шоб було"?
Потому как уже существующие типы способны удовлетворять миллионам комбинаций из различных контрактов, даже тех, о которых не имели представление в момент компиляции. А в случае работы через интерфейсы... в общем ты понял.
Понимаешь, сейчас на интерфейсы взвалено слишком много "обязанностей":
— декларация контрактов (по сути, это должна быть единственная их функциональность)
— бинарная совместимость контрактов... этот момент уже идет из особенностей реализации полиморфизма в семействе таких технологий как С++/Дельфи/Java/.Net. Например в SmallTalk такая проблема не стоит.
Я вижу лишь удобства, если явно разделить эти сущности. Ключевое слово "interface" вполне можно оставить для обозначения "бинарной совместимости", типа как стандарты на аппаратные разъемы тоже называются интерфейсами, а вот то первое обозвать "contract" или там "agreement".
Будут ли проблемы с синтаксисом? Да никогда:
contract Iterator<T> {
T Current { get; }
bool MoveNext();
}
interface IEnumerator<T> : Iterator<T> {
void Reset();
}
Добавить в допустимую цепочку наследования еще 1 элемент:
контракты -> интерфейсы -> классы.
Ограничения в дженериках допустить по интерфейсам и контрактам.
V>>А на самом деле в MSIL можно вложить произвольный methodref уже сейчас (т.е. несуществующего метода несуществующего типа несуществующей сборки). S>Задачи вложить несуществующий metodref не стоит. Стоит задача положить референс на метод фактического типа генерик параметра, который имеет некоторую фиксированную сигнатуру. На том уровне заблуждений, который я сейчас имею, я не вижу способа это сделать, оставаясь в рамках существующей модели.
Оставаясь в рамках стандартного Emit, ты хотел сказать. Формат сборок ничего не запрещает, и это все даже сможет подниматься джитом, если у интересующего типа есть нужный метод с нужной сигнатурой. Надо просто расширить Emit, или написать свой аналогичный тул
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[18]: Философический вопрос про автоматический вывод типов
Здравствуйте, vdimas, Вы писали: V>С помощью отказа от "бинарной" совместимости. т.е. механизм у нас уже как бы есть и геммороя никакого не будет. Осталось приделать интерфейс к этому механизму в виде доп. сущностей VM.Net (напомню, речь об отказе от приведения к интерфейсам, т.е. от боксирования для value-типов)
Я перестаю следить за твоей мыслью. Я не очень хорошо знаю, как именно реализуются интерфейсы в структах — может быть, там действительно формируется некоторая VMT, содержащая переходники для вызова "настоящих" методов на забоксенных данных. В таком случае, джит при параметризации дженерика структом действительно хитрит и "срезает угол", хотя я не вижу никакой проблемы делать то же самое вообще во всех случаях, когда точно известен тип:
int i = 5;
IComparable ii = i; // боксингif (ii.CompareTo(4))
{
...
Здесь теоретически джит может проследить за тем, что а) точный тип ii известен и б) он не используется ни для чего, кроме вызова метода в локальном контексте. Т.е. можно выкинуть боксинг как избыточный. Я не в курсе, делает ли так современный джит. V>Потому как уже существующие типы способны удовлетворять миллионам комбинаций из различных контрактов, даже тех, о которых не имели представление в момент компиляции. А в случае работы через интерфейсы... в общем ты понял.
Нет, не понял. В случае работы через интерфейсы мы имеем массу дополнительных гарантий. Дак-тайпинг — может и хорошая штука, но у него есть масса недостатков. И всовывать его в дотнет я считаю идеологически неверным.
V>Я вижу лишь удобства, если явно разделить эти сущности. Ключевое слово "interface" вполне можно оставить для обозначения "бинарной совместимости", типа как стандарты на аппаратные разъемы тоже называются интерфейсами, а вот то первое обозвать "contract" или там "agreement".
В дотнете бинарная совместимость и гарантии эквивалентны. Не вижу повода отказываться от этой эквивалентности.
V>Будут ли проблемы с синтаксисом? Да никогда: V>[c#] V>contract Iterator<T> { V> T Current { get; } V> bool MoveNext(); V>}
Вопрос в том, как это проверять. V>Оставаясь в рамках стандартного Emit, ты хотел сказать. Формат сборок ничего не запрещает, и это все даже сможет подниматься джитом, если у интересующего типа есть нужный метод с нужной сигнатурой. Надо просто расширить Emit, или написать свой аналогичный тул
дело не в емите. Дело в самом MSIL. Существующий формат байт-кода не позволяет делать такие трюки. И не будет позволять, потому что иначе он не пройдет верификацию.
Или я чего-то фатально не понимаю? Ты не мог бы привести пример байт-кода для вызова статического метода op_addition на типе T, где оба аргумента тоже имеют тип Т?
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[19]: Философический вопрос про автоматический вывод типов
Здравствуйте, Sinclair, Вы писали:
S>Я перестаю следить за твоей мыслью. Я не очень хорошо знаю, как именно реализуются интерфейсы в структах — может быть, там действительно формируется некоторая VMT, содержащая переходники для вызова "настоящих" методов на забоксенных данных.
Забоксенный value-type — это и есть экземпляр "настоящего" класса, т.е. это именно тот вариант представления типа, как если бы мы описывали этот тип как reference-type (со ссылкой на тип). Небоксированный value-type — это просто кусок памяти размером, достаточным для вмещения полей, безо-всяких vtable.
Я лишь напирал на тот факт, что джит на настоящий момент уже в состоянии трактовать интерфейсы как контракты (например, для value-type), а не как бинарные "разъемы". Т.е., по-сути, механизм обслуживания контрактов уже готов.
V>>Потому как уже существующие типы способны удовлетворять миллионам комбинаций из различных контрактов, даже тех, о которых не имели представление в момент компиляции. А в случае работы через интерфейсы... в общем ты понял.
S>Нет, не понял. В случае работы через интерфейсы мы имеем массу дополнительных гарантий.
Ммм... каких дополнительных гарантий? Что-то не вспомню ни одной, кроме бинарной совместимости с другими такими же интерфейсами. Только вот незадача — в большинстве случаев, когда интерфесы используются как констрейны в дженериках, эти интерфейсы НЕ ИСПОЛЬЗУЮТСЯ по прямому назначению. Т.е. никто не юзает их в непосредственном виде ВНЕ дженерика. Ну и нафига тогда нам это дополнительное ограничение в виду обязательности НАСЛЕДОВАНИЯ интерфейса (щаз AVK возмутится по поводу "наследования", но в сравнении с обсуждаемыми контрактами этот термин точнее отражает суть использования интерфейсов в данный момент)
S>Дак-тайпинг — может и хорошая штука, но у него есть масса недостатков. И всовывать его в дотнет я считаю идеологически неверным.
Это не дак-тайпинг, это, считай, дробление размерности интерфейсов до единичных методов... илиже до произвольных комбинаций этих методов. По крайней мере, в отличие от дак-тайпинга ты сохраняешь в целостности и сохранности типизированность и строгую статическую структуру.
Ты выбери для обзора другой угол. Логически, интерфейсы — это и есть constrain (или контракт, и так и так верно). Все остальные их св-ва в дотнете обусловлены особенностями реализации полиморфизма. Я лишь предлагаю сделать возможным задавать контракты (или ограничения) БЕЗ завязки на инструмент полиморфизма. Т.е. пока что я вижу применение контрактов только в ограничениях дженериков.
Вся штука в том, что для того, чтобы тип удовлетворял конракту, он не обязан от него наследоваться. Таким образом, я верну себе львиную долю гибкости от шаблонных решений (которую имел на С++).
V>>Я вижу лишь удобства, если явно разделить эти сущности. Ключевое слово "interface" вполне можно оставить для обозначения "бинарной совместимости", типа как стандарты на аппаратные разъемы тоже называются интерфейсами, а вот то первое обозвать "contract" или там "agreement". S>В дотнете бинарная совместимость и гарантии эквивалентны.
Угу, подобная эквивалентность — это принятие побочных эффектов за целевые.
По поводу того, как в MSIL сейчас сохраняются дженерики — дык это какая-то недоработка... Недодумали они чего-то.
Вот пример, который не компилится:
public interface I1 {
void M1();
void M2();
}
public interface I2 {
void M2();
void M3();
}
public class Class1<T> where T:I1, I2 {
T _field;
void MM() { _field.M2(); }
}
Казалось бы, все вполне логично с т.з. проектирования абстракций. Только не компилится... и вот только попробуй мне сказать, что ситуацию в этом примере спасет явное приведение к одному из интерфейсов... какое нафиг может быть преобразование типа к ограничению???!!!
"Чистые" контракты могли бы быть лишены всеего этого багажа непродумманости.
Более того, над контрактами можно было бы выполнять операции как над множествами: объединять, вычитать, находить разность и т.д. Результатом подобных операций был бы новый контракт.
Re[20]: Философический вопрос про автоматический вывод типов
vdimas,
V>По поводу того, как в MSIL сейчас сохраняются дженерики — дык это какая-то недоработка... Недодумали они чего-то.
V>Вот пример, который не компилится: V>
V> public interface I1 {
V> void M1();
V> void M2();
V> }
V> public interface I2 {
V> void M2();
V> void M3();
V> }
V> public class Class1<T> where T:I1, I2 {
V> T _field;
V> void MM() { _field.M2(); }
V> }
V>
Вопросик можно? Спасибо.
Можно ввести общий интерфейс I содержащий только M2 и параметризовать класс им.
Что может помешать?
Ситуация, когда интерфейсы заморожены (нельзя или невозможно поменять), довольно редкая.
Комбинаторный "взрыв" количества интерфейсов. Тоже весьма специфический случай.
Какие ещё случаи я забыл?
Кроме того, то, что указанный вызов не кушается компилятором, это не слишком большая проблема. Получается просто некрасиво, но не более того (могло бы быть сгенерировано компилятором).
...
void MM()
{
_f1 = _field as I1;
_f2 = _field as I2;
if (_f1 != null)
_f1.M2()
else
_f2.M2();
}
V>"Чистые" контракты могли бы быть лишены всеего этого багажа непродумманости. V>Более того, над контрактами можно было бы выполнять операции как над множествами: объединять, вычитать, находить разность и т.д. Результатом подобных операций был бы новый контракт.
Я продолжу. Контракты потом захочется организовывать в коллекции, чтобы автоматизировать вещи типа $\Cup_i C_i$. Затем захочется делать выборку из этих коллекций. Чтобы делать выборку, нужна нотация для описания условий. И т.д. и т.п.
Уже целый язык получается (на ум приходят аналогии с xpath и sql).
Уфф...
V>>"Чистые" контракты могли бы быть лишены всеего этого багажа непродумманости. V>>Более того, над контрактами можно было бы выполнять операции как над множествами: объединять, вычитать, находить разность и т.д. Результатом подобных операций был бы новый контракт.
LCR>Я продолжу. Контракты потом захочется организовывать в коллекции, чтобы автоматизировать вещи типа $\Cup_i C_i$. Затем захочется делать выборку из этих коллекций. Чтобы делать выборку, нужна нотация для описания условий. И т.д. и т.п.
LCR>Уже целый язык получается (на ум приходят аналогии с xpath и sql).
LCR>Картина получается слишком сложной, имхо.
Тут мой стиль изложения хромает, выражусь точнее: Существование контрактов => язык операций над ними => слишком сложно.
Здравствуйте, Lazy Cjow Rhrr, Вы писали:
LCR>Можно ввести общий интерфейс I содержащий только M2 и параметризовать класс им.
Это можно в моем надуманном примере, а если ты должен использовать "чужие" интерфейсы, то не можно. Да, к тому же мне и остальные методы интерфейсов нужны.
LCR>Кроме того, то, что указанный вызов не кушается компилятором, это не слишком большая проблема. Получается просто некрасиво, но не более того (могло бы быть сгенерировано компилятором). LCR>
Отличный пример того, что интерфейсы пока не тянут на понятие контракт. Ты взял да попытался разрисовать механику (ибо по-другому — никак). Более того, налицо побочные эффекты: результат может измениться, если в if() ты сначала проверишь _f2. Я уже молчу о том, что приведенный код содержит откровенный ляп, что так же весьма показательно. (вернее так: приведенный код — это попытка озвучить софизм на императивном ЯП, присмотрись внимательно, что ты там накуролесил в этих 6-ти строчках )
Вот тебе и "контракты" на базе интерфейсов.
V>>"Чистые" контракты могли бы быть лишены всеего этого багажа непродумманости. V>>Более того, над контрактами можно было бы выполнять операции как над множествами: объединять, вычитать, находить разность и т.д. Результатом подобных операций был бы новый контракт.
LCR>Я продолжу. Контракты потом захочется организовывать в коллекции, чтобы автоматизировать вещи типа $\Cup_i C_i$.
Контракт — это уже и есть коллекция, вернее множество. Некое множество ограничений.
Кстати, вспомнил еще кое-что. До меня доходили слухи, что в каком-нибудь C# XX.0 делегаты будут совместимы м/у собой по сигнатурам, а так же можно будет вешать делегаты на пропертя, и вообще планнируют пару подпорок для ФЯ. Для того, чтобы это стало возможным, им придется ввести еще одну сущность — "сигнатура". Так вот, представление типа обсуждаемого контракта можно было бы свести к коллекции (множеству) этих "сигнатур".
LCR>Уже целый язык получается (на ум приходят аналогии с xpath и sql).
Твои xpath и sql уже встроены в C#-подобный язык.
LCR>Картина получается слишком сложной, имхо.
А ну да... как же без этого крайне ценного замечания... А на мой взгляд на порядок проще чем LINQ, да и руки развяжет основательно.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[22]: Философический вопрос про автоматический вывод типов
vdimas,
V>Я уже молчу о том, что приведенный код содержит откровенный ляп, что так же весьма показательно.
Да, _f2 может быть null.
LCR>>Я продолжу. Контракты потом захочется организовывать в коллекции, чтобы автоматизировать вещи типа $\Cup_i C_i$. V>Контракт — это уже и есть коллекция, вернее множество. Некое множество ограничений.
Может потребоваться множество множеств. В самом деле, почему нет? Естественно и операции над ним. Скажем, контракты C0, C1, C2, C3. Мы можем ручками:
interface Ix : D diff (C0 or C1 or C2 or C3) {}
А можно обобщить эту картину на случай не только n=3, параметризовав C. Потребуется некий конструкт, коллекция этих C_i. Вот я о чём.
Ещё есть одно ограничение, которое хотелось всегда иметь: notnull. Твои контракты не потянут это ограничение, потому что интерфейс не может его (ограничение) отразить.
Здравствуйте, Lazy Cjow Rhrr, Вы писали:
V>>Я уже молчу о том, что приведенный код содержит откровенный ляп, что так же весьма показательно.
LCR>Да, _f2 может быть null.
Опять не угадал. У нас I1 и I2 — ограничения дженерика. Соответственно требуемый тип реализует ОБА интерфейса. Это значит, что _f1 и _f2 либо одновременно равны null в твоем примере, либо оба не равны. Ставить там if() на проверку _f1 или _f2 — абсурд.
LCR>>>Я продолжу. Контракты потом захочется организовывать в коллекции, чтобы автоматизировать вещи типа $\Cup_i C_i$. V>>Контракт — это уже и есть коллекция, вернее множество. Некое множество ограничений. LCR>Может потребоваться множество множеств. В самом деле, почему нет? Естественно и операции над ним. Скажем, контракты C0, C1, C2, C3. Мы можем ручками: LCR>
LCR>interface Ix : D diff (C0 or C1 or C2 or C3) {}
LCR>
LCR>А можно обобщить эту картину на случай не только n=3, параметризовав C. Потребуется некий конструкт, коллекция этих C_i. Вот я о чём.
Знаешь, меня бы на ближайшие лет 10 устроило бы хотя бы простое объединение, такое же как в случае нынешних интерфейсов:
class MyClass<T> where T : C0<T>, C1<T>, C2<T> { ... }
LCR>Ещё есть одно ограничение, которое хотелось всегда иметь: notnull. Твои контракты не потянут это ограничение, потому что интерфейс не может его (ограничение) отразить.
Это ограничени из области run-time, а не compile-time. Есть компилятор C#, который умеет обрабатывать дополнительный набор аттрибуттов и генерировать код для подобной проверки.
Авообще, самое замечательное ограничение notnull в дотнете — это использовать value-типы, что я и делаю часто и охотно. Кстати, в дженериках так же можно задать ограничение на ValueType.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[24]: Философический вопрос про автоматический вывод типов
vdimas,
LCR>>Да, _f2 может быть null.
V>Опять не угадал. У нас I1 и I2 — ограничения дженерика. Соответственно требуемый тип реализует ОБА интерфейса. Это значит, что _f1 и _f2 либо одновременно равны null в твоем примере, либо оба не равны. Ставить там if() на проверку _f1 или _f2 — абсурд.
Здравствуйте, vdimas, Вы писали: V>Казалось бы, все вполне логично с т.з. проектирования абстракций. Только не компилится... и вот только попробуй мне сказать, что ситуацию в этом примере спасет явное приведение к одному из интерфейсов... какое нафиг может быть преобразование типа к ограничению???!!!
По-моему, ты гонишь. Ты ввел два совершенно разных метода: I1.M2 и I2.M2. Тут и без дженерика неясно, что ты имеешь в виду. Точнее, при использовании "настоящего" типа у компилятора есть средство разрулить неопределенность.
Вот тебе пример класса, которым я параметризую твой дженерик:
public class Crach: I1, I2
{
public void M1() { Console.Write("I1M1");}
void I1.M2() { Console.Write("I1M2");}
void I2.M2() { Console.Write("I2M2");}
public void M3() { Console.Write("I2M3");}
}
Что должен вывести вызов new Class1<Crash>.MM()? V>"Чистые" контракты могли бы быть лишены всеего этого багажа непродумманости.
Да-да-да. Я прямо так и вижу этот багаж непродуманности. Вот когда ты отмедитируешь над тем, что нужно делать в таком случае, расскажи мне. V>Более того, над контрактами можно было бы выполнять операции как над множествами: объединять, вычитать, находить разность и т.д. Результатом подобных операций был бы новый контракт.
Это все — дак тайпинг, что ты только что продемонстрировал своим примером.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[21]: Философический вопрос про автоматический вывод типов
Здравствуйте, Sinclair, Вы писали:
V>>Казалось бы, все вполне логично с т.з. проектирования абстракций. Только не компилится... и вот только попробуй мне сказать, что ситуацию в этом примере спасет явное приведение к одному из интерфейсов... какое нафиг может быть преобразование типа к ограничению???!!! S>По-моему, ты гонишь. Ты ввел два совершенно разных метода: I1.M2 и I2.M2. Тут и без дженерика неясно, что ты имеешь в виду.
По моему, ты слишком увлекся особенностями реализации контрактов в дотнете, не находишь? Иначе бы не приводил код с явной имплементацией интерфейсов в обсуждении применимости интерфейсов как контрактов. Ты лишь продемонстрировал, что интерфейсы плохо для этого подходят.
Ты бы хоть задумался — в каком случае тебе потребуются отдельные явные имплементации методов M2 в разных интерфейсах? Очевидно, в случае обладания разной семантикой. Сильная семантическая нагрузка на интерфейсы (как на самодостаточные наборы сигнатур) в дотнете не от хорошей жизни, а от отсутствия МН. В дотнете такую сущность как "интерфейс" зачастую выбирают для описания корня иерархии некоторого семейства, хотя корнем ИМХО должен был бы быть некий базовый класс, а не интерфейс (где сказано, что базовый класс не может обладать базовой функциональностью? да он обязан ею обладать).
Если же продолжать обсуждать контракты, то понятие "контракт" немного слабее, что-ли, чем понятие "сущность", которую несут в себе интерфейсы в дотнете сейчас. Например, мне для алгоритма надо, чтобы некий экземпляр обладал св-вом Count. Да, достаточно чтобы просто одним этим св-вом. Не думаю, что при "пересечении" этого св-ва у разных ограничений (интерфейсов или контрактов) должны возникать семантические конфликты. Уверен, контракты именно будут проектироватьименно таким образом, дабы минимизировать вероятность столкновений.
S>Это все — дак тайпинг, что ты только что продемонстрировал своим примером.
Вот ты и гонишь со своим дак-тайпингом. Где ты увидел "недотипизированность" или динамическую типизированность? VM при загрузке типа будет параметризировать дженерик конкретным типом, все связи будут "бинарные и жесткие". А то с твоих слов выходит, что шаблоны в С++ — это тоже дак-тайпинг, ведь там даже контракты задавать не надо — пихай что хочешь... Хотя мне эти шаблоны помогали имено жестче типизировать абстракции и обкладываться ограничениями. (про С++ разговор особый, как всегда недостающие фичи легко реализуются в нем ср-вами языка, например ограничения шаблонов или контракты... не бинарные интерфейсы, а именно контракты ).
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[22]: Философический вопрос про автоматический вывод типов
Здравствуйте, vdimas, Вы писали: V>По моему, ты слишком увлекся особенностями реализации контрактов в дотнете, не находишь? Иначе бы не приводил код с явной имплементацией интерфейсов в обсуждении применимости интерфейсов как контрактов. Ты лишь продемонстрировал, что интерфейсы плохо для этого подходят.
Наверное, увлекся. V>Ты бы хоть задумался — в каком случае тебе потребуются отдельные явные имплементации методов M2 в разных интерфейсах? Очевидно, в случае обладания разной семантикой.
Совершенно верно. И все-таки, объясни мне, какой именно метод должен вызываться в данном случае?
Или ты предлагаешь вернуться к плюсам, где невозможно реализовать семантически различные методы с одинаковой сигнатурой? Ты так и не ответил, какой именно код должен исполняться в приведенном мной случае. А если ты честно ответишь на этот вопрос, то поймешь, что без явной квалификации интерфейса не обойтись. А то, что в шарпе нет специального синтаксиса, как в плюсах, так это ерунда — семантика-то та же. V>Сильная семантическая нагрузка на интерфейсы (как на самодостаточные наборы сигнатур) в дотнете не от хорошей жизни, а от отсутствия МН. В дотнете такую сущность как "интерфейс" зачастую выбирают для описания корня иерархии некоторого семейства, хотя корнем ИМХО должен был бы быть некий базовый класс, а не интерфейс (где сказано, что базовый класс не может обладать базовой функциональностью? да он обязан ею обладать).
Ничего не понимаю. Почему это корня? Множественное наследование в дотнете присутствует, и именно в интерфейсах. Никогда не видел, чтобы именно интерфейс в дотнете выбирали в качестве корня иерархии. Классы — да: вот например нету ни IStream, ни ITextReader. V>Если же продолжать обсуждать контракты,
Не надо обсуждать контракты. Чтобы то, что ты предлагаешь, хоть как-то заработало, нужно отказаться от дотнета. Ок, мне не оченm интересно обсуждать перспективы альтернативных технологий. V>то понятие "контракт" немного слабее, что-ли, чем понятие "сущность", которую несут в себе интерфейсы в дотнете сейчас. Например, мне для алгоритма надо, чтобы некий экземпляр обладал св-вом Count. Да, достаточно чтобы просто одним этим св-вом. Не думаю, что при "пересечении" этого св-ва у разных ограничений (интерфейсов или контрактов) должны возникать семантические конфликты. Уверен, контракты именно будут проектироватьименно таким образом, дабы минимизировать вероятность столкновений.
А зачем? S>>Это все — дак тайпинг, что ты только что продемонстрировал своим примером. V>Вот ты и гонишь со своим дак-тайпингом. Где ты увидел "недотипизированность" или динамическую типизированность?
Как это? Дак-тайпинг — это и есть "наличие подходящих методов". Вместо точной сигнатуры, как у интерфейсов. V>VM при загрузке типа будет параметризировать дженерик конкретным типом, все связи будут "бинарные и жесткие". А то с твоих слов выходит, что шаблоны в С++ — это тоже дак-тайпинг, ведь там даже контракты задавать не надо — пихай что хочешь... Хотя мне эти шаблоны помогали имено жестче типизировать абстракции и обкладываться ограничениями. (про С++ разговор особый, как всегда недостающие фичи легко реализуются в нем ср-вами языка, например ограничения шаблонов или контракты... не бинарные интерфейсы, а именно контракты ).
Совершенно верно, шаблоны в плюсах — это дак-тайпинг. А ты не знал?
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[23]: Философический вопрос про автоматический вывод типов
V>>Ты бы хоть задумался — в каком случае тебе потребуются отдельные явные имплементации методов M2 в разных интерфейсах? Очевидно, в случае обладания разной семантикой. S>Совершенно верно. И все-таки, объясни мне, какой именно метод должен вызываться в данном случае?
Метод Class1.M2 разумеется, единственный и неповторимый . Речь же о контракте. Я же не обсуждаю текущую реализацию интерфейсов в дотнете, я пытаюсь объяснить, почему иногда мне было бы удобно использовать контракты там, где мы вынуждены использовать интерфейсы. Через контракты, например, можно было бы требовать ниличия даже СТАТИЧЕСКИХ методов, а значит... да именно, перегруженных операторов (согласись, дженерики смотрятся бледновато без них).
S>Или ты предлагаешь вернуться к плюсам, где невозможно реализовать семантически различные методы с одинаковой сигнатурой?
Нет, не предлагаю. Пусть для интерфейсов все останется как есть. Интерфейсы очень эффективно используются для осуществления бинарной совместимости. Ведь в С++ тоже вовсю успешно применяются полностью абстрактные классы (аналоги интерфейсов) именно там, где они нужны. Мы ведь обсуждали способ задания ограничений в дженериках, ты не забыл? А это несколько "другой" способ использования интерфейсов, чем то, про что ты сейчас говорил.
S>Ты так и не ответил, какой именно код должен исполняться в приведенном мной случае.
В твоем коде и при использовании интерфейсов — не знаю Надо явно указывать и это зависит от семантик интерфейсов.
А при использовании контрактов — Class1.M2
S>А если ты честно ответишь на этот вопрос, то поймешь, что без явной квалификации интерфейса не обойтись.
И я о том же, ну неудобно их юзать для ограничений дженериков.
V>>Сильная семантическая нагрузка на интерфейсы (как на самодостаточные наборы сигнатур) в дотнете не от хорошей жизни, а от отсутствия МН. В дотнете такую сущность как "интерфейс" зачастую выбирают для описания корня иерархии некоторого семейства, хотя корнем ИМХО должен был бы быть некий базовый класс, а не интерфейс (где сказано, что базовый класс не может обладать базовой функциональностью? да он обязан ею обладать). S>Ничего не понимаю. Почему это корня? Множественное наследование в дотнете присутствует, и именно в интерфейсах. Никогда не видел, чтобы именно интерфейс в дотнете выбирали в качестве корня иерархии. Классы — да: вот например нету ни IStream, ни ITextReader.
Зато полно IDbConnection, IDbTransaction и прочее, и прочее...
S>Не надо обсуждать контракты. Чтобы то, что ты предлагаешь, хоть как-то заработало, нужно отказаться от дотнета. Ок, мне не оченm интересно обсуждать перспективы альтернативных технологий.
2 года назад я слышал подобное о шаблонах в дотнете. И что? Никто не отказался. Реализовали дженерики, и расширили возможности среды.
V>>то понятие "контракт" немного слабее, что-ли, чем понятие "сущность", которую несут в себе интерфейсы в дотнете сейчас. Например, мне для алгоритма надо, чтобы некий экземпляр обладал св-вом Count. Да, достаточно чтобы просто одним этим св-вом. Не думаю, что при "пересечении" этого св-ва у разных ограничений (интерфейсов или контрактов) должны возникать семантические конфликты. Уверен, контракты именно будут проектироватьименно таким образом, дабы минимизировать вероятность столкновений. S>А зачем? S>>>Это все — дак тайпинг, что ты только что продемонстрировал своим примером. V>>Вот ты и гонишь со своим дак-тайпингом. Где ты увидел "недотипизированность" или динамическую типизированность? S>Как это? Дак-тайпинг — это и есть "наличие подходящих методов". Вместо точной сигнатуры, как у интерфейсов.
Ага, только разница в том, в какой момент определяется наличие сигнатуры — момент исполнения или компиляции.
V>>VM при загрузке типа будет параметризировать дженерик конкретным типом, все связи будут "бинарные и жесткие". А то с твоих слов выходит, что шаблоны в С++ — это тоже дак-тайпинг, ведь там даже контракты задавать не надо — пихай что хочешь... Хотя мне эти шаблоны помогали имено жестче типизировать абстракции и обкладываться ограничениями. (про С++ разговор особый, как всегда недостающие фичи легко реализуются в нем ср-вами языка, например ограничения шаблонов или контракты... не бинарные интерфейсы, а именно контракты ). S>Совершенно верно, шаблоны в плюсах — это дак-тайпинг. А ты не знал?
Нет не знал и продолжаю не знать.
Шаблоны — это способ описание кодогенерации. А ты не знал?
В генерируемых типах никакого Дак-тайпинга нет и близко!
Понимаешь, там такая штука, в общем, если метода нет, то конкретный тип и не компилируется. Дак-тайпингом было названо несколько другое.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[24]: Философический вопрос про автоматический вывод типов
Здравствуйте, vdimas, Вы писали: V>Метод Class1.M2 разумеется, единственный и неповторимый . Речь же о контракте.
Еще раз попробую тебя нагнуть: что делать, если класс реализует два одноименных метода M2? В дотнете это возможно.
V>2 года назад я слышал подобное о шаблонах в дотнете. И что? Никто не отказался. Реализовали дженерики, и расширили возможности среды.
Нет. Дженерики ничего не выбросили из дотнета. S>>Как это? Дак-тайпинг — это и есть "наличие подходящих методов". Вместо точной сигнатуры, как у интерфейсов. V>Ага, только разница в том, в какой момент определяется наличие сигнатуры — момент исполнения или компиляции.
И? Ты еще не забыл, что инстанцирование дженериков происходит в рантайме? S>>Совершенно верно, шаблоны в плюсах — это дак-тайпинг. А ты не знал? V>Нет не знал и продолжаю не знать. V>Шаблоны — это способ описание кодогенерации. А ты не знал?
Знал. Но от того, что ты назовешь что-то более длинным словом, менее утиной эта типизация не станет. К примеру, шаблону все равно, чем его параметризуют — настоящим указателем на V>В генерируемых типах никакого Дак-тайпинга нет и близко! V>Понимаешь, там такая штука, в общем, если метода нет, то конкретный тип и не компилируется. Дак-тайпингом было названо несколько другое.
Как это несколько другое? Дак тайпинг — это и есть достаточность наличия метода с именем squack для того, чтоб быть уткой. Непринципиально, проверяется это в компайл-тайме или в рантайме. Точнее, нам конечно же удобнее иметь все проверки в компайл-тайме,
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[25]: Философический вопрос про автоматический вывод типов
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, vdimas, Вы писали: V>>Метод Class1.M2 разумеется, единственный и неповторимый . Речь же о контракте. S>Еще раз попробую тебя нагнуть: что делать, если класс реализует два одноименных метода M2? В дотнете это возможно.
Один из нас буксует, ИМХО...
В дотнете невозможно напрямую вызвать ни один из этих одноименных метода (вернее, не одноименных, но с одинаковой сигнатурой, ты ведь это хотел спросить?) из класса напрямую, только через приведение к интерфейсу. Я использую эту мысль как демонстрацию неудобства интерфейсов при использовании их как ограничений, а ты зачем-то пытаешься выснить, насколько я хорошо представляю себе технологию реализации интерфейсов в дотнете. Ответ: достаточно, чтобы судить о возможностях дальнейших увеличений удобств в дотнет.
V>>2 года назад я слышал подобное о шаблонах в дотнете. И что? Никто не отказался. Реализовали дженерики, и расширили возможности среды. S>Нет. Дженерики ничего не выбросили из дотнета.
Где я предлагал что-либо выбросить? Я предлагаю добавить. Зачем убирать имеющиеся правила задания ограничений в дженериках?
S>>>Как это? Дак-тайпинг — это и есть "наличие подходящих методов". Вместо точной сигнатуры, как у интерфейсов. V>>Ага, только разница в том, в какой момент определяется наличие сигнатуры — момент исполнения или компиляции. S>И? Ты еще не забыл, что инстанцирование дженериков происходит в рантайме?
Ну вот опять... Ты снова и снова намекаешь на особенности механизма, который реализует VM.Net сейчас? Ты сводишь обсуждение к примерно такому абсурду: "какой смысл обсуждать будущие возможные улучшения, если они не реализуются нынешней реализацией?". Я тебе напоминал про ранние дискуссии о шаблонах в дотнет и точно таких же доводах, но ты не понял намека, очевидно.
Я ведь могу предложить несколько вариантов реализации обсуждаемого механизма и даже относительно форматов PE — где и как оно все будет представляться. РАЗУМЕЕТСЯ, потребуются новые сущности в самой VM.Net, потребуется опять немного расширить объектную систему метаинформации, точно так же как потребовались новые сущности и расширения мета-системы для реализации дженериков. Тебя именно этот факт беспокоит?
S>Как это несколько другое? Дак тайпинг — это и есть достаточность наличия метода с именем squack для того, чтоб быть уткой. Непринципиально, проверяется это в компайл-тайме или в рантайме. Точнее, нам конечно же удобнее иметь все проверки в компайл-тайме
Хорошо, попробую зайти с другой стороны. Давай разделим компайл-тайм и рантайм. Было бы тебе достаточно, чтобы в предлагаемой схеме все несоответствия выявлялись в компайл-тайм? (блин, да ведь даже intellisence сохраняется в этой схеме, в отличие от невозможности применять intellisence к параметрам шаблонов С++)
Мне ведь глубоко фиолетово насчет подробностей внутренних механизмов, если в результате я получу верифицируемое решение, которое не уступает строго-типизированному.