Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Dufrenite, Вы писали:
D>>Мне нужна реализация не привязанная к дотнету. Я бы предпочел скорее LLVM.
VD>Боюсь, что на нем еще очено долго ничего путного не будет.
Здравствуйте, Silver_s, Вы писали:
S_> Вот был бы фреймворк хорошо управляющий механизмами таких заморозок, позволяющий и вручную и по таймерам эти заморозки/транзакции проводить.
В Rx много интересного хелперного функционала.
... << RSDN@Home 1.2.0 alpha 4 rev. 1464 on Windows 7 6.1.7600.0>>
Здравствуйте, Dufrenite, Вы писали:
D>Хороший вопрос. Я позаимствовал решение из архитектуры программного пакета 3D моделирования Maya. Оно заключается в принципе "тяни-толкай". Согласно этому принципу, распространение изменений происходит в 2 этапа. На первом этапе информация об изменении "проталкивается" через весь подграф зависимых свойств объектов, которые помечаются как измененные. На втором этапе код который нуждается в новом значении оконечного свойства "вытягивает" это значение из всего измененного подграфа. Попутно, естественно, все пересчитанные свойства помечаются как неизмененные.
Расшифрую выделенное: вытягивание здесь означает перевычисление изменившихся узлов тех и только тех, от которых зависит вычисляемое свойство. Уверен, что подразумевалось именно это, но людьми не знакомыми с Maya это может быть неочевидно.
Прихожу к выводу, что объекты — это только "часть правды". Объекты, как концентрация нашего "проектного представления" о программе безусловно полезны. Но вот если бы еще вынети ДАННЫЕ на верхушку программы и вынести их как обязательную конструкцию. Данные — унифицировать по строению, — как таблицы в СУБД. А между ними прописать явняе отношения — как особые конструкции вроде SQL.
Могу ошибаться, но объектно-ориентированное программирование может решать и такие проблемы. Если я правильно понял вопрос, то классическим решением является декомпозиция входных и выходных данных в объект и добавление в эти объекты методов преобразования откуда надо и во что надо. Например, что-то вроде:
void OnSomethingArrived( XMLStream* incoming )
{
var something = new Something();
something.FromXmlStream( incoming );
ProcessSomething( something ); // <- вот тут у нас логика
var database = GetDatabase();
something.ToDatabase( database ); // <- тут переложили в другой формат.
}
Здравствуйте, Dufrenite, Вы писали:
D>Это не присвоение, а описание потока данных. Полностью декларативное. D>Например, оператор Z <= X + Y; означает, что при каждом изменении входного свойства X или Y, выходное свойство Z автоматически пересчитывается. Сответственно, пересчитываются все зависящие от Z выходные свойства, а это коллекции Ints и Doubles.
D>Можно также добавить внешние зависимости. Например: D>
D>class Class2(obj : Class1)
D>{
D> Sum <= obj.Doubles.Aggregate(0, (sum, d) => sum + d);
D>}
D>
D>Соответственно, при изменении входных свойств объекта obj выходное свойство Sum также автоматически пересчитается.
Здравствуйте, vdimas, Вы писали:
V>Хм, электронщики все-таки повлияли на программистов.
Ухлопал кучу времени, пытаясь понять чего мне не хватает в известных подходах. Придумал реактивное программирование, а оказалось, что изобрел велосипед.
Когда же увидел примеры VHDL, то в очередной раз понял что образование должно включать не только программирование.
V>Когда-то давно на эту тему фантазировал: http://www.rsdn.ru/forum/philosophy/1676773.1.aspx
Мыслим в одном направлении
D>>Мне нужна реализация не привязанная к дотнету. Я бы предпочел скорее LLVM.
V>Эта техника не зависит от платформы, ибо реализация ее тривиальна (кроме циклических случаев и прочих "гонок"), дело в языке описания зависимостей.
Техника то не зависит, а конкретная реализация очень даже зависит.
Здравствуйте, Dufrenite, Вы писали:
D>Ухлопал кучу времени, пытаясь понять чего мне не хватает в известных подходах. Придумал реактивное программирование, а оказалось, что изобрел велосипед. D>Когда же увидел примеры VHDL, то в очередной раз понял что образование должно включать не только программирование.
Дык, вроде программистам электронику и устройства ЭВМ дают непрерывно с 3-го по 5-й курс. Не учат толком — это да.
Там это все было не просто так обсуждение, а часть гораздо более серьезного. Реактивный подход — это одно из немногих направлений, где можно будет значительную часть программы описывать с помощью графических IDE, постепенно отказываясь от "настукивания" плоского текста исходников как основного способа представления программ. (на всякий случай, слово "основного" — ключевое, т.е. полностью отказаться никто не призывает)
Здравствуйте, vdimas, Вы писали:
V>Не учат толком — это да.
VHDL не изучали, это точно. Но жаловаться не буду: рассказывали много интересного, кое что даже пригодилось (МИЭТ).
V>Там это все было не просто так обсуждение, а часть гораздо более серьезного. Реактивный подход — это одно из немногих направлений, где можно будет значительную часть программы описывать с помощью графических IDE, постепенно отказываясь от "настукивания" плоского текста исходников как основного способа представления программ. (на всякий случай, слово "основного" — ключевое, т.е. полностью отказаться никто не призывает)
Пока что, плоский текст, это наиболее дешевое решение. А так, да. Большинство data-flow языков — графические.
Прихожу к выводу, что объекты — это только "часть правды". Объекты, как концентрация нашего "проектного представления" о программе безусловно полезны. Но вот если бы еще вынети ДАННЫЕ на верхушку программы и вынести их как обязательную конструкцию. Данные — унифицировать по строению, — как таблицы в СУБД. А между ними прописать явняе отношения — как особые конструкции вроде SQL.
EOH>Могу ошибаться, но объектно-ориентированное программирование может решать и такие проблемы. Если я правильно понял вопрос, то классическим решением является декомпозиция входных и выходных данных в объект и добавление в эти объекты методов преобразования откуда надо и во что надо. Например, что-то вроде:
EOH>
EOH>void OnSomethingArrived( XMLStream* incoming )
EOH>{
EOH> var something = new Something();
EOH> something.FromXmlStream( incoming );
EOH> ProcessSomething( something ); // <- вот тут у нас логика
EOH> var database = GetDatabase();
EOH> something.ToDatabase( database ); // <- тут переложили в другой формат.
EOH>}
EOH>
Хех, я понимаю, что можно написать "преобразователь". Но акцет был в другом. Сейчас, когда вы читаете программу — в центре внимания — метод, функция, процедуры. Программа начинается с главной процедуры, которая вызывает другие и так далее. Во всех конструкциях управления — вызов функии и процедур — на первом месте. В ООП данные даже предлагается прятатть за свойствами, чтобы их вообще не было. Чтобы был "мир процедур".
А представьте себе язык, который начинается с описания выходных данных, например (это что-то вроде цели), от которых можно оттолкнуться и черех лес отношений с другими данными перейти к пониманию как эта цель достигается и как другие данные, а также отношения меду ними влияют на результат (тяни-толкай). В таком подходе не страдает и процедурная сторона — процедуры по прежнему явно читаемы и их место в общем алгоритме понятно. А в отношении данных, за счет их выставления на показ и возможности проследить все "руки", тянущихся к ним отношений — степень выразительности и понимания программы значительно возрастает. А значит — программы становится и легче читать.
Кроме упомянутых здесть систем реактивного программирования (очень интересно было узнать), есть еще Data-Driver-Design. Тоже советую почитать.
Но возникает проблема: раз данные становятся "общественным достоянием", раз они выходят из под ига объектов, то ООП расслаивается, как растаявшее мороженное: отдельно функции которые несут процедурную, активную, действующую составляющую. И отдельно — данные, которые замыкают на себе систему отношений, концентрируют взаимоотношения процедур и функций и делают это более отчетливо чем управляющие конструкции. Кроме того, мы получаем новые замечательные возможности. Все наверняка знакомы с ситуацией — скачав очередной DataGrid из интернета, обнаруживаем, что в нем есть очень корошие качества (fratures) А и Б, но как назло нет качеств В и Г, которые есть в другом таком же компоненте. Или наконец нам удалось скачать компонент в котормо есть почти все. Но это будет МОНСТР, который пугает сложностью своей настройки и тяжеловесностью. В случае расслоения объектов мы можем получить следующее — вот в этой библиотеке ест замечателная функция размещения ячеек в окне. Эта функция например позволяет делать многоуровневые заголовки. А эта функция позволяет выполнять хитрые сортировки, подсунутых ей в качестве данных колонок, а эта функция позволяет все красиво раскаршивать. В итоге мы получаем композитный объект, скрестив "коня и трепетную лань".
Но, после "расслоения" мы получаем новые проблемы: данные, перестав прятаться в объектах, должны приобрести универсальность для их обработчиков и самопрезентабельность. Они — должны быть такими данными, которые могут обратиться в любую процедуру и быть там обработанными. Функции, будучи написанными разными авторами, тем не менее не должны предъявлять к данным особых требований по структуре — т.е. структура данных не должна быть строго предопеределена.
В технологии COM, когда есть ситуация независимого создания объектов на разных языках разными авторами в разное время независимо друг от друга — предусмотрена обязательная спецификация обмена данными — UDT (или UDF — что то такое).
Универсальная структура данных — какая она?
Можно представить, что все данные — это ассоциативные массивы. Тогда дата это массив:
TDate["day"]
TDate["month"]
TDate["year"]
И мы хотим, чтобы все функции принимали его, как родного.
Но возможно ли это? А если кто-то написал функцию, понимающую дату как количество дней от крещения Руси? Тогда что?
Значит без преобразователей не обойтись?
Хорошо, пусть так, но страшно представить себе количнство перобразователей в большой программе, если разные функции ориентированы на работу с различными типами...
То есть определив в программе основные типы и получив в распоряжение функции исполнители, мы один раз указываем какияи функциями будут селаны преобоазования для входа каждой функции и потом завязывая отношения между функциями посредством связывающих их данных — уже не упоминаем преобразователи, предполагая, что "компилятор" подставит их сам исходя из заданных отношений входов и выходов функций один раз в начале программы. Так? ... А что карсиво получется.
Есть и другой подход — единая библиотека типов и следование ей всех производителей.
А представьте себе язык, который начинается с описания выходных данных, например (это что-то вроде цели), от которых можно оттолкнуться и черех лес отношений с другими данными перейти к пониманию как эта цель достигается и как другие данные, а также отношения меду ними влияют на результат (тяни-толкай).
Функциональные языки так построены. Проблема, на мой взгляд, в том, что это нишевые задачи. А задачи из реальной жизни — "давайте напишем paint". И какие в графическом редакторе будут входные или выходные данные? Или виртуальную машину. Или средство удаленного доступа. Или GUI для системы управления задачами.
А представьте себе язык, который начинается с описания выходных данных, например (это что-то вроде цели), от которых можно оттолкнуться и черех лес отношений с другими данными перейти к пониманию как эта цель достигается и как другие данные, а также отношения меду ними влияют на результат (тяни-толкай).
EOH>Функциональные языки так построены. Проблема, на мой взгляд, в том, что это нишевые задачи. А задачи из реальной жизни — "давайте напишем paint". И какие в графическом редакторе будут входные или выходные данные? Или виртуальную машину. Или средство удаленного доступа. Или GUI для системы управления задачами.
Ну во первых ФЯП в отношении ДАННЫХ тоже построены как Процедурные языки. Вот например из статьи:
"Программа на языке Хаскелл — функция, описывающая процесс вычисления."
Нет там никакого императивно-ведущего описания данных. Переменные путаются под ногами ФУНКЦИЙ — как везде.
А во вторых — никакой нишевости нет. Есть традиции мышления, которые сложно преодолевать. Как бы я писал наинт на ФП:
Тут — если вычислена Функция_определения_кисти и СобытиеКнопкиМыши(), то вычислися функция Функция_Ожидающая_события и быдет определена Точка_области_рисованяи — которая может быть структурой данных непосредственно адресованной на канву рисования.
Здравствуйте, salog, Вы писали:
S>Здравствуйте, VladD2, Вы писали:
VD>>Уверен, что основная проблема тут или в языке, или в его знании. Не возьмусь угадать сам язык, но точно сказать, что это классический ООЯ. Причем если это C#, то с LINQ-ом ты незнаком.
S>Спасибо за упоминание. Я слышал естественно, но не вникал. Щас сижу читаю статью.
И даже не только/столько LINQ, как ADO.NET Entity Framework.
Hibernate наверное что-то подобное для Явы.
Здравствуйте, salog, Вы писали:
S>Здравствуйте, Eye of Hell, Вы писали:
S>А во вторых — никакой нишевости нет. Есть традиции мышления, которые сложно преодолевать. Как бы я писал наинт на ФП:
S>Тут — если вычислена Функция_определения_кисти и СобытиеКнопкиМыши(), то вычислися функция Функция_Ожидающая_события и быдет определена Точка_области_рисованяи — которая может быть структурой данных непосредственно адресованной на канву рисования.
Если говорить слегка категорично, то единственная современная проблема программирования — это сложность.
Если я правильно вас понял, то программу в вашем понимании можно представить как совокупность наборов:
ФорматДанных1 < ФункцияПреобразвания + СобытиеЗапускаПреобразования > ФорматДанных2
плюс граф зависимостей таких наборов между собой и средства, которые контролируют "наведенные" преобразования.
Такая модель действительно очень удобная во многих случаях, более того, частные ее случаи реализованы в промышленных языках программирования, датабиндиг, сериализация и т.п.
Хотя, например, в .НЕТ реализовать свой датабиндиг — геморрой конкретный, именно из-за отсутствия встроенных средств контроля неконтролируемых каскадных событий преобразования.
Собственно, то, что вы описываете (опять же, если я правильно понял) — это парадигма/способ/стратегия проектирования и реализации, и применять ее можно даже в С++.
Специализированные языки программирования привносят лишь удобство.
Более того, я не случайно в начале упомянул о сложности.
В сложном приложении потоки событий будут очень сложными и запутанными, и фактически разобраться в них может быть сложнее, в императивном коде.
Более того, на сложность понимания напрямую влияет естественность концепции — к примеру,
для UI наиболее естественной (и поэтому такой распространенной) является модель реакции на события пользовательского ввода.
Данные же как функция от пользовательского интерфейса — согласитесь, это менее очевидная для понимания вещь, хотя и более чистая и абстрактная.
Кроме того, остается вопрос производительности.
К примеру, функциональные языки элегантны во многом за счет иммутабельности данных,
но в то же время — в корне многих оптимизаций производительности лежит именно мутабельность данных.
Здравствуйте, salog, Вы писали:
S>А представьте себе язык, который начинается с описания выходных данных, например (это что-то вроде цели), от которых можно оттолкнуться и черех лес отношений с другими данными перейти к пониманию как эта цель достигается и как другие данные, а также отношения меду ними влияют на результат (тяни-толкай). В таком подходе не страдает и процедурная сторона — процедуры по прежнему явно читаемы и их место в общем алгоритме понятно. А в отношении данных, за счет их выставления на показ и возможности проследить все "руки", тянущихся к ним отношений — степень выразительности и понимания программы значительно возрастает. А значит — программы становится и легче читать.
Вот вы и пришли самостоятельно практически к тому же самому, что написал "Эдсгер Дейкстра в своей книжке "Дисциплина программирования"...
Вывод слабейшего предусловия на основе требуемого постусловия... Он и язык соответствующий там описывает...
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
sto>Кроме того, остается вопрос производительности. sto>К примеру, функциональные языки элегантны во многом за счет иммутабельности данных, sto>но в то же время — в корне многих оптимизаций производительности лежит именно мутабельность данных.
Зато в корне других оптимизаций (особенно в многопоточной среде) наоборот лежит иммутабельность данных