Привет, может кто-нибудь находил в инете инфу по метапрограммированию.
Интересуют принципы выделения и организации низкоуровневой структуры, и
методы конструирования мета-конструкций на основе предыдущего (нижнего) слоя понятий.
Нужно для создания древовидного конструктора программ.
— Основная идея — снизить порог вхождения в написание программ на любом языке,
используя принцип конструктора — каждая выбранная деталь определяет множество возможных
следующих деталей, что разгружает память от необходимости помнить синтаксис программы.
— Например, (Паскаль, консольный вариант) для создания программы достаточно заполнить два элемента —
название программы (строка) и список команд (дерево). Все другие секции (константы, типы,
переменные, процедуры), могут генерироваться для компилятора автоматически. Пользователь
будет их объявлять в первом месте использования. То есть редактирование в месте использования.
Динамически конструируемое дерево это легко позволяет.
— Уже несколько месяцев бьюсь над структурой конструирования мета-конструкций.
— Реализовать хотелось бы на javascript + sql (web kit html5), так как интересно сделать
конструктор на чистом браузере (для тачскринов).
по-большому счету, нет никаких специальных мета-конструкций.
есть лишь:
числа
логические величины
последовательности/множества/дерево/граф
операции над числами/логическими величинами/последовательностями и т.д.
исполнитель и операции над ним
мета же появляется только в виде того, что саму программу можно представить, например, в виде дерева. и применить к программе все те же самые операции, которые применяются к дереву.
типичным примером такого подхода являются макросы: когда программа рассматривается как текст (сишные макросы), или как дерево (nemerle)
слои же строятся на основе моделей/парадигм, например, поверх байтовой последовательности строятся сложные типы/структуры, поверх стеко-регистровой машинки строится ооп и т.д.
Здравствуйте, lseder, Вы писали:
L>Привет, может кто-нибудь находил в инете инфу по метапрограммированию. L>Интересуют принципы выделения и организации низкоуровневой структуры, и L>методы конструирования мета-конструкций на основе предыдущего (нижнего) слоя понятий.
... L>- Уже несколько месяцев бьюсь над структурой конструирования мета-конструкций.
Замах на рубль...
L>- Реализовать хотелось бы на javascript + sql (web kit html5), так как интересно сделать L>конструктор на чистом браузере (для тачскринов).
желания-то как раз все грамотные:
сейчас действительно не хватает простых средств разработки для веба,
и да, это действительно можно добиться через полуавтоматическую обработку мелочей,
и слоистую структуру программы
Здравствуйте, lseder, Вы писали:
L>Привет, может кто-нибудь находил в инете инфу по метапрограммированию. L>Интересуют принципы выделения и организации низкоуровневой структуры, и L>методы конструирования мета-конструкций на основе предыдущего (нижнего) слоя понятий.
Идея средства программирования, которое бы позволяло пользователю "складывать" программы из "кубиков" по аналогии с конктруктором LEGO витает очень давно. Однако все попытки сделать это провалились.
Вопрос — почему?
Здравствуйте, 0x7be, Вы писали:
0>Вопрос — почему?
1. В конечном счёте кубики уступают по выразительности нескольким строчкам кода.
2. Человек способен ошибаться, даже тасуя прямоугольники в графическом редакторе.
Здравствуйте, Sinix, Вы писали:
0>>Вопрос — почему? S>1. В конечном счёте кубики уступают по выразительности нескольким строчкам кода.
Когда надо написать "1+1", то да. А если я хочу, что-то более "масштабное", то надо быть Донцовой, чтобы быстро и "выразительно" получить желаемое.
S>2. Человек способен ошибаться, даже тасуя прямоугольники в графическом редакторе.
Это ты серьёзно сравниваешь количество ошибок при тусовании кубиков и при написании кода?
R3>Когда надо написать "1+1", то да. А если я хочу, что-то более "масштабное", то надо быть Донцовой, чтобы быстро и "выразительно" получить желаемое.
Наоборот что-то простое из кубиков получается быстро, красиво и выразительнее текста, чуть сложнее текст оказывается на порядок и проще и выразительнее.
Здравствуйте, Real 3L0, Вы писали:
R3>Вероятно потому, что всё это было не юзабельно. Кубики — они из названия подразумевают "лёгкость", но я ещё не встречал простого средства разработки.
Потому, что эти "кубики" не устраняли главной сложности в программировании, они решали не ту проблему.
Точно по той же причине провалились попытки сделать программирование простым, приблизив синтаксис языков к английскому.
Здравствуйте, 0x7be, Вы писали:
R3>>Вероятно потому, что всё это было не юзабельно. Кубики — они из названия подразумевают "лёгкость", но я ещё не встречал простого средства разработки. 0>Потому, что эти "кубики" не устраняли главной сложности в программировании, они решали не ту проблему.
А какую проблему они решали?
0>Точно по той же причине провалились попытки сделать программирование простым, приблизив синтаксис языков к английскому.
Здравствуйте, FR, Вы писали:
R3>>Когда надо написать "1+1", то да. А если я хочу, что-то более "масштабное", то надо быть Донцовой, чтобы быстро и "выразительно" получить желаемое. FR>Наоборот что-то простое из кубиков получается быстро, красиво и выразительнее текста, чуть сложнее текст оказывается на порядок и проще и выразительнее.
Мы живём в разных реальностях.
Пример 1.
Давай я тебе дам исходники, а ты не компилируя их, сможешь рассказать, что делает программа? Сколько времени у тебя на это уйдёт?
А теперь посмотрим на какой-нибудь бизнес-процесс, представленный в виде какой-нибудь модели (какой-нибудь нотации)? Сколь времени уйдёт на это? И заметь, я даже не уточнял — какую именно нотацию брать, что абсолютно невозможно опустить при просмотре исходников.
Пример 2.
Я уже как-то писал. Мне понадобилось в программу вставить проверку email-ящика. Просто — тупо открыть письмо и прочитать текст. ... Узнал много "офигенно полезной и нужной мне в данный момент" информации, типа MIME.
Или другой пример. Мне надо было подготовить данные, вставить их в контролы на форме, после чего показать форму пользователю. ... Узнал много "офигенно полезной и нужной мне в данный момент" информации, типа handle окна.
Здравствуйте, Real 3L0, Вы писали:
R3>Когда надо написать "1+1", то да. А если я хочу, что-то более "масштабное", то надо быть Донцовой, чтобы быстро и "выразительно" получить желаемое.
Да нет, просто в случае кода мы можем произвольно менять детализацию — вынося всё ненужное в методы и дописав мелкие костыли прям по месту. В случае с "кубиками" все костыли приходится изображать в виде кубиков же, что напрочь убивает юзабилити.
На самом деле, при наличии в команде хороших архитекторов и автоматизации контроля за качеством кода, результат по наглядности и удобству использования не сильно отстаёт от аналогичной блок-схемы.
S>>2. Человек способен ошибаться, даже тасуя прямоугольники в графическом редакторе. R3>Это ты серьёзно сравниваешь количество ошибок при тусовании кубиков и при написании кода?
Абсолютно. Как наглядный пример — попробуйте сделать что угодно неординарное в любом генераторе инсталляторов (например, в штатном от студии), и то же самое — кодом.
Пример из личной практики — на громадный пакет SSIS (workflow в чистом виде) ушло примерно 2 с половиной недели. В основном — на борьбу с дизайнером и дописывание своих action-ов. После чего всю эту радость выбросили нафиг и за день заменили самописным вариантом.
Здравствуйте, Sinix, Вы писали:
S>Да нет, просто в случае кода мы можем произвольно менять детализацию — вынося всё ненужное в методы и дописав мелкие костыли прям по месту. В случае с "кубиками" все костыли приходится изображать в виде кубиков же, что напрочь убивает юзабилити.
Как оно может убить то, чего нет? Повторюсь (и ты сам это знаешь) — на текущий момент нет юзабильной "платформы, управляющей кубиками". (*)
S>На самом деле, при наличии в команде хороших архитекторов и автоматизации контроля за качеством кода, результат по наглядности и удобству использования не сильно отстаёт от аналогичной блок-схемы.
+1. Только вот так и получается, чтобы написать "чтение почты из ящика", надо обладать знаниями архитектора. Не всем оно надо.
S>>>2. Человек способен ошибаться, даже тасуя прямоугольники в графическом редакторе. R3>>Это ты серьёзно сравниваешь количество ошибок при тусовании кубиков и при написании кода? S>Абсолютно. Как наглядный пример — попробуйте сделать что угодно неординарное в любом генераторе инсталляторов (например, в штатном от студии), и то же самое — кодом.
Не имел с этим дел. Но понимаю, ибо (*).
S>Пример из личной практики — на громадный пакет SSIS (workflow в чистом виде) ушло примерно 2 с половиной недели. В основном — на борьбу с дизайнером и дописывание своих action-ов. После чего всю эту радость выбросили нафиг и за день заменили самописным вариантом.
И опять (*).
Это всё равно, как развитие тачскрин-экранов: их придумали пару десяткок лет назад, но технология не стала популярной. Пока не появился сифон.
С кубиками пока такая же фигня: они придуманы давно, но нет удобного механизма их использования.
Если немного пофантазировать.
Кубики — это техника: определённу яму можно выкопать быстро и легко, но только определённым экскаватором. Чтобы выкопать яму другого размера, надо брать другой экскаватор. Маленькую ямку ("1+1") выкопать нельзя никаким экскаватором. Другой техникой — можно, но сразу много ямок. Чтобы проделать тунель для метро — нужна другая техника.
Но всё этом можно сделать обычной лопатой, причём включая маленькую ямку.
Так что, будем сильнее натачивать лопату или будем придумывать новую технику?
Вот например, есть ли хоть один "конструктор кубиков", который бы использовал онлайн-базу этих кубиков, что-то типа магазина-приложений? Я не встречал. О каком удобстве тогда стоит говорить, если нет основного механизма.
А если бы "нечто неординарное", что ты не смог сделать в генераторе инсталяторе, уже присутствовало бы в виде кубика в этом инсталяторе, ты бы тоже считал его "ацтоем"?
Конечно, через некоторое время тебе бы попался кубик, который выдаёт результат на 99% как надо, а 1% — не так. Если этот 1% для тебя очень важен, то сейчас переписывается весь кубик. Если же этот кубик состоял бы из других кубиков, то ты бы просто заменил ненужный кубик на правильный.
В общем, опять (*).
Здравствуйте, lseder, Вы писали:
L>Привет, может кто-нибудь находил в инете инфу по метапрограммированию. L>Интересуют принципы выделения и организации низкоуровневой структуры, и L>методы конструирования мета-конструкций на основе предыдущего (нижнего) слоя понятий.
Чего-то вменяемого для начинающих нет. Есть много разрозненной и очень специализированной информации, зачастую в научных работах.
Есть более менее продуманные и работающие решения: Lisp, Nemerle, MPS.
Есть куча решений застрявших на стадии прототипов.
L>Нужно для создания древовидного конструктора программ. L>- Основная идея — снизить порог вхождения в написание программ на любом языке, L>используя принцип конструктора — каждая выбранная деталь определяет множество возможных L>следующих деталей, что разгружает память от необходимости помнить синтаксис программы.
Какая-то не проработанная идея. Бессмысленная, я бы сказал.
Сокрытие деталей называется абстрагированием и инкапсуляцией. В программистском мире на сегодня имеется три проработанные концепции позволяющие добиться повышения абстракции:
1. Функции.
2. Объекты.
3. Языки предметной области — DSL.
Понизить порог вхождения они не могут, так как решают другую задачу — повышение уровня кода. Обычно чтобы понимать более высокоуровневый код нужно знать больше концепций, что никак не может понижать планку вхождения (если понимать под этим уровень знаний). Абстракция понижает сложность восприятия. Потратив время на понимание концепций потом можно быстрее понять программу целиком. Но это не тоже самое что понижение планки вхождения в язык.
L>- Например, (Паскаль, консольный вариант) для создания программы достаточно заполнить два элемента - L>название программы (строка) и список команд (дерево). Все другие секции (константы, типы, L>переменные, процедуры), могут генерироваться для компилятора автоматически. Пользователь L>будет их объявлять в первом месте использования.
Эту проблему просто не надо решать. Просто возьмите файл-заготовку где все секции уже будут и заполните только те секции что надо. Или еще проще — возьмите более современный язык в котором можно не писать всего этого оберточного кода (Руби, Питон, Немерл, Жабаскрипт, Лисп, ...).
L>То есть редактирование в месте использования. L>Динамически конструируемое дерево это легко позволяет.
А нужно ли это кому-либо? Мне кажется — нет.
Людям нужны более высокоуровневые конструкции.
Скажем в Яве отсутствуют такие концепции как лябды, итераторы, конструкции детерминированной финализации и т.п. По этому многие называют ее менее удобной и более низкоуровневой. Вот добавление таких конструкций в язык было бы оправдано.
Другой пример — встраивание в язык DSL-ей. Например, многие часто используют в своих программах SQL, XML и регексы. Встроить их в язык, так чтобы их было удобно использовать в этом языке даст ощутимую пользу. Во многие ЯП эти DSL-и хардкодятся. Это несомненно плохо. И возможность расширять базовый язык DSL-ями опять же полезна.
Но у вас какие-то сумбурные идеи. Они смело решаются текстовым препроцессором вроде препроцессора С.
Мне кажется вам нужно в первую очередь доработать свои идеи. А для этого имеет смысл познакомиться с теми идеями, что есть у других. И дело тут не в метапрограммирвоании.
L>- Уже несколько месяцев бьюсь над структурой конструирования мета-конструкций.
Я бьюсь над этой задачей последние 10 лет и пока что не доволен результатом на 100%.
L>- Реализовать хотелось бы на javascript + sql (web kit html5), так как интересно сделать L>конструктор на чистом браузере (для тачскринов).
sql то ту причем? Как он с броузерам может быть связан?
javascript, как многие скриптовые языки, обладает возможностями метапрограммирования за счет прототипного ООП и возможности динамически выполнять код. Средства эти не очень удобные, но приемлемые для использования.
ЗЫ
В общем, сначала постарайтесь сформулировать саму идею (задачу). А потом уже будет смысл думать о средствах.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Real 3L0, Вы писали:
R3>Как оно может убить то, чего нет? Повторюсь (и ты сам это знаешь) — на текущий момент нет юзабильной "платформы, управляющей кубиками". (*)
Угу. Так предложите Проблема в том, что обычный код уже подошёл к пределу выразительности и даже уполз за него (если мы говорим о хардкорном ФП). Попробуйте выразить это
var customer = customers.Where(c => c.Age > 18 && c.NotBanned).Skip(123).FirstOrDefault();
в виде кубиков. А теперь — метод, в котором подобных строк — штук 5. А теперь — код, который оперирует парой сотен таких методов
R3>+1. Только вот так и получается, чтобы написать "чтение почты из ящика", надо обладать знаниями архитектора. Не всем оно надо.
Зависит от фреймворка. Если готовый компонент есть — какая разница между использованием его из кода или дизайнера? А вот если нет — с дизайнером всё, с кодом можно побарахтаться
R3>Это всё равно, как развитие тачскрин-экранов: их придумали пару десяткок лет назад, но технология не стала популярной. Пока не появился сифон. R3>С кубиками пока такая же фигня: они придуманы давно, но нет удобного механизма их использования.
Ну так тачскрин остаётся весьма узконишевой нишей. В качестве основного устройства управления он оччень неудобен, особенно — на больших экранах. Со всякими workflow-движками ситуация абшолютно аналогичная: не взлетят
R3>Так что, будем сильнее натачивать лопату или будем придумывать новую технику?
Увы, лучше затариться археологическими кисточками. Лопата — слишком грубый инструмент
R3>Вот например, есть ли хоть один "конструктор кубиков", который бы использовал онлайн-базу этих кубиков, что-то типа магазина-приложений? Я не встречал. О каком удобстве тогда стоит говорить, если нет основного механизма.
Ну будет онлайн магазин — что, появится контент? Неа, пара-тройка полезных вещей (о которых и так все кому надо знают) просто потонет под тонной багоподелок. И так — в любом магазине, спасает только поиск (если уже знаешь что искать).
R3>А если бы "нечто неординарное", что ты не смог сделать в генераторе инсталяторе, уже присутствовало бы в виде кубика в этом инсталяторе, ты бы тоже считал его "ацтоем"?
Неа. Потому что на все случаи жизни кубиков не напасёшься. Особенно для экзотики наподобие гусеничных ужоежей.
R3>Если же этот кубик состоял бы из других кубиков, то ты бы просто заменил ненужный кубик на правильный.
Угу. Тем самым взяв на себя обязанность сопровождать ещё и чужой кубик — следить за обновлениями, разруливать конфликты, править костыли... Ба, мы опять вернулись к тому, от чего убегали
Здравствуйте, Real 3L0, Вы писали:
0>>Потому, что эти "кубики" не устраняли главной сложности в программировании, они решали не ту проблему. R3>А какую проблему они решали?
Они пытались упростить синтаксис, сделать так, что бы он *выглядел* как нечто знакомое.
0>>Точно по той же причине провалились попытки сделать программирование простым, приблизив синтаксис языков к английскому. R3>Про это я ничего не говорил.
Это я уже подбрасываю угля в тему
Здравствуйте, Real 3L0, Вы писали:
FR>>Наоборот что-то простое из кубиков получается быстро, красиво и выразительнее текста, чуть сложнее текст оказывается на порядок и проще и выразительнее.
R3>Мы живём в разных реальностях.
R3>Пример 1. R3>Давай я тебе дам исходники, а ты не компилируя их, сможешь рассказать, что делает программа? Сколько времени у тебя на это уйдёт? R3>А теперь посмотрим на какой-нибудь бизнес-процесс, представленный в виде какой-нибудь модели (какой-нибудь нотации)? Сколь времени уйдёт на это? И заметь, я даже не уточнял — какую именно нотацию брать, что абсолютно невозможно опустить при просмотре исходников.
Неудачный пример, исходники можно все же скомпилировать и получить программу. Модель скомпилировать нельзя, там явно недостаточно информации. Как только начинается попытка довести ее до достаточной на реальных задачах — все оказывается плачевно. Для каждого кубика приходится писать кучу кода, который читать и поддерживать гораздо сложнее чем те исходники.
R3>Пример 2. R3>Я уже как-то писал. Мне понадобилось в программу вставить проверку email-ящика. Просто — тупо открыть письмо и прочитать текст. ... Узнал много "офигенно полезной и нужной мне в данный момент" информации, типа MIME.
Плохой пример, кубик тут бы помог настолько же, насколько поможет любая нормальная библиотека. Но шаг влево, шаг вправо кубик пришлось бы выкинуть и писать в рукопашную.
R3>Или другой пример. Мне надо было подготовить данные, вставить их в контролы на форме, после чего показать форму пользователю. ... Узнал много "офигенно полезной и нужной мне в данный момент" информации, типа handle окна.
Хороший пример. Для дизайна форм кубики прижились, хотя html/xaml люди предпочитают делать опять же в коде.
L>>- Реализовать хотелось бы на javascript + sql (web kit html5), так как интересно сделать L>>конструктор на чистом браузере (для тачскринов).
VD>sql то ту причем? Как он с броузерам может быть связан?
Здравствуйте, 0x7be, Вы писали:
0>Здравствуйте, lseder, Вы писали:
L>>Привет, может кто-нибудь находил в инете инфу по метапрограммированию. L>>Интересуют принципы выделения и организации низкоуровневой структуры, и L>>методы конструирования мета-конструкций на основе предыдущего (нижнего) слоя понятий. 0>Идея средства программирования, которое бы позволяло пользователю "складывать" программы из "кубиков" по аналогии с конктруктором LEGO витает очень давно. Однако все попытки сделать это провалились. 0>Вопрос — почему?
а я знаю! а я знаю! но не скажу!!!!!!
Тут есть монго формулировок других: почему не получается разбить задачу на составные части так, чтобы части можно было изменять независимо друг от друга.
Здравствуйте, 0x7be, Вы писали:
0>Здравствуйте, Real 3L0, Вы писали:
R3>>Вероятно потому, что всё это было не юзабельно. Кубики — они из названия подразумевают "лёгкость", но я ещё не встречал простого средства разработки. 0>Потому, что эти "кубики" не устраняли главной сложности в программировании, они решали не ту проблему. 0>Точно по той же причине провалились попытки сделать программирование простым, приблизив синтаксис языков к английскому.
100% — именно эта причина, у естественного языка получится бесконечная грамматика если попытаться создать компилятор.
Здравствуйте, Real 3L0, Вы писали:
R3>Здравствуйте, 0x7be, Вы писали:
0>>Вопрос — почему?
R3>Вероятно потому, что всё это было не юзабельно. Кубики — они из названия подразумевают "лёгкость", но я ещё не встречал простого средства разработки.
Да ладно. COM + VB — отличный кубики, все очень легко и просто.
Или Дельфи с ее компонентами.
Кубики писать — да, геморрой, а из имеющихся кубиков все очень легко собирается.
Здравствуйте, Ziaw, Вы писали:
Z>Неудачный пример, исходники можно все же скомпилировать и получить программу. Модель скомпилировать нельзя, там явно недостаточно информации. Как только начинается попытка довести ее до достаточной на реальных задачах — все оказывается плачевно. Для каждого кубика приходится писать кучу кода, который читать и поддерживать гораздо сложнее чем те исходники.
Это потому, что нет хорошего конструктора кубиков (КК). Ты описываешь проблемы, присутствующие в существующих КК. Но почему они должны быть в будущих (ещё не созданных) КК?
Например, проблема недостатка информации. Почему её нельзя решить? Вспомни какой-нибудь процесс (последовательность действий), выполненный много раз на компьютере. Думаю, при выполнении этого процесса ты вводил какие-то данные. Почему компьютер не сохранил эти данные при первом вводе, чтобы автоматически ввести их при повторном запуске процесса? Чтобы ты мог ввести (выбрать) другие данные. Но зачем тебе вводить другие данные? Потому что изменились начальные данные. Так почему начальные данные не предоставляют информацию о том, что с ними можно сделать?
Я очень сильно сомневаюсь, что проблема недостатка информации существует. Вот проблема получения информации — существует.
R3>>Я уже как-то писал. Мне понадобилось в программу вставить проверку email-ящика. Просто — тупо открыть письмо и прочитать текст. ... Узнал много "офигенно полезной и нужной мне в данный момент" информации, типа MIME. Z>Плохой пример, кубик тут бы помог настолько же, насколько поможет любая нормальная библиотека. Но шаг влево, шаг вправо кубик пришлось бы выкинуть и писать в рукопашную.
Библиотека — это и есть кубик, но в мире программирования. Либо пишешь код руками (без КК; узнавая, что такое MIME), либо используешь библиотеку (с КК; не узнавая, что такое MIME). Так что нормальный пример.
Здравствуйте, Real 3L0, Вы писали:
R3>Здравствуйте, jazzer, Вы писали:
J>>Кубики писать — да, геморрой, а из имеющихся кубиков все очень легко собирается.
R3>Отсутствует механизм поиска нужного кубика
гугл?
R3>следовательно лёгкость отсутствует в принципе.
странная логика
Здравствуйте, Sinix, Вы писали:
S>Угу. Так предложите
Ещё не доделал.
S> Проблема в том, что обычный код уже подошёл к пределу выразительности и даже уполз за него (если мы говорим о хардкорном ФП). Попробуйте выразить это S>
S>в виде кубиков. А теперь — метод, в котором подобных строк — штук 5. А теперь — код, который оперирует парой сотен таких методов
А зачем нужно создавать кубик, который будет аналогичен одной строки кода?
Я исхожу из идеи, что кубик должен выполнять полноценное действие.
S>Ну так тачскрин остаётся весьма узконишевой нишей. В качестве основного устройства управления он оччень неудобен, особенно — на больших экранах.
На больших экранах — это потому, что устаёшь рукой махать. Возможно имеет смысл выделить "область управляния", которая будет меньше экрана, и через которую будет осуществляться управление.
S> Со всякими workflow-движками ситуация абшолютно аналогичная: не взлетят
Ну, пока вроде бы летают.
R3>>Так что, будем сильнее натачивать лопату или будем придумывать новую технику? S>Увы, лучше затариться археологическими кисточками. Лопата — слишком грубый инструмент
Нее, это не мой путь. Думаю, лень в итоге всё равно победит.
S>Ну будет онлайн магазин — что, появится контент? Неа, пара-тройка полезных вещей (о которых и так все кому надо знают) просто потонет под тонной багоподелок. И так — в любом магазине, спасает только поиск (если уже знаешь что искать).
Проблема с тонной багоподелок решаема.
S>Неа. Потому что на все случаи жизни кубиков не напасёшься. Особенно для экзотики наподобие гусеничных ужоежей.
На все — нет. На 99% (сам же использовал слово "экзотика" ) — да.
R3>>Если же этот кубик состоял бы из других кубиков, то ты бы просто заменил ненужный кубик на правильный. S>Угу. Тем самым взяв на себя обязанность сопровождать ещё и чужой кубик — следить за обновлениями, разруливать конфликты, править костыли... Ба, мы опять вернулись к тому, от чего убегали
Эээ, с чего это? Ты сопровождаешь только свой кубик.
Здравствуйте, jazzer, Вы писали:
R3>>Отсутствует механизм поиска нужного кубика J>гугл?
Он тут не помощник.
Кстати, на днях искал инфу по определённому файлу: вбил название — гугель выдал мне 3 страницы ссылок на ресурсы, которые за денюжку починят мне все проблемы с этим файлом.
Т.е. для поиска кубиков нужен поисковик, заточенный на поиск кубиков. Потому что параметров у этих кубиков будет немало.
R3>>следовательно лёгкость отсутствует в принципе. J>странная логика
Здравствуйте, Real 3L0, Вы писали:
R3>Здравствуйте, jazzer, Вы писали:
R3>>>Отсутствует механизм поиска нужного кубика J>>гугл?
R3>Он тут не помощник. R3>Кстати, на днях искал инфу по определённому файлу: вбил название — гугель выдал мне 3 страницы ссылок на ресурсы, которые за денюжку починят мне все проблемы с этим файлом. R3>Т.е. для поиска кубиков нужен поисковик, заточенный на поиск кубиков. Потому что параметров у этих кубиков будет немало.
Я к тому, что поиск кубика ортогонален языку.
А то так можно договориться до того, что трудно найти сотрудников, дешевый офис и страну с низкими налогами.
R3>>>следовательно лёгкость отсутствует в принципе. J>>странная логика
R3>А оно так.
Здравствуйте, Real 3L0, Вы писали:
S>> Проблема в том, что обычный код уже подошёл к пределу выразительности и даже уполз за него (если мы говорим о хардкорном ФП). Попробуйте выразить это
var customer = customers.Where(c => c.Age > 18 && c.NotBanned).Skip(123).FirstOrDefault();
S>>в виде кубиков. А теперь — метод, в котором подобных строк — штук 5. А теперь — код, который оперирует парой сотен таких методов R3>А зачем нужно создавать кубик, который будет аналогичен одной строки кода?
В таком случае вам будут нужны миллионы слабоотличающихся кубиков.
S>>Ну так тачскрин остаётся весьма узконишевой нишей. В качестве основного устройства управления он оччень неудобен, особенно — на больших экранах. R3>На больших экранах — это потому, что устаёшь рукой махать. Возможно имеет смысл выделить "область управляния", которая будет меньше экрана, и через которую будет осуществляться управление.
И мы получаем обычный тачпад, только руку на весу держать надо.
S>> Со всякими workflow-движками ситуация абшолютно аналогичная: не взлетят R3>Ну, пока вроде бы летают.
Но низэнько-низэнько(с)
S>>Ну будет онлайн магазин — что, появится контент? Неа, пара-тройка полезных вещей (о которых и так все кому надо знают) просто потонет под тонной багоподелок. И так — в любом магазине, спасает только поиск (если уже знаешь что искать). R3>Проблема с тонной багоподелок решаема.
Ни в одном онлайн-каталоге её не решили. И решать не будут, т.к. это требует привлечения на порядок больших расходов и только мешает основной цели существования сайа — продать/привлечь побольше посетителей.
S>>Неа. Потому что на все случаи жизни кубиков не напасёшься. Особенно для экзотики наподобие гусеничных ужоежей. R3>На все — нет. На 99% (сам же использовал слово "экзотика" ) — да.
80-20%
R3>>>Если же этот кубик состоял бы из других кубиков, то ты бы просто заменил ненужный кубик на правильный. S>>Угу. Тем самым взяв на себя обязанность сопровождать ещё и чужой кубик — следить за обновлениями, разруливать конфликты, править костыли... Ба, мы опять вернулись к тому, от чего убегали R3>Эээ, с чего это? Ты сопровождаешь только свой кубик.
Неа, раз уж взялся лезть во внутренности чужого кода — будь добр сам нести ответственность за последствия.
Здравствуйте, Sinix, Вы писали:
S>Здравствуйте, Vaako, Вы писали:
V>>а я знаю! а я знаю! но не скажу!!!!!!
S>Да не надо гадать, рано или поздно любая система начинает работать на скотче, клее и побочных эффектах. Эволюция
Ураган просто после такого начинаешь думать о естественном язык как самом непонятном языке на свете. Менеджер произнес фразу из ТЗ с другим акцентом и программист уже решил, что от него требуется совсем другое Тут нужна экспертная система не уступающая человеческому интеллекту, чтобы понять что хочет заказчик (какие кубики), а только потом переходить к задачке: как же нам эти кубики порасставлять чтобы получить желаемое.
У меня была одна кубическая задача которая произвела на меня сильное впечатление. Начальник моего начальника нарисовал прямоугольник, это была сложная система много-много строчек кода, потом добавил еще один прямоугольничек — это была другая система еще сложнее. Соединив их он произнес "вот так это происходит сейчас". Потом стер линию и нарисовал вместо нее третий приямоуголник соединив его с первыми двумя. Вердикт был следующим: "написать программное обеспечение чтобы некоторые функции первых двух прямоугольником изменились". На вопрос "но это потребует некоторой модификации первой системы (прямоугольничка)" был получен исчерпывающий ответ "ну что вы задаете глупые вопросы, я же все нарисовал понятным языком".
Позвольте уточнить.
Никаких новых кубиков сверх тех которые вводятся в курсе
программирования в школе — переменная, условный переход, циклы, функции.
Вспомните правило — семь плюс минус два. Больше чем 7 разнородных элементов
показывать в окне выбора возможных элементов смысла нет. Все что больше, надо
группировать, и давать возможность искать по словам.
Мета-структуры нужны лишь мне, как разработчику пользовательского интерфейса.
>Удар на копейку!
Это прототип. Толку от идей на бумаге немного.
>Потратив время на понимание концепций потом можно быстрее понять >программу целиком. Но это не тоже самое что понижение планки вхождения в язык.
Смысл конструктора в абстрагировании от синтаксиса ввода конкретного языка.
Знакомство с основными концепциями программирования подразумевается как базовое условие
для любого программиста.
Мне показалось возможным разделить синтаксис языка на два элемента, которые лучше соответствуют
целям того самого синтаксиса. 1) Ввод программы, 2) Чтение программы.
Для первой задачи надо синтаксис покороче, вводить только то что необходимо — данные и структуру.
Для второй надо синтаксис по нагляднее и понятней, как пример тот же паскаль, разработанный
для обучению программирования.
>Мне кажется вам нужно в первую очередь доработать свои идеи. >А для этого имеет смысл познакомиться с теми идеями, что есть у других.
Если есть информация — давайте.
Здравствуйте, lseder, Вы писали:
>>Мне кажется вам нужно в первую очередь доработать свои идеи. >>А для этого имеет смысл познакомиться с теми идеями, что есть у других. L>Если есть информация — давайте.
Здравствуйте, Real 3L0, Вы писали:
R3>Здравствуйте, jazzer, Вы писали:
J>>А то так можно договориться до того, что трудно найти сотрудников, дешевый офис и страну с низкими налогами.
R3>А резве не так?
Так, конечно, но какое это отношение имеет к языку программирования? Мы же, вроде, о программировании тут говорим
Здравствуйте, Sinix, Вы писали:
R3>>А зачем нужно создавать кубик, который будет аналогичен одной строки кода? S>В таком случае вам будут нужны миллионы слабоотличающихся кубиков.
Сейчас не нужны, и потом не будут нужны. Кому нужен второй кубик, если есть первый, делающий тоже самое?
R3>>На больших экранах — это потому, что устаёшь рукой махать. Возможно имеет смысл выделить "область управляния", которая будет меньше экрана, и через которую будет осуществляться управление. S>И мы получаем обычный тачпад, только руку на весу держать надо.
Это было всего лишь моё предположение.
Но всё равно не надо думать, что тачскрин на больших экранах не нужен совсем.
S>>> Со всякими workflow-движками ситуация абшолютно аналогичная: не взлетят R3>>Ну, пока вроде бы летают. S>Но низэнько-низэнько(с)
Ага, и дорого. Т.е. кто-то готов платить, что бы ты не говорил.
R3>>Проблема с тонной багоподелок решаема. S>Ни в одном онлайн-каталоге её не решили. И решать не будут, т.к. это требует привлечения на порядок больших расходов и только мешает основной цели существования сайа — продать/привлечь побольше посетителей.
Не решили, потому что и не начинали решать.
И расходы нужны не большие. По крайней мере в моём решении этой проблемы. Но да — "привлечение" у меня страдает.
S>>>Неа. Потому что на все случаи жизни кубиков не напасёшься. Особенно для экзотики наподобие гусеничных ужоежей. R3>>На все — нет. На 99% (сам же использовал слово "экзотика" ) — да. S>80-20%
Абсолютное большинство необходимых функций уже реализована. Твою "экзотику", думаю уже тоже кто-то реализовал.
R3>>Эээ, с чего это? Ты сопровождаешь только свой кубик. S>Неа, раз уж взялся лезть во внутренности чужого кода — будь добр сам нести ответственность за последствия.
Чужой код и замена одного кубика — это разные вещи.
Здравствуйте, Real 3L0, Вы писали:
R3>Сейчас не нужны, и потом не будут нужны. Кому нужен второй кубик, если есть первый, делающий тоже самое?
Напоминаю, мы говорим о замене для
var customer = customers.Where(c => c.Age > 18 && c.NotBanned).Skip(123).FirstOrDefault();
Допустим, завтра мне потребуется добавить пару условий, послезавтра — брать последнего найденного кастомера, через месяц — считать статистику по неподпавшим под условие. Где вы наберёте кубиков для всего?
R3>Это было всего лишь моё предположение. R3>Но всё равно не надо думать, что тачскрин на больших экранах не нужен совсем.
Как основной способ управления — не нужен. Но давайте вернёмся к теме
S>>Ни в одном онлайн-каталоге её не решили. И решать не будут, т.к. это требует привлечения на порядок больших расходов и только мешает основной цели существования сайа — продать/привлечь побольше посетителей. R3>И расходы нужны не большие. По крайней мере в моём решении этой проблемы. Но да — "привлечение" у меня страдает.
Неа. Рецепты из серии "пчёлы против мёда" в жизни нифига не работают.
R3>>>Эээ, с чего это? Ты сопровождаешь только свой кубик. S>>Неа, раз уж взялся лезть во внутренности чужого кода — будь добр сам нести ответственность за последствия. R3>Чужой код и замена одного кубика — это разные вещи.
Не замена, а попытка вломиться в чужой код для добавления неподдерживаемых фич. Это оччень разные вещи.
Вообще все эти переливания из пустого в порожнее не имеют за собой никакой практической ценности. Пока вы не представите свое видение всей потребной инфраструктуры для массового и распределённого производства совместимых всемогуторов, мы так и будем перекидываться доводами "взлетит-не взлетит", "тачпады тоже нужны" и байками про простоту расширения чужого кода. Я таки самоустранюсь, вам — удачи и спасибо за приятный спор
с кубиками всё упирается в то, что:
1. не проработан вопрос модификации готового кубика
2. не проработан вопрос наследования одного кубика от другого
например, от кубика со структурой дом->квартира в текущих средах разработки почти невозможно перейти к кубику со структурой дом->подъезд->квартира или дом->этаж->квартира, не говоря уже о структуре дом->подъезд,этаж->квартира
S>Допустим, завтра мне потребуется добавить пару условий, послезавтра — брать последнего найденного кастомера, через месяц — считать статистику по неподпавшим под условие. Где вы наберёте кубиков для всего?
и чем не устраивают кубики:
.Where
.Age
18 >
&&
.NotBanned
.Skip
123
.FirstOrDefault
?
DG>>и чем не устраивают кубики: S>Всем устраивают. олько чем они отличаются от текущего положения дел?
тем что кроме мелких кубиков, нет крупных кубиков.
например,
кубик Where есть, но визуального(пользовательского) Where уже нет
кубик Linq есть, но визуального(пользовательского) Linq нет
и т.д.
Здравствуйте, DarkGray, Вы писали:
DG>тем что кроме мелких кубиков, нет крупных кубиков. DG> кубик Linq есть, но визуального(пользовательского) Linq нет DG>и т.д.
Workflow Foundation?
Проблема в том, что для пользователей вся эта требуха чрезмерно сложна, для программистов — слишком громоздка, вот и остаётся очень узкая ниша конфигурируемых продуктов.
это какой-то другой кубик.
S>Проблема в том, что для пользователей вся эта требуха чрезмерно сложна, для программистов — слишком громоздка, вот и остаётся очень узкая ниша конфигурируемых продуктов.
странная отмазка — особенно о том, что для пользователей — это слишком сложно.
например, в аналитических программах интерфейс еще сложнее, в тех же почтовиках, что bat, что mail.ru, что gmail — фильтры имеют именно такой функционал.
но в тоже время кубика нет, и каждый раз приходится делать велосипед заново.
Здравствуйте, jazzer, Вы писали:
J>>>А то так можно договориться до того, что трудно найти сотрудников, дешевый офис и страну с низкими налогами. R3>>А резве не так? J>Так, конечно, но какое это отношение имеет к языку программирования? Мы же, вроде, о программировании тут говорим
Так я и говорю, что сотрудников ищут не в гугле, а не специализированном сайте. Почему же ты считаешь, что для поиска нужного кубика будет достаточно гугля?
Здравствуйте, Sinix, Вы писали:
S>Допустим, завтра мне потребуется добавить пару условий, послезавтра — брать последнего найденного кастомера, через месяц — считать статистику по неподпавшим под условие. Где вы наберёте кубиков для всего?
Ну, фантазировать можно много. За всю мою карьеру в качестве аналитика, такие мелкие измения в процессах случались ну очень редко.
S>>>Ни в одном онлайн-каталоге её не решили. И решать не будут, т.к. это требует привлечения на порядок больших расходов и только мешает основной цели существования сайа — продать/привлечь побольше посетителей. R3>>И расходы нужны не большие. По крайней мере в моём решении этой проблемы. Но да — "привлечение" у меня страдает. S>Неа. Рецепты из серии "пчёлы против мёда" в жизни нифига не работают.
Ну почему же. Вот яблочники (вроде как) очень сильно следят за качеством программ.
R3>>Чужой код и замена одного кубика — это разные вещи. S>Не замена, а попытка вломиться в чужой код для добавления неподдерживаемых фич. Это оччень разные вещи.
Да с чего ты постоянное в этом примере прилепляешь "чужой код"? Когда ты используешь, например, log4net и у тебя падает приложение, ты первым делом думаешь, что проблема у log4net, или у тебя?
Или ты просто не можешь представить такой технологии, что кубики можно разделить (сделать независимыми между собой)?
S>Вообще все эти переливания из пустого в порожнее не имеют за собой никакой практической ценности. Пока вы не представите свое видение всей потребной инфраструктуры для массового и распределённого производства совместимых всемогуторов, мы так и будем перекидываться доводами "взлетит-не взлетит", "тачпады тоже нужны" и байками про простоту расширения чужого кода. Я таки самоустранюсь, вам — удачи и спасибо за приятный спор
Лучше бы ты помог мне реальным делом. Ну да ладно.
Здравствуйте, DarkGray, Вы писали:
DG>с кубиками всё упирается в то, что: DG>1. не проработан вопрос модификации готового кубика
Кубик, который является только кодом, т.е. не состоит из других кубиков, пусть подифицирует разработчик.
DG>2. не проработан вопрос наследования одного кубика от другого
А зачем нужно наследование кубиков? Взаимодействия не достаточно?
DG>например, от кубика со структурой дом->квартира в текущих средах разработки почти невозможно перейти к кубику со структурой дом->подъезд->квартира или дом->этаж->квартира, не говоря уже о структуре дом->подъезд,этаж->квартира
DG>>1. не проработан вопрос модификации готового кубика
R3>Кубик, который является только кодом, т.е. не состоит из других кубиков, пусть подифицирует разработчик.
не понятно откуда следует что этого достаточно для решения задач
DG>>2. не проработан вопрос наследования одного кубика от другого
R3>А зачем нужно наследование кубиков? Взаимодействия не достаточно?
если ограничиться только взаимодействием, то кубиков требуется бесконечное множество даже для простейших задач
DG>>например, от кубика со структурой дом->квартира в текущих средах разработки почти невозможно перейти к кубику со структурой дом->подъезд->квартира или дом->этаж->квартира, не говоря уже о структуре дом->подъезд,этаж->квартира
есть готовый кубик, который описывает целый дом, при этом он считает, что в дом напрямую "вставлены" квартиры.
например, такая модель достаточно для прописки, задания почтового адреса и т.д.
но, например, для расчета давления воды или для стоимости доставки до квартиры тяжелых грузов — нужно еще понятие Этаж.
и либо необходимо модифицировать уже готовый кубик Дом из предыдущего примера, либо разрабатывать с нуля новый.
Здравствуйте, DarkGray, Вы писали:
R3>>Кубик, который является только кодом, т.е. не состоит из других кубиков, пусть подифицирует разработчик. DG>не понятно откуда следует что этого достаточно для решения задач
Этого достаточно для решения некоторого колличества задач.
DG>>>2. не проработан вопрос наследования одного кубика от другого R3>>А зачем нужно наследование кубиков? Взаимодействия не достаточно? DG>если ограничиться только взаимодействием, то кубиков требуется бесконечное множество даже для простейших задач
Я не понимаю, почему все (кажется, все) используют в таких спорах аргумент, что необходимо решать какое-то бесконечное множество задач.
Современное программное обеспечение не решает бесконечное множество задач, тем не менее, их количества достаточно, для решения большинства задач и пользователи не сильно от этого страдают. В настоящее время они (пользователи) просят, например, от меня, решения опрделённого колличества их задач, но никак не бесконечного колличества.
Что же касается наследования, по-моему (возможно я не прав, ибо не думал в эту сторону), оно ничем не лучше взаимодействия (возможно, хуже).
Наследование: кубик Б наследован от кубика А == мы не можем легко (т.е. "ни о чём не думая") изменить кубик А, не поломав что-то в кубике Б; а также, кубик Б не имеет смысла существования, при отсутствии кубика А.
Взаимодействие: кубик Б взаимодействует с кубиком А, т.е. каждый из этих кубиков обладает полноценной системой, решающей определённое количество задач — кубик Б выполняет свои задачи и сообщает о результате кубику А, не зависимо от наличия кубика А (конечно, всё делается без потери данных).
Может я сейчас скажу неудачный пример, но вот для подсчёта количества объектов в списке, нам нужно знать типы/классы этих объектов, или достаточно знать того, что этого список?
DG>есть готовый кубик, который описывает целый дом, при этом он считает, что в дом напрямую "вставлены" квартиры. DG>например, такая модель достаточно для прописки, задания почтового адреса и т.д. DG>но, например, для расчета давления воды или для стоимости доставки до квартиры тяжелых грузов — нужно еще понятие Этаж. DG>и либо необходимо модифицировать уже готовый кубик Дом из предыдущего примера, либо разрабатывать с нуля новый.
Мне кажется, что ты как раз и показал, в чём заключается проблема наследования.
R3>Этого достаточно для решения некоторого колличества задач.
двух штук?
DG>>>>2. не проработан вопрос наследования одного кубика от другого R3>>>А зачем нужно наследование кубиков? Взаимодействия не достаточно? DG>>если ограничиться только взаимодействием, то кубиков требуется бесконечное множество даже для простейших задач
R3>Я не понимаю, почему все (кажется, все) используют в таких спорах аргумент, что необходимо решать какое-то бесконечное множество задач.
потому что есть такая наука комбинаторика
и она утверждает что даже малое кол-во элементов оперирует огромными числами.
например, такие числа как 12!, 2^20, 10^10 уже бесконечные с точки зрения практики, а они появляются лишь на наборах из 10-20 элементах
посчитай, например, сколькими способами можно вывести строчку, хотя бы в html
посчитай сколько способов не используется
посчитай сколько кубиков для вывода текста необходимо, если кубик для вывода текста не умеет модифицироваться.
R3>Современное программное обеспечение не решает бесконечное множество задач, тем не менее, их количества достаточно, для решения большинства задач и пользователи не сильно от этого страдают. В настоящее время они (пользователи) просят, например, от меня, решения опрделённого колличества их задач, но никак не бесконечного колличества.
это аргумент из разряда: пользователи не должны этого хотеть. и обычно он не работает.
R3>Взаимодействие: кубик Б взаимодействует с кубиком А, т.е. каждый из этих кубиков обладает полноценной системой, решающей определённое количество задач — кубик Б выполняет свои задачи и сообщает о результате кубику А, не зависимо от наличия кубика А (конечно, всё делается без потери данных).
возьми несколько любых задач, и представь что один из кубиков что-то не умеет
а потом попробуй разобрать как ты сможешь эту проблему решить без модификации данного кубика одним лишь взаимодействием.
хотя бы что-нибудь банальное: есть winforms, есть label, а текст надо написать под углом 30 градусов
R3>Может я сейчас скажу неудачный пример, но вот для подсчёта количества объектов в списке, нам нужно знать типы/классы этих объектов, или достаточно знать того, что этого список?
для хорошего решения нам необходимо знать тип списка
например, если список это массив, то достаточно спросить длину и это даст эффективность O(1)
DG>>есть готовый кубик, который описывает целый дом, при этом он считает, что в дом напрямую "вставлены" квартиры. DG>>например, такая модель достаточно для прописки, задания почтового адреса и т.д. DG>>но, например, для расчета давления воды или для стоимости доставки до квартиры тяжелых грузов — нужно еще понятие Этаж. DG>>и либо необходимо модифицировать уже готовый кубик Дом из предыдущего примера, либо разрабатывать с нуля новый.
R3>Мне кажется, что ты как раз и показал, в чём заключается проблема наследования.
а ты что предлагаешь? писать всё заново? а кто за это заплатит?
или ты надеешься что ты господь бог и всеведущий, и заранее все варианты предусмотришь?
Здравствуйте, DarkGray, Вы писали:
R3>>Этого достаточно для решения некоторого колличества задач. DG>двух штук?
Если этого достаточно, значит так оно и есть.
DG>посчитай, например, сколькими способами можно вывести строчку, хотя бы в html
Это задача из разрядка "экзотики". Конечно, если мы начнём удовлетворять пожелания каждого пользователя, то программу надо будет писать под каждого пользователя.
Я говорю о полезных задачах. О бизнес-задачах.
Например, для форматирования флешки я знаю только одну команду: "мой компьютер — диск: — формат". Всё. Никакие бесчётные множества способов форматирования флешки мне не нужны. Да их и не много, на самом деле. И почему-то никакая комбинаторика не использовалась.
И именно из этого я исхожу: постановка задачи — результат.
R3>>Современное программное обеспечение не решает бесконечное множество задач, тем не менее, их количества достаточно, для решения большинства задач и пользователи не сильно от этого страдают. В настоящее время они (пользователи) просят, например, от меня, решения опрделённого колличества их задач, но никак не бесконечного колличества. DG>это аргумент из разряда: пользователи не должны этого хотеть. и обычно он не работает.
Я ни слова не сказал про "не должны хотеть". Ключевое слово в моём абзаце — "конечное колличество".
DG>возьми несколько любых задач, и представь что один из кубиков что-то не умеет
Почти такая же фраза и была у меня в начале. Только звучала она по другому: сделаем кубик, который умеет только что-то одно ...
DG>а потом попробуй разобрать как ты сможешь эту проблему решить без модификации данного кубика одним лишь взаимодействием.
Взял, и тупо (в упор) решил.
Я не хвалюсь, ибо понимаю, что решение с одной стороны просто смешно; а с другой, возможно, не для всех задач это решение сработает. Но для части задач оно подходит просто уникально.
DG>хотя бы что-нибудь банальное: есть winforms, есть label, а текст надо написать под углом 30 градусов
Эта задача, как бы, не решается моей системой. В качестве аналога можно посмотреть https://mozillalabs.com/ubiquity/ У них "команда" запускает "что-то" на выполнение, но сама система ничего не делает.
R3>>Мне кажется, что ты как раз и показал, в чём заключается проблема наследования. DG>а ты что предлагаешь? писать всё заново? а кто за это заплатит?
Ни в коем случае. Надо будет обязательно использовать существующие наработки. При наличии кода — это не должно быть проблемой.
Например, существующий кубик "Блокнот" можно разложить на несколько мелких кубиков, в том числе "Вырезать", "Скопировать" или "Вставить".
DG>или ты надеешься что ты господь бог и всеведущий, и заранее все варианты предусмотришь?
Единственное, на что я надеюсь, это дописать проект. Если сделаю хотя бы часть из того, что я "нафантазировал" и это будет работать так, как мне хотелось бы, то как минимум я буду этим пользоваться. Это реально облегчит мне жизнь. Ну а если это облегчит жизнь кому-то ещё, то вообще здорово.
Здравствуйте, Real 3L0, Вы писали:
R3>Здравствуйте, jazzer, Вы писали:
J>>>>А то так можно договориться до того, что трудно найти сотрудников, дешевый офис и страну с низкими налогами. R3>>>А резве не так? J>>Так, конечно, но какое это отношение имеет к языку программирования? Мы же, вроде, о программировании тут говорим
R3>Так я и говорю, что сотрудников ищут не в гугле, а не специализированном сайте. Почему же ты считаешь, что для поиска нужного кубика будет достаточно гугля?
Я обобщенный гугль имел в виду, в качестве синонима "интернет с поиском". К языкам все это какое отношение имеет, ты скажешь наконец?
?
Если да, то я сказал, что если нужный кубик под рукой, то всё супер. Если же нет, то ни о какой лёгкости речи быть не может, какой бы язык при этом не использовался.
Здравствуйте, Real 3L0, Вы писали:
R3>Здравствуйте, jazzer, Вы писали:
J>>... К языкам все это какое отношение имеет, ты скажешь наконец?
R3>Я немножко потерялся — ты про это http://www.rsdn.ru/forum/philosophy/4300001.1.aspx
? R3>Если да, то я сказал, что если нужный кубик под рукой, то всё супер. Если же нет, то ни о какой лёгкости речи быть не может, какой бы язык при этом не использовался.
Ну тогда я не вижу противоречия своим словам, ты говоришь ровно то же, что я сказал там.
Могу привести в качестве примера современную электронику, где решение проблемы, в большинстве случаев, сводится к выбору нужных "кубиков".
Между тем,что я думаю,тем,что я хочу сказать,тем,что я,как мне кажется,говорю,и тем,что вы хотите услышать,тем,что как вам кажется,вы слышите,тем,что вы понимаете,стоит десять вариантов возникновения непонимания.Но всё-таки давайте попробуем...(Э.Уэллс)
Здравствуйте, AlexCab, Вы писали:
AC>Здравствуйте, Real 3L0 AC>Здравствуйте, DarkGray
AC>Могу привести в качестве примера современную электронику, где решение проблемы, в большинстве случаев, сводится к выбору нужных "кубиков".
Это потому что в электронике зачастую решаются типовые задачи. Как только появляются нестандартные задачи, в дело идут микроконтроллеры а, в тяжелых случаях — ПЛИСы и DSP, а это уже набивание текста и программизм в полный рост.
Здравствуйте, Real 3L0, Вы писали:
0>>Потому, что эти "кубики" не устраняли главной сложности в программировании, они решали не ту проблему. R3>А какую проблему они решали?
Главная проблема программирования это большое количество сущностей. Но об этом мало кто задумывается, ломая копья по поводу синтаксиса. Хотя замена синтаксиса на другой это обычно "те же яйца — вид сбоку" вместо упрощения.
Здравствуйте, Real 3L0, Вы писали:
0>>Потому, что эти "кубики" не устраняли главной сложности в программировании, они решали не ту проблему. R3>А какую проблему они решали?
На сегодняшних вполне привычных языках количество сущностей в коде можно уменьшить в разы. Но почему-то об этом ни книжек не пишут, ни дискуссий не ведут, тратя вместо этого кучу сил и ресурсов на поиски кубиков, макросов и прочего синтаксического сахара, который все должен упростить. Но ничего кардинально не упрощается, т.к. синтаксический сахар количество сущностей уменьшить не способен.
Здравствуйте, hardcase, Вы писали:
H>Это потому что в электронике зачастую решаются типовые задачи.
Так было не всегда, ещё не так давно электроника была "искусством создания схем", но со временем были определены топовые задачи и типовые решения для них. Думаю тоже сейчас происходит с программированием.
H>Как только появляются нестандартные задачи, в дело идут микроконтроллеры а, в тяжелых случаях — ПЛИСы и DSP, а это уже набивание текста и программизм в полный рост.
Truth.
Между тем,что я думаю,тем,что я хочу сказать,тем,что я,как мне кажется,говорю,и тем,что вы хотите услышать,тем,что как вам кажется,вы слышите,тем,что вы понимаете,стоит десять вариантов возникновения непонимания.Но всё-таки давайте попробуем...(Э.Уэллс)
Здравствуйте, Undying, Вы писали:
U>На сегодняшних вполне привычных языках количество сущностей в коде можно уменьшить в разы. Но почему-то об этом ни книжек не пишут, ни дискуссий не ведут, тратя вместо этого кучу сил и ресурсов на поиски кубиков, макросов и прочего синтаксического сахара, который все должен упростить. Но ничего кардинально не упрощается, т.к. синтаксический сахар количество сущностей уменьшить не способен.
Как по вашему это можно добиться значительного уменьшения "количества сучностей"(кроме ручной опитимизации)?
Между тем,что я думаю,тем,что я хочу сказать,тем,что я,как мне кажется,говорю,и тем,что вы хотите услышать,тем,что как вам кажется,вы слышите,тем,что вы понимаете,стоит десять вариантов возникновения непонимания.Но всё-таки давайте попробуем...(Э.Уэллс)
Здравствуйте, AlexCab, Вы писали:
U>>На сегодняшних вполне привычных языках количество сущностей в коде можно уменьшить в разы. Но почему-то об этом ни книжек не пишут, ни дискуссий не ведут, тратя вместо этого кучу сил и ресурсов на поиски кубиков, макросов и прочего синтаксического сахара, который все должен упростить. Но ничего кардинально не упрощается, т.к. синтаксический сахар количество сущностей уменьшить не способен. AC>Как по вашему это можно добиться значительного уменьшения "количества сущностей"(кроме ручной опитимизации)?
Не понял, каким образом ручной оптимизацией можно уменьшить количество сущностей?
Методов уменьшения количества сущностей достаточно много. Самый крутой из них это построение логики на геттерах, а не на сеттерах, т.е. замена явных присвоений значений по событию на вычисление значений на лету (напрямую или через автоматический кэш) при обращении к этому значению.
Здравствуйте, Undying, Вы писали:
U>Не понял, каким образом ручной оптимизацией можно уменьшить количество сущностей?
А, понял, я мел ввиду то лишнее что остаётся в "сырых" версиях кода.
Между тем,что я думаю,тем,что я хочу сказать,тем,что я,как мне кажется,говорю,и тем,что вы хотите услышать,тем,что как вам кажется,вы слышите,тем,что вы понимаете,стоит десять вариантов возникновения непонимания.Но всё-таки давайте попробуем...(Э.Уэллс)
R3>Ни в коем случае. Надо будет обязательно использовать существующие наработки. При наличии кода — это не должно быть проблемой. R3>Например, существующий кубик "Блокнот" можно разложить на несколько мелких кубиков, в том числе "Вырезать", "Скопировать" или "Вставить".
а в ворде это будут свои кубики "вырезать", "Скопировать" или "вставить"?
в браузере опять такие же, но свои?
в граф. редакторе тоже?
в файл менеджере?
и т.д?
вот и пошла комбинаторика: кол-во программ * (вырезать, скопировать, вставить)
Здравствуйте, Undying, Вы писали:
U>Главная проблема программирования это большое количество сущностей. Но об этом мало кто задумывается, ломая копья по поводу синтаксиса. Хотя замена синтаксиса на другой это обычно "те же яйца — вид сбоку" вместо упрощения.
А что следует из "большого колличества сущностей"? (Про синтаксис согласен.)
U> Но ничего кардинально не упрощается, т.к. синтаксический сахар количество сущностей уменьшить не способен.
foreach, using, linq, var и т.д. — это всё как раз уменьшение кол-ва сущностей, и это синтаксический сахар
зы
опять же надо понимать что такое уменьшение кол-ва сущностей.
самое минимальное кол-во сущностей — это последовательность 0 и 1. но это не то, что хочется, т.к. в этих сущностях мы не сможем ничего толкового запрограммировать и будем, как минимум, в мозгу выдумать какие-то вспомогательные сущности.
т.е. стоит считать все сущности и те, которые в коде есть, и те которые используются для написания, модифицирования, доказательства правильности и объяснения данного кода
Здравствуйте, Undying, Вы писали:
U>Методов уменьшения количества сущностей достаточно много. Самый крутой из них это построение логики на геттерах, а не на сеттерах, т.е. замена явных присвоений значений по событию на вычисление значений на лету (напрямую или через автоматический кэш) при обращении к этому значению.
Хм, уточни, плиз.
Как я думаю сделать: кубик 1 запрашивает данные А, система смотрит, кто может предоставить данные А — это кубик 2, выполняет кубик 2 — получаем данные А, отдаём данные А кубику 1. Т.е. для получения данных мне всё равно нужна сущность — кубик 2. Как в этом случае должна исчезнуть одна сущность?
Или это как с примером про чтение почты: кубик 1 запросил почту, кубик 2 предоставил почту, что в итоге даёт нам, что кубику 1 не надо знать о существовании сущности "MIME"?
Здравствуйте, DarkGray, Вы писали:
R3>>Например, существующий кубик "Блокнот" можно разложить на несколько мелких кубиков, в том числе "Вырезать", "Скопировать" или "Вставить". DG>а в ворде это будут свои кубики "вырезать", "Скопировать" или "вставить"?
Конечно, нет.
DG>вот и пошла комбинаторика: кол-во программ * (вырезать, скопировать, вставить)
Есть некоторые ограничения, типа различия между функциями "вырезать" у блокнота и у ворда, которые не позволяют тупо объединить все функции "вырезать" в одну. Но эти ограничения — не полная невозможность.
Здравствуйте, DarkGray, Вы писали:
R3>>Например, существующий кубик "Блокнот" можно разложить на несколько мелких кубиков, в том числе "Вырезать", "Скопировать" или "Вставить". DG>а в ворде это будут свои кубики "вырезать", "Скопировать" или "вставить"?
Именно к этой идее меня подтолкнул Джеф Раскин "Интерфейс" — я всё боялся её себе в слух сказать — слишком фантастично она меняла существующий мир: мир без приложений, но с функциями этих приложений.
R3>Именно к этой идее меня подтолкнул Джеф Раскин "Интерфейс" — я всё боялся её себе в слух сказать — слишком фантастично она меняла существующий мир: мир без приложений, но с функциями этих приложений.
именно эта идея и требует, чтобы можно было взять, например, команду "Вырезать" из блокнота, модифицировать ее и применить к ворду, и это тогда позволить что будет одна команда вырезать на все приложения, что позволяет избежать комбинаторного взрыва
Здравствуйте, DarkGray, Вы писали:
DG>именно эта идея и требует, чтобы можно было взять, например, команду "Вырезать" из блокнота, модифицировать ее и применить к ворду, и это тогда позволить что будет одна команда вырезать на все приложения, что позволяет избежать комбинаторного взрыва
Этого требования я у него не заметил.
Попровь меня дальше, если ошибаюсь.
Итак, что мы имеем: блокнот и ворд. Оба приложения — с функцией "вырезать".
Одним из отличий этих команд является то, что ворд понимает формат вырезанного текста. Блокнот — нет, т.к. блокнот работает с голым текстом. (Если вдруг это уже не так, то допустим, что это так. )
Если ворд модифицирует функцию "вырезать" и теперь она понимает формат текста, то блокнот никто модифицировать не будет. Следовательно, чтобы ворд мог отдать текст блокноту, он должен сделать обратное преобразование текста — удалить из текста форматирование. Вроде всё нормально.
Но тут появляется новый игрок: Writer, который понимает форматированный текст по своему и, следовательно, имеет свою функцию "вырезать". И если обмен текстом с блокнотом у него проблем не вызывает, то обмениваться текстом с вордом он не может по причине того, что ворд ни кому не говорит, в каком виде он ожидает принять форматированный текст.
Также, думаю, мы оба знаем, что произойдёт с текстом, при приобразовании "writer — блокнот — ворд".
Несыковка приложений. Такой мир мне не нужен.
Добавлю, что для пользователя ворда, все функции, работающие с неформатированным текстом, станут недоступны для форматированного (вордовского) текста.
Так что такой мир не нужен не только мне, но и этим пользователям. И, следовательно, Раскин не хотел такой функциональности.
R3> И если обмен текстом с блокнотом у него проблем не вызывает, то обмениваться текстом с вордом он не может по причине того, что ворд ни кому не говорит, в каком виде он ожидает принять форматированный текст.
R3>Добавлю, что для пользователя ворда, все функции, работающие с неформатированным текстом, станут недоступны для форматированного (вордовского) текста. R3>Так что такой мир не нужен не только мне, но и этим пользователям. И, следовательно, Раскин не хотел такой функциональности.
это один из пунктов из памятки "Как эффективно передергивать в дискуссии":
припишите утверждение оппоненту или его позиции — а потом доблестно это утверждение разгромите...
ps
и это кстати показывает, что ты не знаешь на каких принципах работает copy/paste в современной ОС.
Здравствуйте, DarkGray, Вы писали:
DG>это один из пунктов из памятки "Как эффективно передергивать в дискуссии": DG>припишите утверждение оппоненту или его позиции — а потом доблестно это утверждение разгромите...
Не понимаю, о каком "передёргивании" идёт речь. Я сюда не для этого пришёл.
Раскин хотел А. Ты пишешь, что для реализации А, надо Б. Я написал, что сделав Б, мы не сможем сделать А, но Раскин хотел А.
DG>и это кстати показывает, что ты не знаешь на каких принципах работает copy/paste в современной ОС.
Возможно, не спорю. Я приводил пример. Аналогичных примеров в современном ПО — тысячи.
Здравствуйте, DarkGray, Вы писали:
DG>foreach, using, linq, var и т.д. — это всё как раз уменьшение кол-ва сущностей, и это синтаксический сахар
Вообще всё в языках программирования — синтаксический сахар. В некотором смысле.
Вот, к примеру, рассмотрим концепцию "вызов функции" в традиционной архитектуре. Предположим, сахара у нас нет.
Это будет что-то типа
— положить параметры в стек, один за другим
— выполнить инструкцию call на адрес функции
— прочитать результат со стека
— очистить стек от параметров, которые мы использовали.
Можно заметить, что это довольно много работы для банального вызова. Давайте внесём в язык синтаксическое соглашение о том, что если мы пишем a = func(b, c), то это означает как раз
— положить в стек c
— положить в стек b
— сделать call на адрес func
— прочитать результат со стека (и положить его в a)
— очистить стек от c и b
Как видим, мы убрали количество сущностей, с которыми программисту нужно оперировать при каждом вызове, введя удобную абстракцию.
Или вот, более современный пример. Есть у нас, допустим, некоторый паттерн — детерминистическая финализация.
Устроенный как-то так:
— берём объект o, реализующий интерфейс IDisposable
— выполняем некоторый код
— в конце блока кода, независимо от того, вылетело исключение или нет, мы проверяем наш объект на != null и в случае успеха вызываем у него IDisposable.Dispose()
Как видим, нам нужно ковыряться в некотором количестве деталей, которые сами по себе не очень нужны. Поэтому можно внести в язык синтаксическую конструкцию using(), которая позволит всем этим не затрудняться, сокращая количество сущностей — и риск совершить ошибку.
И так — весь синтаксис.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Real 3L0, Вы писали:
Z>>Неудачный пример, исходники можно все же скомпилировать и получить программу. Модель скомпилировать нельзя, там явно недостаточно информации. Как только начинается попытка довести ее до достаточной на реальных задачах — все оказывается плачевно. Для каждого кубика приходится писать кучу кода, который читать и поддерживать гораздо сложнее чем те исходники.
R3>Это потому, что нет хорошего конструктора кубиков (КК). Ты описываешь проблемы, присутствующие в существующих КК. Но почему они должны быть в будущих (ещё не созданных) КК?
Процессы либо укладываются в пару-тройку кнопок, из которых составлять кубик бессмысленно, либо различаются в различных деталях, которые вынести в настройки кубика я могу, но вряд-ли кто-то еще сможет ими воспользоваться. Прекрасный пример кубиков это шелл. Именно потому, что конструирование происходит в тексте.
R3>Библиотека — это и есть кубик, но в мире программирования. Либо пишешь код руками (без КК; узнавая, что такое MIME), либо используешь библиотеку (с КК; не узнавая, что такое MIME). Так что нормальный пример.
Ну да. И такие кубики себя прекрасно зарекомендовали. А вот графические конструкторы все как один убоги.
Здравствуйте, DarkGray, Вы писали:
U>> Но ничего кардинально не упрощается, т.к. синтаксический сахар количество сущностей уменьшить не способен. DG>foreach, using, linq, var и т.д. — это всё как раз уменьшение кол-ва сущностей, и это синтаксический сахар
Все перечисленное не уменьшает количество сущностей, а лишь делает их неявными или немного другими. Foreach явное инкрементирование индекса и обращение по нему заменяет на неявный переход на следующий элемент, using явный вызов Dispose в finally заменяет на неявный и т.д.
Для сравнения. Если мы решаем задачу в сеттерном стиле, то при каждом изменении объекта нужно явно оповестить все объекты зависящие от него. Модифицироваться объект может из десятков и сотен мест. Если задача решается в геттерном стиле, то вместо этих вызовов в десятках и сотнях мест будет несколько автоматических кэшей. Соответственно при использовании геттерного стиля из программы исчезают (а не становятся неявными) десятки и сотни сущностей.
Другой пример. В шарпе сделали, что способ передачи переменной (по ссылке или по значению) задается при декларации типа. Тип мы задаем один раз, переменные этого типа может передавать сотни и тысячи раз. Соответственно благодаря этому из программы исчезают сотни и тысячи сущностей.
Вот поэтому геттерный стиль и определение способа передачи объекта на уровне типа это решения позволяющие кардинально снизить сложность программирования. А все тобой перечисленное это унылый синтаксический сахар, который либо снижает сложность программирования незначительно (foreach, using), либо и вовсе сложность не уменьшает (linq, var). Соответственно, если из шарпа выкинуть все тобой перечисленное, то моя прозводительность снизится на 1%, а число ошибок увеличится еще менее, а если я буду писать в сеттерном стиле вместо геттерного, то производительность упадет в разы, а число ошибок возрастет на порядок.
DG>самое минимальное кол-во сущностей — это последовательность 0 и 1. но это не то, что хочется, т.к. в этих сущностях мы не сможем ничего толкового запрограммировать и будем, как минимум, в мозгу выдумать какие-то вспомогательные сущности.
Ты путаешь количество сущностей в языке и количество сущностей в программе. Стремиться надо ко второму, а не к первому.
Здравствуйте, Real 3L0, Вы писали:
R3>Как я думаю сделать: кубик 1 запрашивает данные А, система смотрит, кто может предоставить данные А — это кубик 2, выполняет кубик 2 — получаем данные А, отдаём данные А кубику 1. Т.е. для получения данных мне всё равно нужна сущность — кубик 2. Как в этом случае должна исчезнуть одна сущность? R3>Или это как с примером про чтение почты: кубик 1 запросил почту, кубик 2 предоставил почту, что в итоге даёт нам, что кубику 1 не надо знать о существовании сущности "MIME"?
Речь не об этом. Есть задача при изменении состояния кубика 1 изменить состояние кубика 2. При решении в общепринятом (сеттерном) стиле, если состояние кубика 1 меняется в десяти местах, то в каждом из этих мест нужно написать код меняющий состояние кубика 2. Соответственно в программе появилось десять дополнительных сущностей (например, вызовов функции обновления состояния кубика 2). Если эту же задачу решить в геттерном стиле, т.е. реализовать кубик 2 в виде автоматического кэша зависящего от кубика 1, то при изменении состояния кубика 1 вызовов функции меняющей состояние кубика 2 писать будет не нужно. Соответственно в программе станет на 10 сущностей меньше.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, DarkGray, Вы писали:
DG>>foreach, using, linq, var и т.д. — это всё как раз уменьшение кол-ва сущностей, и это синтаксический сахар S>Вообще всё в языках программирования — синтаксический сахар. В некотором смысле.
согласен.
зы
бывает еще очень хороший синтаксический сахар, например, язык C по сравнению с asm-ом, такой сахар позволяет полностью(почти) не думать о сущностях с уровня ниже, и этим обеспечивается качественный переход, а называют это что-то типа "введение уровня абстракции" (не получилось слова лучше подобрать).
и бывает что "введение уровня абстракции" противопоставляют синтаксическому сахару, хотя по сути одно продолжение другого
Здравствуйте, Ziaw, Вы писали:
Z>Процессы либо укладываются в пару-тройку кнопок, из которых составлять кубик бессмысленно, либо различаются в различных деталях, которые вынести в настройки кубика я могу, но вряд-ли кто-то еще сможет ими воспользоваться. Прекрасный пример кубиков это шелл. Именно потому, что конструирование происходит в тексте.
А если решить проблему — чтобы кто-то ещё смог ими воспользоваться?
Z>Ну да. И такие кубики себя прекрасно зарекомендовали. А вот графические конструкторы все как один убоги.
Т.е. надо придумать хороший графический конструктор?
U>Ты путаешь количество сущностей в языке и количество сущностей в программе. Стремиться надо ко второму, а не к первому.
стремиться необходимо уменьшить и первое, и второе — мозг человека не бесконечен
а плохо подобранный набор сущностей очень быстро комбинаторно взрывается, и не влазит в человеческий мозг
Здравствуйте, Undying, Вы писали:
U>Речь не об этом. Есть задача при изменении состояния кубика 1 изменить состояние кубика 2. При решении в общепринятом (сеттерном) стиле, если состояние кубика 1 меняется в десяти местах, то в каждом из этих мест нужно написать код меняющий состояние кубика 2. Соответственно в программе появилось десять дополнительных сущностей (например, вызовов функции обновления состояния кубика 2). Если эту же задачу решить в геттерном стиле, т.е. реализовать кубик 2 в виде автоматического кэша зависящего от кубика 1, то при изменении состояния кубика 1 вызовов функции меняющей состояние кубика 2 писать будет не нужно. Соответственно в программе станет на 10 сущностей меньше.
Я погуглил, но не нашел, что такое "автоматический кеш"?
Это не наследование получается?
Здравствуйте, DarkGray, Вы писали:
DG>ты совсем упускаешь, что необходимо еще постоянно доказывать правильность работы программы, особенно после каждого изменения кода
Это ты к чему? Я писал, что есть решения которые позволяют увеличить производительность программиста в разы и сократить количество ошибок на порядок, обсудить эти решения мне было бы интересно, а есть решения выигрыш от которых надо разглядывать под микроскопом, соответственно обсуждать их толку мало. В ответ ты мне приводишь пример с гипотетическим микроскопическим выигрышем. Смысл это обсуждать?
Второе, вот ты привел в пример foreach и using. Какие способы упрощения кода применены в этих конструкциях? В случае foreach применен паттерн Фасад, в случае using вынесение дублирующегося кода в метод. И паттерн Фасад, и вынесение дублирующегося кода в метод это тривиальнейшие способы упрощения кода, о которых все давным давно знают. Какой смысл их обсуждать?
Здравствуйте, Undying, Вы писали:
U>Здравствуйте, DarkGray, Вы писали:
DG>>ты совсем упускаешь, что необходимо еще постоянно доказывать правильность работы программы, особенно после каждого изменения кода
U>Это ты к чему? Я писал, что есть решения которые позволяют увеличить производительность программиста в разы и сократить количество ошибок на порядок, обсудить эти решения мне было бы интересно, а есть решения выигрыш от которых надо разглядывать под микроскопом, соответственно обсуждать их толку мало. В ответ ты мне приводишь пример с гипотетическим микроскопическим выигрышем. Смысл это обсуждать?
U>Второе, вот ты привел в пример foreach и using. Какие способы упрощения кода применены в этих конструкциях? В случае foreach применен паттерн Фасад, в случае using вынесение дублирующегося кода в метод. И паттерн Фасад, и вынесение дублирующегося кода в метод это тривиальнейшие способы упрощения кода, о которых все давным давно знают. Какой смысл их обсуждать?
То что ты описываешь, используется настолько широко, что используя это, не выдумывают названия типа "геттерный подход" или "автоматическое кэширование". В качестве ключей активно используются cчетчики версий, временные пометки, пустые объекты, и другие объекты, которые могут описывать изменяющееся со временем состояние, как в том примере с размерами формы.
Моя мама, работавшая программистом с 68-го года, знает такой прихват. А с фасадом и экстракт-методом, наверное, не знакома.
Здравствуйте, Undying, Вы писали:
R3>>Я погуглил, но не нашел, что такое "автоматический кеш"? R3>>Это не наследование получается? U>Нет, не наследование. Простенький пример использования кэша можешь здесь посмотреть: http://rsdn.static.corbina.ru/forum/design/3612218.1.aspx
DG>>ты совсем упускаешь, что необходимо еще постоянно доказывать правильность работы программы, особенно после каждого изменения кода
U>Это ты к чему? Я писал, что есть решения которые позволяют увеличить производительность программиста в разы и сократить количество ошибок на порядок, обсудить эти решения мне было бы интересно, а есть решения выигрыш от которых надо разглядывать под микроскопом, соответственно обсуждать их толку мало. В ответ ты мне приводишь пример с гипотетическим микроскопическим выигрышем. Смысл это обсуждать?
могу продолжить твою логику: getter, но не setter — это частный случай всем известного immutable-программирования. смысл это обсуждать, и трубить об на каждом углу?
U>Второе, вот ты привел в пример foreach и using. Какие способы упрощения кода применены в этих конструкциях? В случае foreach применен паттерн Фасад, в случае using вынесение дублирующегося кода в метод. И паттерн Фасад, и вынесение дублирующегося кода в метод это тривиальнейшие способы упрощения кода, о которых все давным давно знают. Какой смысл их обсуждать?
обе эти конструкции дают гарантии
например, foreach дает гарантию (с точки зрения беглого чтения листинга), что перебор элементов не зациклится, ничего не пропустит, и не упадет сам по себе
foreach также дает уменьшение сущностей, тем что перебор элементов всегда выполняется одной конструкцией, а не десятью разными для массива, списка, последовательности и т.д.
например, вот такая конструкция вышеуказанных гарантий не дает:
for (int i = 0; i < items.length - 1; ++i)
{
Console.WriteLine(items[i]);
}
с using-ом тоже самое, он дает гарантию, что если есть using, то ресурсы будут очищены.
зы
или другими словами, for/while вместо foreach, и try/finally вместо using-а дает возможность написать их миллионом способов, при этом 99% вариантов будут ошибочными, и лишь 1% или меньше является правильным.
в итоге, код построенный на for/while/try/finally получается менее устойчивым к опечаткам и изменениям, что увеличивает стоимость тестирования и снижает стабильность конечной программы.
ззы
для проверки является ли код for (int i = 0; i < items.length — 1; ++i) правильным — приходится вводить доп. сущности, как минимум, в голове, что увеличивает общее кол-во сущностей.
Здравствуйте, DarkGray, Вы писали:
DG>могу продолжить твою логику: getter, но не setter — это частный случай всем известного immutable-программирования. смысл это обсуждать, и трубить об на каждом углу?
Во-первых, геттерный подход ортогонален immutable-программированию. Никаких проблем в использовании геттерного подхода совместно с мутабельными объектами нет, и даже более того именно в сочетании с мутабельными объектами геттерный подход позволяет снижать сложность кода максимально.
Во-вторых, геттерный подход снижает сложность кода на порядок, соответственно лучшее понимание его тонкостей может дать очень существенный выигрыш.
В-третьих, интереснее всего мне было бы обсудить не геттерный подход (его я и так знаю), а узнать о способах снижения сложности кода мне неизвестных. Паттерн Фасад и вынесение дублирующегося кода в метод мне известны, поэтому обсуждать их неинтересно.
U>>Второе, вот ты привел в пример foreach и using. Какие способы упрощения кода применены в этих конструкциях? В случае foreach применен паттерн Фасад, в случае using вынесение дублирующегося кода в метод. И паттерн Фасад, и вынесение дублирующегося кода в метод это тривиальнейшие способы упрощения кода, о которых все давным давно знают. Какой смысл их обсуждать?
DG>обе эти конструкции дают гарантии
И толку с этого? Какую долю в общем количестве ошибок составляют ошибки при работе с for и finally? У меня исчезающе малую. И смысл это обсуждать, если 99,9% ошибок имеют совершенно другую природу?
Здравствуйте, samius, Вы писали:
S>Моя мама, работавшая программистом с 68-го года, знает такой прихват. А с фасадом и экстракт-методом, наверное, не знакома.
Т.е. твоя мама программируя не использовала функций и не вызывала одну и ту же функцию в нескольких местах программы? Серьезно? Терминов фасад и экстракт-метода твоя мама, конечно, может и не знать, но суть их явно знает прекрасно, т.к. это азы программирования, без которых решение мало-мальски серьезных задач невозможно.
Здравствуйте, samius, Вы писали:
S>То что ты описываешь, используется настолько широко, что используя это, не выдумывают названия типа "геттерный подход" или "автоматическое кэширование". В качестве ключей активно используются cчетчики версий, временные пометки, пустые объекты, и другие объекты, которые могут описывать изменяющееся со временем состояние, как в том примере с размерами формы.
Кстати, если геттерный подход это общеизвестно, то с чего это, к примеру, все микрософтовские библиотеки написаны в кошмарном сеттерном стиле?
Здравствуйте, Undying, Вы писали:
U>Здравствуйте, samius, Вы писали:
S>>Моя мама, работавшая программистом с 68-го года, знает такой прихват. А с фасадом и экстракт-методом, наверное, не знакома.
U>Т.е. твоя мама программируя не использовала функций и не вызывала одну и ту же функцию в нескольких местах программы? Серьезно? Терминов фасад и экстракт-метода твоя мама, конечно, может и не знать, но суть их явно знает прекрасно, т.к. это азы программирования, без которых решение мало-мальски серьезных задач невозможно.
Ну как, и серьезно и не очень. Во времена молодости моей мамы такие вещи называли "подпрограммы". Т.е. фасад был из подпрограмм, и экстракт тоже подпрограмм.
Здравствуйте, DarkGray, Вы писали:
DG>могу продолжить твою логику: getter, но не setter — это частный случай всем известного immutable-программирования. смысл это обсуждать, и трубить об на каждом углу?
Вот когда хотя бы gridSynchronizer будет частью фрамеворка я поверю, что геттерный подход стал более-менее общеизвестным. А пока что во всех библиотеках кошмарная событийно-сеттерная логика, соответственно ничего общеизвестного в геттерном подходе нет, даже подавляющее большинство гиков не понимает что это такое.
Здравствуйте, samius, Вы писали:
S>Ну как, и серьезно и не очень. Во времена молодости моей мамы такие вещи называли "подпрограммы". Т.е. фасад был из подпрограмм, и экстракт тоже подпрограмм.
И к чему это буквоедство? Функция, подпрограмма, метод это синонимы, обозначающие одно и тоже, а именно некий код, который можно вызвать повторно.
Здравствуйте, Undying, Вы писали:
U>Здравствуйте, samius, Вы писали:
S>>То что ты описываешь, используется настолько широко, что используя это, не выдумывают названия типа "геттерный подход" или "автоматическое кэширование". В качестве ключей активно используются cчетчики версий, временные пометки, пустые объекты, и другие объекты, которые могут описывать изменяющееся со временем состояние, как в том примере с размерами формы.
U>Кстати, если геттерный подход это общеизвестно, то с чего это, к примеру, все микрософтовские библиотеки написаны в кошмарном сеттерном стиле?
Даже если посмотреть на вездесущий IEnumerable, то в его контракте заложено именно то, о чем ты выражаешься как "геттерный подход". Изменение коллекции увеличивает версию коллекции, которую кэширует перечислитель.
Здравствуйте, Undying, Вы писали:
U>Здравствуйте, samius, Вы писали:
S>>Ну как, и серьезно и не очень. Во времена молодости моей мамы такие вещи называли "подпрограммы". Т.е. фасад был из подпрограмм, и экстракт тоже подпрограмм.
U>И к чему это буквоедство? Функция, подпрограмма, метод это синонимы, обозначающие одно и тоже, а именно некий код, который можно вызвать повторно.
Совершенно ни к чему. Я же написал, что не очень серьезно.
U> Во-первых, геттерный подход ортогонален immutable-программированию.
если ты про кэши, то это частный случай lazy-программирования
U>Кстати, если геттерный подход это общеизвестно, то с чего это, к примеру, все микрософтовские библиотеки написаны в кошмарном сеттерном стиле?
проще обеспечить меньшее кол-во оверхеда и наведенных эффектов.
например, ты в курсе, что на lazy-инициализации легко словить зацикленность и stackoverflow?
Здравствуйте, DarkGray, Вы писали:
U>> Во-первых, геттерный подход ортогонален immutable-программированию. DG>если ты про кэши, то это частный случай lazy-программирования
Так immutable или lazy?
U>>Кстати, если геттерный подход это общеизвестно, то с чего это, к примеру, все микрософтовские библиотеки написаны в кошмарном сеттерном стиле? DG>проще обеспечить меньшее кол-во оверхеда и наведенных эффектов.
Смеешься? Событийный подход как способ борьбы с оверхедом и наведенными эффектами это пять. Событийный подход это один большой оверхед и наведенный эффект, т.к. удержать в голове цепочки вызовов событий невозможно даже на простых задачах.
DG>например, ты в курсе, что на lazy-инициализации легко словить зацикленность и stackoverflow?
Каким это образом? При использовании сеттерно-событийных библиотек стектрейсы в десятки вызовов вижу регулярно. При использовании геттерного подхода стектрейс в десяток вызовов еще поискать надо.
Здравствуйте, samius, Вы писали:
S>Даже если посмотреть на вездесущий IEnumerable, то в его контракте заложено именно то, о чем ты выражаешься как "геттерный подход". Изменение коллекции увеличивает версию коллекции, которую кэширует перечислитель.
Я очень рад, что микрософт научился использовать геттерный подход для самых примитивных сущностей. Интересно доживу ли я до того момента, когда микрософт научится использовать геттерный подход для чего-то мало-мальски сложного. Судя по динамике развития за последние десять лет, похоже нет, не доживу.
Здравствуйте, Undying, Вы писали:
U>Здравствуйте, samius, Вы писали:
S>>Даже если посмотреть на вездесущий IEnumerable, то в его контракте заложено именно то, о чем ты выражаешься как "геттерный подход". Изменение коллекции увеличивает версию коллекции, которую кэширует перечислитель.
U>Я очень рад, что микрософт научился использовать геттерный подход для самых примитивных сущностей. Интересно доживу ли я до того момента, когда микрософт научится использовать геттерный подход для чего-то мало-мальски сложного. Судя по динамике развития за последние десять лет, похоже нет, не доживу.
Давай попробуем вещь чуть более сложную чем тривиальную.
Есть три сущности A, B, C. У A есть свойство Bar. У B есть свойство Bar, значение которого зависит от значения A.Foo. У C есть свойство XYZ, которое зависит от B.Bar.
В программе меняется нечто, что влияет на A.Foo. Как ты предлагаешь организовать программу, что бы при обращении к C.XYZ мы получили соответствующее значение?
Если суть твоего предложения заключается в переходе от propagation changes к propagation 'changed' flag, то говорить о прорыве не приходится, как собственно и об уменьшении кода.
Здравствуйте, samius, Вы писали:
S>Есть три сущности A, B, C. У A есть свойство Bar. У B есть свойство Bar, значение которого зависит от значения A.Foo. У C есть свойство XYZ, которое зависит от B.Bar.
S>В программе меняется нечто, что влияет на A.Foo. Как ты предлагаешь организовать программу, что бы при обращении к C.XYZ мы получили соответствующее значение?
B.Bar реализуем как автоматический кэш зависящий от A.Foo. Свойство C.XYZ реализуем как автоматический кэш зависящий от B.Bar.
Все, о проблемах с обновлением C.XYZ можно забыть раз и навсегда.
Дополнение. Если от A.Foo зависит на самом деле не B.Bar целиком, а какое-то подсвойство B.Bar, то в виде автоматического кэша надо реализовывать не B.Bar, а это самое подсвойство.
S>Если суть твоего предложения заключается в переходе от propagation changes к propagation 'changed' flag, то говорить о прорыве не приходится, как собственно и об уменьшении кода.
Здравствуйте, Undying, Вы писали:
U>Здравствуйте, samius, Вы писали:
S>>Есть три сущности A, B, C. У A есть свойство Bar. У B есть свойство Bar, значение которого зависит от значения A.Foo. У C есть свойство XYZ, которое зависит от B.Bar.
S>>В программе меняется нечто, что влияет на A.Foo. Как ты предлагаешь организовать программу, что бы при обращении к C.XYZ мы получили соответствующее значение?
U>B.Bar реализуем как автоматический кэш зависящий от A.Foo. Свойство C.XYZ реализуем как автоматический кэш зависящий от B.Bar.
U>Все, о проблемах с обновлением C.XYZ можно забыть раз и навсегда.
U>Дополнение. Если от A.Foo зависит на самом деле не B.Bar целиком, а какое-то подсвойство B.Bar, то в виде автоматического кэша надо реализовывать не B.Bar, а это самое подсвойство.
Ага, вижу небольшую проблему, что C.XYZ не вернет значение пока вся цепочка как минимум не сравнит кэшированные значения с значением дальше по цепочке. Т.е. тривиальнейший запрос на значение C.XYZ выполнит обращение к B.Bar, а тот к A.Foo. Т.е. минимальная сложность обращения к чему-то — O(длина цепочки).
S>>Если суть твоего предложения заключается в переходе от propagation changes к propagation 'changed' flag, то говорить о прорыве не приходится, как собственно и об уменьшении кода.
U>Таким умных слов не знаю.
Пропихивание изменений и пропихивание флага об изменениях. Я думал что цепочка будет связываться флагами, как это принято в lazy reactive propgramming, а не кэшами.
Здравствуйте, samius, Вы писали:
S>Ага, вижу небольшую проблему, что C.XYZ не вернет значение пока вся цепочка как минимум не сравнит кэшированные значения с значением дальше по цепочке. Т.е. тривиальнейший запрос на значение C.XYZ выполнит обращение к B.Bar, а тот к A.Foo. Т.е. минимальная сложность обращения к чему-то — O(длина цепочки).
Да, такая проблема есть, при сотнях тысячах вызовов в секунду просаживание производительности становится критичным. Такие места приходится оптимизировать, благо их немного.
S>Пропихивание изменений и пропихивание флага об изменениях. Я думал что цепочка будет связываться флагами, как это принято в lazy reactive propgramming, а не кэшами.
Идею пропихивания флагов об изменении на пальцах можешь объяснить?
U>Каким это образом? При использовании сеттерно-событийных библиотек стектрейсы в десятки вызовов вижу регулярно. При использовании геттерного подхода стектрейс в десяток вызовов еще поискать надо.
class A
{
int Y:lazy(this.Z - 1)
int Z:lazy(this.Y + 1)
}
Здравствуйте, Undying, Вы писали:
U>Здравствуйте, samius, Вы писали:
S>>Пропихивание изменений и пропихивание флага об изменениях. Я думал что цепочка будет связываться флагами, как это принято в lazy reactive propgramming, а не кэшами.
U>Идею пропихивания флагов об изменении на пальцах можешь объяснить?
То же самое что распихивание значений подписчикам (EventHandler<MyEventArgsWithNewValue>), только вместо самого значения распихивается "знание что нечто изменилось" (EventHandler), по которому подписчик сбрасывает кэш.
Этот подход лучше тем, что позволяет пробегать только по цепочке реальных изменений один раз (по всей длине только в худшем случае), потом берет значения из локальных кэшей.
Но обладает тем же недостатком что и пропихивание изменений — нужна подписка на события.
Здравствуйте, DarkGray, Вы писали:
U>>Смеешься? Событийный подход как способ борьбы DG>ты как-то перескочил с setter-ов на события..
Событийный подход это естественное развитие сеттерного подхода. При сеттерном подходе в чистом виде при изменении состояния объекта нужно менять состояние всех объектов от него зависящих. Однако при решении мало-мальски сложных задач оказывается, что в месте модификации мы не знаем какие объекты зависят от изменяемого. Чтобы обойти эту проблему вводят события, позволяя зависимым объектам самим подписываться на изменения. При реализации геттерного подхода в чистом виде необходимости в событиях не возникает.
Здравствуйте, Undying, Вы писали:
U>Смеешься? Событийный подход как способ борьбы с оверхедом и наведенными эффектами это пять. Событийный подход это один большой оверхед и наведенный эффект, т.к. удержать в голове цепочки вызовов событий невозможно даже на простых задачах.
А ты вот это
видео смотрел?
Посмотри насколько "сеттрено-событийный подход" может рулить при правильном применении.
А вообще pull vs push не имеет однозначного выбора. Иногда хорошо одно иногда другое.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
U> Что-то примеры у тебя все надуманней и надуманней.
по текущим данным пик развития мозга приходится на 25 лет, дальше мозг начинает потихоньку деградировать, и программистам все сложнее с каждым прожитым годом делать выводы: как из очевидного примера получается вариант, который появляется в реальном коде, проскакивает тестирование и ломается у пользователя.
видео смотрел? WH>Посмотри насколько "сеттрено-событийный подход" может рулить при правильном применении. WH>А вообще pull vs push не имеет однозначного выбора. Иногда хорошо одно иногда другое.
Как на Rx записывается цепочка асинхронных шагов и ветвления в этой цепочке? Как на нем решать мало-мальски сложные задачи? Например, есть задача — перепрошить устройство. Необходимо выполнить нескольких сотен асинхронных шагов, из которых 6 разнородных, а один из этих шагов надо выполнять несколько сотен раз в цикле. Как решение такой задачи будет выглядеть на Rx?
Здравствуйте, DarkGray, Вы писали:
DG>по текущим данным пик развития мозга приходится на 25 лет, дальше мозг начинает потихоньку деградировать, и программистам все сложнее с каждым прожитым годом делать выводы: как из очевидного примера получается вариант, который появляется в реальном коде, проскакивает тестирование и ломается у пользователя.
Да, к сожалению это заметно. Ты, к примеру, все решения кардинально упрощающие программирование (геттерный подход, gridSynchronizer, taskPulling) предложил именно в 25 лет. А в дальнейшем от тебя что-то ничего толкового не слышно.
В принципе я видел один случай зацикливания на кэше (не в своем коде). Причина была в том, что был нарушен принцип — делегат кэша должен быть чистой функцией, не меняющей внешнего состояния. Соблазн нарушить этот принцип появился из-за того, что gridSynchronizer есть, а написать controlSynchronizer (синхронизирующий россыпь контролов на форме) все руки не доходили. После написания controlSynchronizer'а эта проблема исчезнет.
Здравствуйте, Undying, Вы писали:
U>Как на Rx записывается цепочка асинхронных шагов и ветвления в этой цепочке? Как на нем решать мало-мальски сложные задачи? Например, есть задача — перепрошить устройство. Необходимо выполнить нескольких сотен асинхронных шагов, из которых 6 разнородных, а один из этих шагов надо выполнять несколько сотен раз в цикле. Как решение такой задачи будет выглядеть на Rx?
Скажем, Rx уместен не в прошивалке, а на самом прошиваемом устройстве.
Здравствуйте, Undying, Вы писали:
U>Как на Rx записывается цепочка асинхронных шагов и ветвления в этой цепочке?
Не понял в чем проблема. Пример показать можешь?
U>Как на нем решать мало-мальски сложные задачи? Например, есть задача — перепрошить устройство. Необходимо выполнить нескольких сотен асинхронных шагов, из которых 6 разнородных, а один из этих шагов надо выполнять несколько сотен раз в цикле. Как решение такой задачи будет выглядеть на Rx?
В том видео показано как асинхронно работать с веб сервисом. Чем устройство отличается от вебсервиса не ясно.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
U>>Как на Rx записывается цепочка асинхронных шагов и ветвления в этой цепочке? WH>Не понял в чем проблема. Пример показать можешь?
Допустим, нужно перепрошить прибор с сервера. Нужно послать запрос 1, дождаться ответа, проверить ответ, если ответ правильный, то на основе данных полученных из ответа сформировать запрос 2. Затем аналогично послать запрос 2, дождаться ответа, проверить ответ, завершить выполнение, если ошибка, либо сформировать следующий запрос. И т.д. сотню-другую раз. Как это делается на Rx?
WH>В том видео показано как асинхронно работать с веб сервисом. Чем устройство отличается от вебсервиса не ясно.
Там в примере цепочка последовательных асинхронных шагов, зависящих от результата предыдущих шагов была?
Здравствуйте, Undying, Вы писали:
U>Здравствуйте, WolfHound, Вы писали:
U>>>Как на Rx записывается цепочка асинхронных шагов и ветвления в этой цепочке? WH>>Не понял в чем проблема. Пример показать можешь?
U>Допустим, нужно перепрошить прибор с сервера. Нужно послать запрос 1, дождаться ответа, проверить ответ, если ответ правильный, то на основе данных полученных из ответа сформировать запрос 2. Затем аналогично послать запрос 2, дождаться ответа, проверить ответ, завершить выполнение, если ошибка, либо сформировать следующий запрос. И т.д. сотню-другую раз. Как это делается на Rx?
from response1 in Request1()
where Predicate1(response1)
from response2 in Request2()
where Predicate2(response2)
select ...
Здравствуйте, Undying, Вы писали:
U>Допустим, нужно перепрошить прибор с сервера. Нужно послать запрос 1, дождаться ответа, проверить ответ, если ответ правильный, то на основе данных полученных из ответа сформировать запрос 2. Затем аналогично послать запрос 2, дождаться ответа, проверить ответ, завершить выполнение, если ошибка, либо сформировать следующий запрос. И т.д. сотню-другую раз. Как это делается на Rx?
На C# это делать не очень удобно.
Придется писать кучу лямбд и руками подписываться на события.
Но если насыпать сахар в виде ComputationExpressions то получится все очень просто и красиво.
def loop(arg)
{
comp Rx
{
defcomp res = Request1(arg);
if (res.IsError)
loop(arg);
else
Request2(res);
}
}
U>Там в примере цепочка последовательных асинхронных шагов, зависящих от результата предыдущих шагов была?
Такого примера в той презентации нет.
Но он тривиален.
Но там есть очень интересный пример.
От пользователя идет поток событий.
Сначала стоит фильтр который ждет чтобы мужду событиями прошло не меньше Н миллисекунд. Ибо, зачем спамить сервер пока пользователь печатает.
Потом стоит фильтр, который не пропускает два одинаковых события подряд.
Далее делаются запросы к веб серверу.
Причем если очередное событие пришло раньше, чем сервер ответил, то текущий запрос отменяется (он уже не актуален) и посылается новый.
После чего ответ проталкивается в UI.
В коде это описывается 1 в 1 со словесным алгоритмом.
Вообще тебе стоит посмотреть это видео.
Тебя заклинило на pull подходе. А он не всегда оптимален.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Можно тоже самое, но на шарпе и без синтаксического сахара? А то непонятно каким образом этот метод возвращает управлению потоку при ожидании результата выполнения.
Здравствуйте, WolfHound, Вы писали:
WH>Но там есть очень интересный пример. WH>От пользователя идет поток событий. WH>Сначала стоит фильтр который ждет чтобы мужду событиями прошло не меньше Н миллисекунд. Ибо, зачем спамить сервер пока пользователь печатает. WH>Потом стоит фильтр, который не пропускает два одинаковых события подряд. WH>Далее делаются запросы к веб серверу. WH>Причем если очередное событие пришло раньше, чем сервер ответил, то текущий запрос отменяется (он уже не актуален) и посылается новый. WH>После чего ответ проталкивается в UI.
Что в этой задаче сложного и интересного?
IEnumerable<Step> EventsAnalytic(TaskPull pull, Queue<Event> events, Form form)
{
SlyFilter filter = new SlyFilter(events);
while (true)
{
Event event = filter.Filter();
if (event != null)
{
Task task = pull.StartTask(ThreadLabel.Server, ServerSend(event));
yield return new WaitStep(delegate
{
return task.IsCompleted || events.Count != 0;
});
if (task.IsCompleted)
{
ServerResult result = task.Finish<ServerResult>();
// Изменяем UI
form.Text = result.Title;
}
}
else
{
yield return new WaitStep();
}
}
}
void Main()
{
// Запускаем анализатор событий в главном потоке
pull.StartTask(ThreadLabel.Main, EventAnalytic(pull, events, form);
}
Причем так можно было писать еще в 2005, возможности языка это прекрасно позволяли. И не нужно ни ждать по пять лет, ни присыпать код тоннами синтаксического сахара.
WH>Тебя заклинило на pull подходе. А он не всегда оптимален.
Pull подход практически всегда оптимален, т.к. позволяет получить предсказуемо работающий код за счет строго определенного порядка обработки. При push подходе определенный порядок обработки принципиально невозможен, т.к. события приходят произвольным образом, соответственно сложность push кода зашкаливает даже на простых задачах.
Здравствуйте, Undying, Вы писали:
U>Что в этой задаче сложного и интересного?
А ты посмотри видео и сравни полученное решение со своим.
Что происходит у тебя не ясно.
Где глотание быстроприходящих сообщений?
Как происходит пробуждение уснувшей задачи?
Где отмена тормозящего запроса, если пришло новое событие?
Сколько потоков этот код держит во время ожидания?
U>Причем так можно было писать еще в 2005, возможности языка это прекрасно позволяли. И не нужно ни ждать по пять лет, ни присыпать код тоннами синтаксического сахара.
yield это магатонны сахара.
А чтобы не ждать есть немерле.
U>Pull подход практически всегда оптимален, т.к. позволяет получить предсказуемо работающий код за счет строго определенного порядка обработки. При push подходе определенный порядок обработки принципиально невозможен, т.к. события приходят произвольным образом, соответственно сложность push кода зашкаливает даже на простых задачах. То что ты не умеешь его готовить не значит что его готовить невозможно.
Если мы работаем с потоком сообщений то мы очень легко можем контролировать порядок событий.
Смотри видео. Там показаны примеры.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
U>>Что в этой задаче сложного и интересного? WH>А ты посмотри видео и сравни полученное решение со своим.
Данное решение логически не содержит практически ничего лишнего, так что максимум что можно это записать его лаконичнее, но не принципиально проще.
WH>Что происходит у тебя не ясно. WH>Где глотание быстроприходящих сообщений?
filter.Filter();
WH>Как происходит пробуждение уснувшей задачи?
По таймеру. Можно дополнить форсированными пробуждениями, но в данной задаче это бессмысленно.
WH>Где отмена тормозящего запроса, если пришло новое событие?
Если нужна именно отмена старого запроса, а не игнорирование его результатов, то нужно добавить пару строчек кода:
if (!task.IsCompleted)
pull.StartTask(CancelServerQuery());
WH>Сколько потоков этот код держит во время ожидания?
Ни одного, естественно.
WH>yield это магатонны сахара.
Yield это всего лишь одна конструкция, логически очень простая и прозрачная. Оценить простоту и прозрачность того синтаксического сахара, который ты предлагаешь я не могу, т.к. с первого взгляда не понятно ничего, а разъяснить ты отказался.
WH>А чтобы не ждать есть немерле.
Вы уже ждали 5 лет, хотя уже в 2005 можно было написать решение, делающее асинхронный код столь же простым сколь и обычный синхронный.
WH> То что ты не умеешь его готовить не значит что его готовить невозможно.
Я не понимаю английский на слух, поэтому смотреть видео мне смысла никакого. Если есть ссылка на код, то приведи, посмотрю.
Здравствуйте, Undying, Вы писали:
U>Данное решение логически не содержит практически ничего лишнего, так что максимум что можно это записать его лаконичнее, но не принципиально проще.
Можно принципиально проще.
var txt = new TextBox();
var lst = new ListBox { Top = txt.Height + 10 };
var frm = new Form {
Controls = { txt, lst }
};
// Turn the user input into a tamed sequence of strings. var textChanged = from evt in Observable.FromEvent<EventArgs>(txt, "TextChanged")
select ((TextBox)evt.Sender).Text;
var input = textChanged
.Throttle(TimeSpan.FromSeconds(1))
.DistinctUntilChanged();
// Bridge with the web service's MatchInDict method. var svc = new DictServiceSoapClient("DictServiceSoap");
var matchInDict = Observable.FromAsyncPattern<string, string, string, DictionaryWord[]>
(svc.BeginMatchInDict, svc.EndMatchInDict);
Func<string, IObservable<DictionaryWord[]>> matchInWordNetByPrefix =
term => matchInDict("wn", term, "prefix");
// The grand composition connecting the user input with the web service. var res = from term in input
from word in matchInWordNetByPrefix(term).TakeUntil(input)
select word;
// Synchronize with the UI thread and populate the ListBox or signal an error. using (res.ObserveOn(lst).Subscribe(
words => {
lst.Items.Clear();
lst.Items.AddRange((from word in words select word.Word).ToArray());
},
ex => {
MessageBox.Show("An error occurred: " + ex.Message, frm.Text,
MessageBoxButtons.OK, MessageBoxIcon.Error);
}))
{
Application.Run(frm);
} // Proper disposal happens upon exiting the application.
U>filter.Filter();
И где там написано в течении какого времени дропать события?
U>По таймеру.
Жесть. И откуда таймер узнает о том с какой частотой нужно пробуждать задачу?
Да и зачем ее вообще пробуждать если пользователь ничего не делает?
Тебе что производительность девать некуда? А как на счет батарейки на мобиле?
U>Можно дополнить форсированными пробуждениями, но в данной задаче это бессмысленно.
А это уже пуш
U>Yield это всего лишь одна конструкция, логически очень простая и прозрачная.
Переписывание кода в конечный автомат это конечно очень просто.
U>Оценить простоту и прозрачность того синтаксического сахара, который ты предлагаешь я не могу, т.к. с первого взгляда не понятно ничего, а разъяснить ты отказался.
А в гугле тебя забанили?
U>Вы уже ждали 5 лет, хотя уже в 2005 можно было написать решение, делающее асинхронный код столь же простым сколь и обычный синхронный.
Ничего мы не ждали.
U>Я не понимаю английский на слух, поэтому смотреть видео мне смысла никакого. Если есть ссылка на код, то приведи, посмотрю. http://go.microsoft.com/fwlink/?LinkId=208528
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, Undying, Вы писали:
U>>Данное решение логически не содержит практически ничего лишнего, так что максимум что можно это записать его лаконичнее, но не принципиально проще. WH>Можно принципиально проще.
Псевдосинхронная запись имеет практически такую же сложность как обычный синхронный код. Вся разница лишь в том, что вместо синхронного ожидания окончания запроса используется yield, что позволяет не занимать поток на время ожидания. Соответственно практически все приемы программирования, которые можно использовать в синхронном коде можно использовать и в асинхронном, а, следовательно, при использовании псевдосинхронной записи порог вхождения для решения асинхронных задач практически такой же как для решения обычных синхронных задач. Асинхронность задачи перестает быть дополнительной сложностью.
Rx навязывает очень специфический стиль программирования, по другому используя Rx писать код нельзя. При этом для меня (равно как и для очень многих других людей) этот стиль является даже не столько сложным, сколько заумным, т.е. принципиально противоречащим моему способу мышления. Соответственно Rx имеет очень высокий порог вхождения, а, значит, никак не может считаться простым способом решения задач.
Кстати, никакой отмены устаревших запросов в решении на Rx нет. Вместо этого есть игнорирование результатов устаревшего запроса, что и делалось в приведенном мной примере.
Еще порадовал этот код:
var textChanged = from evt in Observable.FromEvent<EventArgs>(txt, "TextChanged")
select ((TextBox)evt.Sender).Text;
Рефлекшен, два явных приведения... Сразу видно технология двадцать первого века, с ностальгией вспомнился шарп 1.0.
U>>По таймеру. WH>Жесть. И откуда таймер узнает о том с какой частотой нужно пробуждать задачу? WH>Да и зачем ее вообще пробуждать если пользователь ничего не делает? WH>Тебе что производительность девать некуда? А как на счет батарейки на мобиле?
Ежели мы пишем софт для мобилы и лишние вызовы являются реальной проблемой, то нужно добавить немножко форсов:
IEnumerable<Step> EventsAnalytic(TaskPull pull, Form form)
{
// Получаем ссылку на таску и на поток, в котором она запущена
StateStep stateStep = new StateStep();
yield return stateStep;
SlyFilter filter = new SlyFilter(events, TimeSpan.FromSeconds(1));
Queue<Event> events = new Queue<Event>();
form.txt.TextChanged += delegate
{
events.Enqueue(new Event());
// Инициируем внеочередный вызов таски
stateStep.Force();
};
while (true)
{
Event event = filter.Filter();
if (event != null)
{
Task task = pull.StartTask(ThreadLabel.Server, ServerSend(stateStep, event));
// Указываем допустимое время ожидания и задаем, что поток должен инициировать вызов таски по истечению времени таймаутаyield return new WaitStep(timeout, timeout, delegate
{
return task.IsCompleted || events.Count != 0;
});
if (task.IsCompleted)
{
ServerResult result = task.Finish<ServerResult>();
// Изменяем UI
form.lst.Items.Clear();
form.lst.Items.AddRange(result.Items);
}
}
if (events.Count != 0)
yield return new WaitStep(TimeSpan.FromSeconds(1));
else
yield return new WaitStep(TimeSpan.FromHours(1));
}
}
void Main()
{
// Запускаем анализатор событий в главном потоке
pull.StartUITask(EventsAnalytic(pull, form);
}
Теперь никаких лишних вызовов шагов нет, решение можно смело использовать на мобильной платформе.
U>>Можно дополнить форсированными пробуждениями, но в данной задаче это бессмысленно. WH>А это уже пуш
С чего это? Как без форсов задача записывалась как IEnumerable шагов, так и с форсами также записывается. Что там так принципиально поменялось-то, что pull превратился в push? Там вся разница, что без форсов обработка следующего шага иницируется только по таймеру, а с форсами как по таймеру, так и по событиям. Разница между pull и push явно не в этом.
U>>Yield это всего лишь одна конструкция, логически очень простая и прозрачная. WH>Переписывание кода в конечный автомат это конечно очень просто.
Зачем для использования yield'а знать и уметь переписывать код в конечный автомат? Я вот понятия не имею как оно там в шарпе переписывается, что никак мне использовать yield не мешает. Единственное что нужно знать, что в месте вызова yield управление будет возвращено вызывающему методу.
U>>filter.Filter(); WH>И где там написано в течении какого времени дропать события?
Напоминаю мы обсуждаем решение асинхронных задач. Фильтрация коллекции событий это обычный синхронный код, соответственно в данном контексте он совершенно неинтересен, поэтому вместо него я написал заглушку. Если в Rx предложили хороший способ записи решения таких задач, вместо этой заглушки можно вставить код из Rx, а можно любой другой способ решения, в отличии от Rx псевдосихронный способ записи ничего не навязывает.
U>>Оценить простоту и прозрачность того синтаксического сахара, который ты предлагаешь я не могу, т.к. с первого взгляда не понятно ничего, а разъяснить ты отказался. WH>А в гугле тебя забанили?
ты привел мегасахар для записи асинхронных задач. В каком гугле надо искать что этот сахар означает?
U>>Вы уже ждали 5 лет, хотя уже в 2005 можно было написать решение, делающее асинхронный код столь же простым сколь и обычный синхронный. WH>Ничего мы не ждали.
И как ты решал асинхронные задачи до выхода Rx?
U>>Я не понимаю английский на слух, поэтому смотреть видео мне смысла никакого. Если есть ссылка на код, то приведи, посмотрю. WH>http://go.microsoft.com/fwlink/?LinkId=208528
Здравствуйте, Undying, Вы писали:
U>Rx навязывает очень специфический стиль программирования, по другому используя Rx писать код нельзя. При этом для меня (равно как и для очень многих других людей) этот стиль является даже не столько сложным, сколько заумным, т.е. принципиально противоречащим моему способу мышления. Соответственно Rx имеет очень высокий порог вхождения, а, значит, никак не может считаться простым способом решения задач.
Логика просто звездец.
Эдак можно договориться до того что ничего учить не надо.
U>Кстати, никакой отмены устаревших запросов в решении на Rx нет. Вместо этого есть игнорирование результатов устаревшего запроса, что и делалось в приведенном мной примере.
То, что ты ее не видишь, не значит, что ее нет.
Отписка от события запускает отмену.
U>Рефлекшен, два явных приведения... Сразу видно технология двадцать первого века, с ностальгией вспомнился шарп 1.0.
Там можно и без рефлекшена. Просто писать больше.
А если не использовать C# можно и без рефлекшена и писать меньше.
U>Ежели мы пишем софт для мобилы и лишние вызовы являются реальной проблемой, то нужно добавить немножко форсов:
Это ты называешь простым кодом?
Код на Rx читается почти как спецификация.
А тут у тебя куча деталей реализации вылезла.
U>Теперь никаких лишних вызовов шагов нет, решение можно смело использовать на мобильной платформе.
Вот только его никто не поймет.
А если логика станет чуть сложнее, то его совсем никто не поймет.
WH>>А это уже пуш U>С чего это?
По определению.
U>Как без форсов задача записывалась как IEnumerable шагов, так и с форсами также записывается. Что там так принципиально поменялось-то, что pull превратился в push? Там вся разница, что без форсов обработка следующего шага иницируется только по таймеру, а с форсами как по таймеру, так и по событиям. Разница между pull и push явно не в этом.
Именно в этом.
push это инициация обработки по событию.
U>Зачем для использования yield'а знать и уметь переписывать код в конечный автомат? Я вот понятия не имею как оно там в шарпе переписывается, что никак мне использовать yield не мешает. Единственное что нужно знать, что в месте вызова yield управление будет возвращено вызывающему методу.
Ну и в моём случае не нужно знать, во что это перепишется.
U>Напоминаю мы обсуждаем решение асинхронных задач. Фильтрация коллекции событий это обычный синхронный код, соответственно в данном контексте он совершенно неинтересен, поэтому вместо него я написал заглушку.
Очень даже интересен.
Ибо фильтрация событий по времени их прихода.
U>Если в Rx предложили хороший способ записи решения таких задач, вместо этой заглушки можно вставить код из Rx, а можно любой другой способ решения,
Те превратишь решение в push...
U>в отличии от Rx псевдосихронный способ записи ничего не навязывает.
Кроме горы никому не нужного мусора...
U>В этом посте http://rsdn.ru/forum/philosophy/4304148.1.aspx
Здравствуйте, Undying, Вы писали:
U>Псевдосинхронная запись имеет практически такую же сложность как обычный синхронный код. Вся разница лишь в том, что вместо синхронного ожидания окончания запроса используется yield, что позволяет не занимать поток на время ожидания. Соответственно практически все приемы программирования, которые можно использовать в синхронном коде можно использовать и в асинхронном, а, следовательно, при использовании псевдосинхронной записи порог вхождения для решения асинхронных задач практически такой же как для решения обычных синхронных задач. Асинхронность задачи перестает быть дополнительной сложностью.
Верно я понимаю что речь об асинхронной модели, описанной Рихтером или не Рихтером? Если да, то не совсем корректно ее сравнивать с Rx, ведь Rx это библиотека комбинирования push-based коллекций. А та модель — собственно async workflow. Если ее сравнивать с чем-то подобным, то можно с этим. Async workflow много где описан, просто в этой статье есть примеры на C#.
Да, с перечислителями будет поэлегантнее, хоть они и не для этого делались. Да и возможностей с ними побольше. Ветвление, циклы, try/catch (на F# возможно с async workflow, на C# — нет).
U>Rx навязывает очень специфический стиль программирования, по другому используя Rx писать код нельзя. При этом для меня (равно как и для очень многих других людей) этот стиль является даже не столько сложным, сколько заумным, т.е. принципиально противоречащим моему способу мышления. Соответственно Rx имеет очень высокий порог вхождения, а, значит, никак не может считаться простым способом решения задач.
Rx не для workflow. Он позволяет лишь "когда придет ответ оттуда, засунь его туда". Но последовательно связывать асинхронные вычисления — нет. Или я слабо его себе представляю. Обсуждаемый пример Rx — делает одну подписку и красиво ей управляет. Как засунуть это в более сложный workflow — я слабо представляю.
Т.е. async workflow и async enumerator позволят ответ с сервера послать асинхронно другому серверу "в теле" того же метода (в ковычках потому как управление таки будет возвращаться между делом). А с Rx придется делать две разные подписки. (если это не так, надеюсь что поправят).
U>Кстати, никакой отмены устаревших запросов в решении на Rx нет. Вместо этого есть игнорирование результатов устаревшего запроса, что и делалось в приведенном мной примере.
Именно.
U>Еще порадовал этот код: U>
U> var textChanged = from evt in Observable.FromEvent<EventArgs>(txt, "TextChanged")
U> select ((TextBox)evt.Sender).Text;
U>
U>Рефлекшен, два явных приведения... Сразу видно технология двадцать первого века, с ностальгией вспомнился шарп 1.0.
Рефлекшн — только подписка и отписка. Да и то, не уверен. Там может стоять Emit. Не копался.
двух приведений нет. В первом случае просто явный параметр для метода FromEvent, да и нужен он лишь для событий с типизированными аргументами. Второй — приведение sender-а к TextBox-у. А можно было записать
select txt.Text;
как в случае с
txt.TextChanged += (s, a) => { DoSomethingWith(txt.Text); }
ты привел мегасахар для записи асинхронных задач. В каком гугле надо искать что этот сахар означает?
ссылку давал выше как пример async workflow http://weblogs.asp.net/podwysocki/archive/2008/10/15/functional-c-implementing-async-computations-in-c.aspx
Мое имхо: async workflow удобно юзать в языках с поддержкой workflow. А так как C# его не поддерживает в достаточной мере(те select и let от LINQ-а выглядят довольно криво в случае с async, не позволяют ветвления, катчи и т.п.), то уж лучше юзать в C# асинхронные перечислители. Но все-таки призываю разделять случаи с workflow и случаи с управлением асинхронной подписки (Rx).
Здравствуйте, samius, Вы писали:
S>Здравствуйте, Undying, Вы писали:
S>Да, с перечислителями будет поэлегантнее, хоть они и не для этого делались. Да и возможностей с ними побольше. Ветвление, циклы, try/catch (на F# возможно с async workflow, на C# — нет).
Это всего лишь комбинаторы. Все есть в Rx.
S>Rx не для workflow. Он позволяет лишь "когда придет ответ оттуда, засунь его туда". Но последовательно связывать асинхронные вычисления — нет. Или я слабо его себе представляю. Обсуждаемый пример Rx — делает одну подписку и красиво ей управляет. Как засунуть это в более сложный workflow — я слабо представляю. S>Т.е. async workflow и async enumerator позволят ответ с сервера послать асинхронно другому серверу "в теле" того же метода (в ковычках потому как управление таки будет возвращаться между делом). А с Rx придется делать две разные подписки. (если это не так, надеюсь что поправят).
Не так. Последовательность вызовов делается оператором SelectMany, или через yield return + Observable.Interte в императивном стиле.
U>>Еще порадовал этот код: U>>
U>> var textChanged = from evt in Observable.FromEvent<EventArgs>(txt, "TextChanged")
U>> select ((TextBox)evt.Sender).Text;
U>>
U>>Рефлекшен, два явных приведения... Сразу видно технология двадцать первого века, с ностальгией вспомнился шарп 1.0. S>Рефлекшн — только подписка и отписка. Да и то, не уверен. Там может стоять Emit. Не копался.
там reflection, но есть типизированная версия + геренратор extension-методов.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
S>>Здравствуйте, Undying, Вы писали:
S>>Да, с перечислителями будет поэлегантнее, хоть они и не для этого делались. Да и возможностей с ними побольше. Ветвление, циклы, try/catch (на F# возможно с async workflow, на C# — нет). G>Это всего лишь комбинаторы. Все есть в Rx.
Да, нашел в Rx весь арсенал для workflow builder-а
S>>Rx не для workflow. Он позволяет лишь "когда придет ответ оттуда, засунь его туда". Но последовательно связывать асинхронные вычисления — нет. Или я слабо его себе представляю. Обсуждаемый пример Rx — делает одну подписку и красиво ей управляет. Как засунуть это в более сложный workflow — я слабо представляю.
Вижу, ошибался. S>>Т.е. async workflow и async enumerator позволят ответ с сервера послать асинхронно другому серверу "в теле" того же метода (в ковычках потому как управление таки будет возвращаться между делом). А с Rx придется делать две разные подписки. (если это не так, надеюсь что поправят). G>Не так. Последовательность вызовов делается оператором SelectMany, или через yield return + Observable.Interte в императивном стиле.
Observable.Iterate?
Здравствуйте, samius, Вы писали:
S>>>Т.е. async workflow и async enumerator позволят ответ с сервера послать асинхронно другому серверу "в теле" того же метода (в ковычках потому как управление таки будет возвращаться между делом). А с Rx придется делать две разные подписки. (если это не так, надеюсь что поправят). G>>Не так. Последовательность вызовов делается оператором SelectMany, или через yield return + Observable.Interte в императивном стиле. S>Observable.Iterate?
Угу. Тут пример — http://blogs.msdn.com/b/jeffva/archive/2010/07/23/rx-on-the-server-part-1-of-n-asynchronous-system-io-stream-reading.aspx
Здравствуйте, WolfHound, Вы писали:
WH>Эдак можно договориться до того что ничего учить не надо.
Разумеется. Использовать более сложное решение имеет смысл только в том случае, если оно кардинально расширяет наши возможности по решению наших задач по сравнению с более простым и прозрачным решением. Впрочем правильно приготовленные простые решения очень часто обладают и куда большей мощностью, чем решения сложные, т.к. в простых решениях нужные сущности не прикрыты слоями абстракций.
WH>То, что ты ее не видишь, не значит, что ее нет. WH>Отписка от события запускает отмену.
Код с неявными побочными эффектами? Тот кто будет это поддерживать будет вам очень благодарен.
WH>Код на Rx читается почти как спецификация. WH>А тут у тебя куча деталей реализации вылезла.
Что конкретно вылезло? Единственный некрасивый момент в решении это способ передачи ссылок на таску и поток выполнения внутрь описания шагов из-за стандартной проблемы яйца и курицы.
WH>А если логика станет чуть сложнее, то его совсем никто не поймет.
Ты не способен понимать синхронный код? Асинхронное решение с использованием псевдосинхронном записи практически ничем от синхронного не отличается. Соответственно псевдосинхронную запись без каких-либо проблем понимают даже студенты.
WH>push это инициация обработки по событию.
Тогда и обычный IEnumerable это пуш. Т.к. все функции программы в конечном итоге вызываются по событию.
WH>Очень даже интересен. WH>Ибо фильтрация событий по времени их прихода.
И что там интересного? Если прошла секунда со времени прихода последнего события, то фильтр возвращает это событие и очищает очередь событий. Если нет, то возвращает null. Хотя собственно даже очередь здесь не нужна, можно хранить только последнее событие.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
S>>>>Т.е. async workflow и async enumerator позволят ответ с сервера послать асинхронно другому серверу "в теле" того же метода (в ковычках потому как управление таки будет возвращаться между делом). А с Rx придется делать две разные подписки. (если это не так, надеюсь что поправят). G>>>Не так. Последовательность вызовов делается оператором SelectMany, или через yield return + Observable.Interte в императивном стиле. S>>Observable.Iterate? G>Угу. Тут пример — http://blogs.msdn.com/b/jeffva/archive/2010/07/23/rx-on-the-server-part-1-of-n-asynchronous-system-io-stream-reading.aspx
Все понятно стало. Т.е. фактически для сцепления с императивом заюзан тот же трюк с асинхронным перечислителем.
Благодарю, был неправ в своих догадках.
Здравствуйте, Undying, Вы писали:
U>Разумеется. Использовать более сложное решение имеет смысл только в том случае, если оно кардинально расширяет наши возможности по решению наших задач по сравнению с более простым и прозрачным решением. Впрочем правильно приготовленные простые решения очень часто обладают и куда большей мощностью, чем решения сложные, т.к. в простых решениях нужные сущности не прикрыты слоями абстракций.
Твое решение сложнее.
Намного сложнее.
Ты просто посмотри на ту гору грязи, не имеющую отношения к делу, которую ты написал.
U>Код с неявными побочными эффектами? Тот кто будет это поддерживать будет вам очень благодарен.
Это стандартное поведение.
Так что запомнить это нужно раз и навсегда.
U>Что конкретно вылезло? Единственный некрасивый момент в решении это способ передачи ссылок на таску и поток выполнения внутрь описания шагов из-за стандартной проблемы яйца и курицы.
Да у тебя там чуть менее чем весь код детали реализации.
U>Ты не способен понимать синхронный код? Асинхронное решение с использованием псевдосинхронном записи практически ничем от синхронного не отличается. Соответственно псевдосинхронную запись без каких-либо проблем понимают даже студенты.
Там столько деревьев, что за ними не видно леса.
U>Тогда и обычный IEnumerable это пуш. Т.к. все функции программы в конечном итоге вызываются по событию.
Ты не понимаешь чем push отличается от pull.
В случае с IEnumerable ты вытягиваешь данные. Это pull.
А в случае с пробуждением кода внешний код проталкивает данные тебе. Это push.
U>И что там интересного? Если прошла секунда со времени прихода последнего события, то фильтр возвращает это событие и очищает очередь событий. Если нет, то возвращает null. Хотя собственно даже очередь здесь не нужна, можно хранить только последнее событие.
Интересно записать это одной строчкой:
var input = textChanged
.Throttle(TimeSpan.FromSeconds(1))
.DistinctUntilChanged();
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
WH>В случае с IEnumerable ты вытягиваешь данные. Это pull. WH>А в случае с пробуждением кода внешний код проталкивает данные тебе. Это push.
В случае псевдосинхронной записи данные всегда вытягивает TaskPull. Force никаких данных к себе не проталкивает, оно лишь говорит TaskPull'у, что ему надо вытянуть к себе данные прямо сейчас.
U>>И что там интересного? Если прошла секунда со времени прихода последнего события, то фильтр возвращает это событие и очищает очередь событий. Если нет, то возвращает null. Хотя собственно даже очередь здесь не нужна, можно хранить только последнее событие. WH>Интересно записать это одной строчкой: WH>
WH> var input = textChanged
WH> .Throttle(TimeSpan.FromSeconds(1))
WH> .DistinctUntilChanged();
WH>
Зачем это записывать одной строчкой? У тебя число буковок в коде самоцель?
WH>Ты просто посмотри на ту гору грязи, не имеющую отношения к делу, которую ты написал.
Это у тебя претензии не к способу решения асинхронных задач, а к императивному стилю вообще. Ты считаешь, что функциональный стиль лучше императивного, я считаю наоборот. Спорить на эту тему бессмысленно, т.к. по видимому у нас действительно совершенно разные типы мышления.
Здравствуйте, Undying, Вы писали:
U>В случае псевдосинхронной записи данные всегда вытягивает TaskPull. Force никаких данных к себе не проталкивает, оно лишь говорит TaskPull'у, что ему надо вытянуть к себе данные прямо сейчас.
Само сообщение уже информация.
Ты как ни крутись, а это pull.
Просто по определению.
U>Зачем это записывать одной строчкой? У тебя число буковок в коде самоцель?
У меня цель чтобы в коде небыло ни одной буквы которая не относится к решению задачи.
Rx очень близок к идеалу.
Хотя можно и лучше.
Но не на C#.
U>Это у тебя претензии не к способу решения асинхронных задач, а к императивному стилю вообще. Ты считаешь, что функциональный стиль лучше императивного, я считаю наоборот. Спорить на эту тему бессмысленно, т.к. по видимому у нас действительно совершенно разные типы мышления.
У меня претензии к коду, который занимается деталями реализации.
Его быть не должно.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
WH>Это стандартное поведение. WH>Так что запомнить это нужно раз и навсегда.
Т.е. для чтения кода, использующего подобные библиотеки, нужно держать в памяти кучу мусорных знаний. Я как-то предпочитаю писать библиотеки, которые этого не требуют.
Здравствуйте, WolfHound, Вы писали:
U>>Зачем это записывать одной строчкой? У тебя число буковок в коде самоцель? WH>У меня цель чтобы в коде небыло ни одной буквы которая не относится к решению задачи.
От отсутствия буковок (как и от увеличения количества слоев абстракции вообще) сущности никуда не деваются, а лишь становятся неявными. А код напичканный неявными сущностями, во-первых, сложно читать, во-вторых, если нужно сделать что-то нестандартное и требуется доступ к этим неявным сущностям, то появляются танцы с бубном и простыни кода на ровном месте.
Например, если в зависимости от свойств события интервал Throttle нужно будет делать разный, то как измениться код на Rx? А если интервал будет зависеть от предшествующих событий?
Здравствуйте, lseder, Вы писали:
L>Привет, может кто-нибудь находил в инете инфу по метапрограммированию. L>Интересуют принципы выделения и организации низкоуровневой структуры, и L>методы конструирования мета-конструкций на основе предыдущего (нижнего) слоя понятий.
По моему наиболее близко на сегодняшний день, к сабжу.
Есть еще книги, "Порождающее программирование". "Фабрики разработки программ". И много много всего по паттернам, UML.
L>- Реализовать хотелось бы на javascript + sql (web kit html5), так как интересно сделать L>конструктор на чистом браузере (для тачскринов).
Здравствуйте, Undying, Вы писали:
U>Здравствуйте, WolfHound, Вы писали:
U>>>Зачем это записывать одной строчкой? У тебя число буковок в коде самоцель? WH>>У меня цель чтобы в коде небыло ни одной буквы которая не относится к решению задачи.
U>От отсутствия буковок (как и от увеличения количества слоев абстракции вообще) сущности никуда не деваются, а лишь становятся неявными. А код напичканный неявными сущностями, во-первых, сложно читать, во-вторых, если нужно сделать что-то нестандартное и требуется доступ к этим неявным сущностям, то появляются танцы с бубном и простыни кода на ровном месте.
Есть магическое слово "монада", дает ответы сразу на все вопросы, которые ты задаешь.
U>Например, если в зависимости от свойств события интервал Throttle нужно будет делать разный, то как измениться код на Rx? А если интервал будет зависеть от предшествующих событий?
Ты для начала напиши с помощью другой технологии пример что WolfHound привел. А потом найди пример, который в Rx плохо делается, а с другой технологией хорошо.
Здравствуйте, gandjustas, Вы писали:
U>>Например, если в зависимости от свойств события интервал Throttle нужно будет делать разный, то как измениться код на Rx? А если интервал будет зависеть от предшествующих событий? G>Ты для начала напиши с помощью другой технологии пример что WolfHound привел.
G>А потом найди пример, который в Rx плохо делается, а с другой технологией хорошо.
Ты на что отвечаешь вообще читаешь или умеешь только вопросом на вопрос отвечать? Я как раз и спрашиваю хорошо или плохо будет решаться на задача с нестандартным условием. Сам я ответить на этот вопрос не могу, т.к. Rx не знаю. В императивном стиле и при использовании псевдосинхронной записи код решения задачи с нестандартным условием останется тривиальным.
Здравствуйте, Undying, Вы писали:
U>Т.е. для чтения кода, использующего подобные библиотеки, нужно держать в памяти кучу мусорных знаний. Я как-то предпочитаю писать библиотеки, которые этого не требуют.
Где ты взял кучу я не понял.
Всего одно правило: Отписка от события сообщает источнику события что результат больше не нужен.
За то в твоем коде я вижу кучу мусора, который не нужен.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, Undying, Вы писали:
U>От отсутствия буковок (как и от увеличения количества слоев абстракции вообще) сущности никуда не деваются, а лишь становятся неявными. А код напичканный неявными сущностями, во-первых, сложно читать, во-вторых, если нужно сделать что-то нестандартное и требуется доступ к этим неявным сущностям, то появляются танцы с бубном и простыни кода на ровном месте.
Ну давай разбираться какие у нас в этом коде есть сущности.
Начнем с того что у нас есть сущность: поток событий.
Rx делает ее явной.
var textChanged = from evt in Observable.FromEvent<EventArgs>(txt, "TextChanged")
select ((TextBox)evt.Sender).Text;
Это не слой абстракции. Это прикладная сущность.
Именно в этих терминах задача и сформулирована.
Можешь попробовать сформулировать ее по-другому.
Далее мы этот поток фильтруем:
Тут у нас два действия.
1)Глотать события пока интервал между ними не превысит секунду.
2)Глотать идущие подряд одинаковые события.
var input = textChanged
.Throttle(TimeSpan.FromSeconds(1))
.DistinctUntilChanged();
Код в точности повторяет описание того что делается.
И так далее...
U>Например, если в зависимости от свойств события интервал Throttle нужно будет делать разный, то как измениться код на Rx? А если интервал будет зависеть от предшествующих событий?
Вот тебе домашнее задание:
Реализовать то, что ты хочешь, используя эти комбинаторы.
/// <summary>
/// Records the timestamp for each value in an observable sequence.
/// </summary>
/// <param name="source">Source sequence to timestamp values for.</param>
/// <returns>An observable sequence with timestamp information on values.</returns>public static IObservable<Timestamped<TSource>> Timestamp<TSource>(this IObservable<TSource> source)
/// <summary>
/// Applies an accumulator function over an observable sequence and returns each intermediate result. The specified seed value is used as the initial accumulator value.
/// </summary>
/// <param name="source">An observable sequence to accumulate over.</param>
/// <param name="seed">The initial accumulator value.</param>
/// <param name="accumulator">An accumulator function to be invoked on each element.</param>
/// <returns>An observable sequence containing the accumulated values.</returns>public static IObservable<TAccumulate> Scan<TSource, TAccumulate>(this IObservable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> accumulator)
/// <summary>
/// Filters the elements of an observable sequence based on a predicate.
/// </summary>
/// <param name="source">An observable sequence whose elements to filter.</param>
/// <param name="predicate">A function to test each source element for a condition.</param>
/// <returns>An observable sequence that contains elements from the input sequence that satisfy the condition.</returns>public static IObservable<TSource> Where<TSource>(this IObservable<TSource> source, Func<TSource, bool> predicate)
/// <summary>
/// Projects each element of an observable sequence into a new form.
/// </summary>
/// <param name="source">A sequence of elements to invoke a transform function on.</param>
/// <param name="selector">A transform function to apply to each source element.</param>
/// <returns>An observable sequence whose elements are the result of invoking the transform function on each element of source.</returns>public static IObservable<TResult> Select<TSource, TResult>(this IObservable<TSource> source, Func<TSource, TResult> selector)
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
U>От отсутствия буковок (как и от увеличения количества слоев абстракции вообще) сущности никуда не деваются, а лишь становятся неявными. А код напичканный неявными сущностями, во-первых, сложно читать, во-вторых, если нужно сделать что-то нестандартное и требуется доступ к этим неявным сущностям, то появляются танцы с бубном и простыни кода на ровном месте.
это все верно, но это не всё. если бы это был единственный критерий, то мы бы до сих пор писали на ассемблере и радовались...
второй и более важный и критичный критерий — это каким кол-вом проявленных сущностей в единицу времени человек может управлять осознанно.
к сожалению, это очень маленькое число — и поэтому приходится разбивать код на функции, библиотеки, вводить промежуточные абстракции и т.д.
если учитывать эти оба фактора, то задача ставится по другому: какие сущности сделать явными, а какие скрыть и сделать неявными, причем чем больше сущностей удастся скрыть, тем сильнее повысятся возможности управляемости теми сущностями, которые остались не скрытыми и прописаны явно.
если брать mainstream, то в разряд неявных сущностей переведены такие вещи как: схема размещения переменных по регистрам, генерация последовательности ассемблерных команд, управление памятью, управление потоком ошибок и т.д.
да, все это уменьшило наши возможности по управлению этими вещами. например, если в той же Java или .Net-е необходимо какая-то особенная работа с памятью, то это требует нетривиальных усилий.
но эти ограничения помогают сосредоточиться на важном: на логике программы, не увязая в мелочах.
зы
если брать Rx, то его лаконизм позволяет сосредоточиться на логике управления потоками сообщений, при этом получая минимальные оверхеды по времени отклика.
ззы U> Например, если в зависимости от свойств события интервал Throttle нужно будет делать разный, то как измениться код на Rx? А если интервал будет зависеть от предшествующих событий?
в крайнем случае, по месту придется написать свою функцию MyThrottle, расковыряв Reflector-ом стандартную функцию Throttle
Здравствуйте, Undying, Вы писали:
U>Здравствуйте, gandjustas, Вы писали:
U>>>Например, если в зависимости от свойств события интервал Throttle нужно будет делать разный, то как измениться код на Rx? А если интервал будет зависеть от предшествующих событий? G>>Ты для начала напиши с помощью другой технологии пример что WolfHound привел.
U>http://rsdn.ru/forum/philosophy/4313117.1.aspx
Трижды читал этот код, но не понял. Важный функционал скрыт в каком-то SlyFilter, зато наружу выставлены детали реализации workflow.
G>>А потом найди пример, который в Rx плохо делается, а с другой технологией хорошо.
U>Ты на что отвечаешь вообще читаешь или умеешь только вопросом на вопрос отвечать? Я как раз и спрашиваю хорошо или плохо будет решаться на задача с нестандартным условием. Сам я ответить на этот вопрос не могу, т.к. Rx не знаю. В императивном стиле и при использовании псевдосинхронной записи код решения задачи с нестандартным условием останется тривиальным.
Ну Rx поддерживает псевдосинхронную запись с помощью yield return, а в худшем случае все закончится написанием своего комбинатора, что обычно не очень сложно.
Здравствуйте, gandjustas, Вы писали:
G>Трижды читал этот код, но не понял.
Значит, у императивщиков и функциональщиков точно совершенно разные принципы мышления. Соответственно функциональщики не могут понять простейший императивный код, а императивщики наоборот. Поэтому дискуссия бессмысленна, у нас совершенно разные представления о простом и сложном.
G>Важный функционал скрыт в каком-то SlyFilter, зато наружу выставлены детали реализации workflow.
Точно также как в Rx важный функционал скрыт в функции Throttle.
Здравствуйте, Undying, Вы писали:
U>Здравствуйте, gandjustas, Вы писали:
G>>Трижды читал этот код, но не понял.
U>Значит, у императивщиков и функциональщиков точно совершенно разные принципы мышления. Соответственно функциональщики не могут понять простейший императивный код, а императивщики наоборот. Поэтому дискуссия бессмысленна, у нас совершенно разные представления о простом и сложном.
да мне как-бы пофиг, если императивно код записывается проще, то я предпочту такой стиль. Но ты показал десятки строк против трех. Причем твои десятки в разы менее понятны.
G>>Важный функционал скрыт в каком-то SlyFilter, зато наружу выставлены детали реализации workflow.
U>Точно также как в Rx важный функционал скрыт в функции Throttle.
Он предельно прост (ибо комбинатор) и для него есть документация. SlyFilter обоими достоинствам необладает.
L>Марти Фаулер. Архитектура корпоративных программных приложений.
спасибо, посмотрю. но моя задача по размерам пока не тянет на корпоративные размеры,
хотя общие принципы разработки знать необходимо.
L>По моему наиболее близко на сегодняшний день, к сабжу. L>Есть еще книги, "Порождающее программирование". "Фабрики разработки программ". И много много всего по паттернам, UML.
"Порождающее программирование" наиболее близко к теме, но книгу чарнецки в Украине купить невозможно.
L>>- Реализовать хотелось бы на javascript + sql (web kit html5), так как интересно сделать L>>конструктор на чистом браузере (для тачскринов). L>А зачем?
для iPad-а и других тачскринов.
Здравствуйте, DarkGray, Вы писали:
DG>если брать mainstream, то в разряд неявных сущностей переведены такие вещи как: схема размещения переменных по регистрам, генерация последовательности ассемблерных команд, управление памятью, управление потоком ошибок и т.д.
Обрати внимание все что ты перечислил это аппаратные, а не бизнес сущности. В бизнес логике есть, к примеру, сущность "сложение", при этом вопрос какие регистры будут задействованы и какая память использована это лишние сущности отсутствующие в логическом алгоритме. Поэтому скрывать аппаратные сущности можно и нужно. При условии, конечно, что это не приводит к критической просадке производительности на том классе задач, для решения которых предназначен язык/библиотека.
Логические сущности не являются лишними, поэтому скрывая их очень легко затруднить понимание кода и усложнить решение реальных задач. Поэтому лучшими библиотеками являются те, которые решают задачи используя минимум абстракций. Т.к. при необходимости написать обертку скрывающую неиспользуемые логические сущности под конкретную задачу проблемы не составляет, а простота доступа к логическим сущностям позволяет решать нестандартные задачи без лишних сложностей.
DG>в крайнем случае, по месту придется написать свою функцию MyThrottle, расковыряв Reflector-ом стандартную функцию Throttle
Т.е. при небольшом усложнении задачи происходит кардинальный скачок сложности решения. Это плохо, т.к. приводит к ситуациям, когда то что с точки зрения пользователя выглядит копеечной работой оказывается очень сложным в программной реализации.
DG>>если брать mainstream, то в разряд неявных сущностей переведены такие вещи как: схема размещения переменных по регистрам, генерация последовательности ассемблерных команд, управление памятью, управление потоком ошибок и т.д.
U>Обрати внимание все что ты перечислил это аппаратные, а не бизнес сущности.
во-первых, какие бизнес-сущности скрывает Rx?
во-вторых, какую аппаратную сущность скрывает, например, exception, или using, или автоматический деструктор?
также можно привести много других примеров скрытия той или иной логики: виртуальные функции, linq, wcf, wpf, com, sql и т.д.
U> В бизнес логике есть, к примеру, сущность "сложение", при этом вопрос какие регистры будут задействованы и какая память использована это лишние сущности отсутствующие в логическом алгоритме. Поэтому скрывать аппаратные сущности можно и нужно. При условии, конечно, что это не приводит к критической просадке производительности на том классе задач, для решения которых предназначен язык/библиотека.
и какую бизнес-сущность описывает, например, операция foreach или while?
U>Логические сущности не являются лишними, поэтому скрывая их очень легко затруднить понимание кода и усложнить решение реальных задач. Поэтому лучшими библиотеками являются те, которые решают задачи используя минимум абстракций. Т.к. при необходимости написать обертку скрывающую неиспользуемые логические сущности под конкретную задачу проблемы не составляет, а простота доступа к логическим сущностям позволяет решать нестандартные задачи без лишних сложностей.
перечисли, пожалуйста, хотя бы штук 30 таких логических сущностей, которые скрывать не стоит, чтобы понятно было о чем речь
DG>>в крайнем случае, по месту придется написать свою функцию MyThrottle, расковыряв Reflector-ом стандартную функцию Throttle
U>Т.е. при небольшом усложнении задачи происходит кардинальный скачок сложности решения. Это плохо, т.к. приводит к ситуациям, когда то что с точки зрения пользователя выглядит копеечной работой оказывается очень сложным в программной реализации.
и поэтому все копеечные задачи (при том что их большинство) надо решать за 100 рублей каждую?
Здравствуйте, DarkGray, Вы писали:
DG>также можно привести много других примеров скрытия той или иной логики: виртуальные функции, linq, wcf, wpf, com, sql и т.д.
Мы (кажется, с тобой) как-то дискутировали на тему, на сколько сильно можно скрыть все ненужные в данный момент сущности, при написании команды, приближенной к естественному языку. Использовался пример с принтером: надо напечатать документ. Ты говорил, что количество уточняющих деталей (например, какой именно принтер или как именно надо напечатать) не позволит легко пользоваться такими командами.
Также дискутировали и в этой теме.
Так всё таки — можно?
Не приведёт ли всё это "скрытие той или иной логики: виртуальные функции, linq, wcf, wpf, com, sql и т.д." к некоторому подобию естественного языка?
Я пытаюсь понять, где проходит граница между "можно скрыть" и "комбинаторным взрывом"?
R3>Не приведёт ли всё это "скрытие той или иной логики: виртуальные функции, linq, wcf, wpf, com, sql и т.д." к некоторому подобию естественного языка?
естественный язык очень убогий, как минимум из-за отсутствия встроенного способа описывать деревья и графы
R3>Мы (кажется, с тобой) как-то дискутировали на тему, на сколько сильно можно скрыть все ненужные в данный момент сущности, при написании команды, приближенной к естественному языку. Использовался пример с принтером: надо напечатать документ. Ты говорил, что количество уточняющих деталей (например, какой именно принтер или как именно надо напечатать) не позволит легко пользоваться такими командами.
R3>Я пытаюсь понять, где проходит граница между "можно скрыть" и "комбинаторным взрывом"?
чтобы не было комбинаторного взрыва, как раз и используется скрытие значительной части информации, которая считается верной и известной априори.
возьмем команду:
document.print()
в простейшем случае ее достаточно, если есть всем известные умолчания (и которые мы как раз и скрыли):
что print — это распечатать на принтере,
что принтер один,
что печатать надо одну копию,
настройки печати по умолчанию,
что печатается весь документ
и т.д.
но допустим принтера два: цветной и черно-белый, и вот уже хочется указывать принтер
document.print(to:color-printer)
нужно несколько копий
document.print(to:color-printer, quantity:5)
и т.д.
и это приводит к нескольким большим темам:
как описывать умолчания так, чтобы их легко можно было переопределять в уточняющем виде?
как описывать умолчания так, чтобы они были устойчивы к изменениям?
как построить язык взаимодействия, чтобы в нем легко описывались "расширяющиеся круги" уточнений?
Здравствуйте, DarkGray, Вы писали:
R3>>Не приведёт ли всё это "скрытие той или иной логики: виртуальные функции, linq, wcf, wpf, com, sql и т.д." к некоторому подобию естественного языка? DG>естественный язык очень убогий, как минимум из-за отсутствия встроенного способа описывать деревья и графы
Да, поэтому я и использовал слово "подобие". Хотя в этом "подобии" в итоге может быть использованы только буквы, цифры, пробелы и знаки пунктуации, исключая все правила.
DG>но допустим принтера два: цветной и черно-белый, и вот уже хочется указывать принтер DG>document.print(to:color-printer)
Например, в этом случае выбор принтера может следовать из свойств документа: в каком статусе документ находится (драфт или релиз), тот принтер и будет выбран.
DG>нужно несколько копий DG>document.print(to:color-printer, quantity:5)
Например, в этом случае выбор количества копий может следовать из того, для чего печатается документ. Например, для себя (в статусе драфт — сделать вычитку) достаточно одной копии, а для рассылки (релиз) — в зависимости от количества участников договора, который и содержится в этом документе.
Я к тому, что наши процессы (бизнес-процессы, процессы жизнидеятельности) уже описаны или могут быть описаны. Но мы этим не пользуемся в полной мере.
Пример:
Программист создал форму и планирует сделать на ней две кнопки: ОК и Cancel. Соответственно, он, например, в дизайнере кидает их на форму.
Но, например, у Microsoft есть документ, который описывает, как должны быть расположены эти кнопки.
Получается, что программист делает то, что уже было описано, как делать.
Почему программист не может просто, например, поставить где-то пару галочек: "форма имеет кнопку закрытия с сохранением ввода" и "форма имеет кнопку закрытия с отклонением ввода", а всё остальное будет сделано автоматически?
Следующий уровень — "форма содержит такой-то бизнес-объект".
Следующий — "приложение управляет таким-то бизнес-объектом".
Потом выяснится, что приложения не нужны. Нужны только бизнес-объекты. Данные — Действие — Результат.
Вот тогда и произойдёт следующий шаг в эволюции программирования.
DG>и это приводит к нескольким большим темам: DG>как описывать умолчания так, чтобы их легко можно было переопределять в уточняющем виде? DG>как описывать умолчания так, чтобы они были устойчивы к изменениям? DG>как построить язык взаимодействия, чтобы в нем легко описывались "расширяющиеся круги" уточнений?
Здравствуйте, DarkGray, Вы писали:
DG>во-первых, какие бизнес-сущности скрывает Rx?
Похоже скрывает даже время глотания событий, т.к. судя по ответу Wolfhound'а даже тривиальнейшее добавление условия делается не так-то просто.
DG>во-вторых, какую аппаратную сущность скрывает, например, exception, или using, или автоматический деструктор?
Логически у нас есть задачи: прервать выполнение с ошибкой и освободить ресурсы после того как объект стал ненужен. Эти логические задачи и решает то, что ты перечислил, скрывая от нас механику решения, которая с логической точки зрения является мусором.
DG>и какую бизнес-сущность описывает, например, операция foreach или while?
Логически у нас есть задачи: выполнить для каждого элемента и повторить. Эти логические задачи решаются в шарпе с помощью foreach и while.
DG>перечисли, пожалуйста, хотя бы штук 30 таких логических сущностей, которые скрывать не стоит, чтобы понятно было о чем речь
Это сущности, которые заметны или могут быть заметны для пользователя (уточню, что пользователем может быть не только человек, но и программное окружение). Например, время глотания события заметно для пользователя, т.к. от него зависит время отклика на действие, поэтому это логическая сущность. Также, к примеру, заметен размер кнопки или способ шифрации данных сервером.
Здравствуйте, Real 3L0, Вы писали:
R3>Пример: R3>Программист создал форму и планирует сделать на ней две кнопки: ОК и Cancel. Соответственно, он, например, в дизайнере кидает их на форму. R3>Но, например, у Microsoft есть документ, который описывает, как должны быть расположены эти кнопки. R3>Получается, что программист делает то, что уже было описано, как делать. R3>Почему программист не может просто, например, поставить где-то пару галочек: "форма имеет кнопку закрытия с сохранением ввода" и "форма имеет кнопку закрытия с отклонением ввода", а всё остальное будет сделано автоматически? R3>Следующий уровень — "форма содержит такой-то бизнес-объект". R3>Следующий — "приложение управляет таким-то бизнес-объектом". R3>Потом выяснится, что приложения не нужны. Нужны только бизнес-объекты. Данные — Действие — Результат. R3>Вот тогда и произойдёт следующий шаг в эволюции программирования.
Дык уже есть. Бери 1с, Dynamics, SharePoint. Там ты не пишешь приложение, там ты создаешь объекты, описываешь действия, и представления результатов.
Здравствуйте, gandjustas, Вы писали:
G>Дык уже есть. Бери 1с, Dynamics, SharePoint. Там ты не пишешь приложение, там ты создаешь объекты, описываешь действия, и представления результатов.
Ну и как "ложится" вышеприведённый пример с принтером в эти системы?
Здравствуйте, Real 3L0, Вы писали:
R3>Здравствуйте, gandjustas, Вы писали:
G>>Дык уже есть. Бери 1с, Dynamics, SharePoint. Там ты не пишешь приложение, там ты создаешь объекты, описываешь действия, и представления результатов.
R3>Ну и как "ложится" вышеприведённый пример с принтером в эти системы?
Создаешь объект "принтер", прописываешь ему свойства, задаешь действие — печатать, которое может спросить файл например.
Здравствуйте, gandjustas, Вы писали:
G>>>Дык уже есть. Бери 1с, Dynamics, SharePoint. Там ты не пишешь приложение, там ты создаешь объекты, описываешь действия, и представления результатов. R3>>Ну и как "ложится" вышеприведённый пример с принтером в эти системы? G>Создаешь объект "принтер", прописываешь ему свойства, задаешь действие — печатать, которое может спросить файл например.
А после этих действий, упомянутый тобой объект "файл" будет знать, что теперь его можно печатать? Или надо дополнительно какие-то связи прописывать?
Здравствуйте, Real 3L0, Вы писали:
R3>Здравствуйте, gandjustas, Вы писали:
G>>>>Дык уже есть. Бери 1с, Dynamics, SharePoint. Там ты не пишешь приложение, там ты создаешь объекты, описываешь действия, и представления результатов. R3>>>Ну и как "ложится" вышеприведённый пример с принтером в эти системы? G>>Создаешь объект "принтер", прописываешь ему свойства, задаешь действие — печатать, которое может спросить файл например.
R3>А после этих действий, упомянутый тобой объект "файл" будет знать, что теперь его можно печатать? Или надо дополнительно какие-то связи прописывать?
Как ты сделаешь — так и будет. Придумай реальную задачу, а не сфероконя_в_вакууме.
Здравствуйте, gandjustas, Вы писали:
G>Как ты сделаешь — так и будет.
Т.е. если у меня в базе милион разных объектов, то мне это для каждого надо будет делать? Не интересно.
G> Придумай реальную задачу, а не сфероконя_в_вакууме.
Это самая что ни на есть реальная задача. Не все пользователи компьютеров считают бюджеты и проводят платёжки.
U>Логически у нас есть задачи: прервать выполнение с ошибкой и освободить ресурсы после того как объект стал ненужен. Эти логические задачи и решает то, что ты перечислил, скрывая от нас механику решения, которая с логической точки зрения является мусором.
DG>>и какую бизнес-сущность описывает, например, операция foreach или while?
U>Логически у нас есть задачи: выполнить для каждого элемента и повторить. Эти логические задачи решаются в шарпе с помощью foreach и while.
DG>>перечисли, пожалуйста, хотя бы штук 30 таких логических сущностей, которые скрывать не стоит, чтобы понятно было о чем речь
U>Это сущности, которые заметны или могут быть заметны для пользователя (уточню, что пользователем может быть не только человек, но и программное окружение).
если использовать это определение, то с точки зрения пользователя все наоборот:
1. с точки зрения пользователя важно какой будет путь ошибки, что будет прервано, а что не будет, а текущие exception-ы это скрывают. например, при копировании файлов при ошибках будут отменено копирование последующих файлов, или не будет?
2. с точки зрения пользователя нет "операции для каждого элемента", а уж тем более "повторить". похожи хоть один интерфейс где эти операции есть? но есть операции — для всех, для выбранных, отфильтровать, найти и т.д.
зы
и убери из критерия слово "программное окружение", а то я могу привести кучу программных окружений для которых важно размещение по памяти(например, вирусы), или важно размещение по регистрам (например, числомолотилки для которых важен каждый процент скорости)
R3>Я к тому, что наши процессы (бизнес-процессы, процессы жизнидеятельности) уже описаны или могут быть описаны. Но мы этим не пользуемся в полной мере.
потому что мы не умеем описывать мир.
если использовать имеющиеся инструменты, то вот здесь как раз комбинаторный взрыв и происходит.
R3>Почему программист не может просто, например, поставить где-то пару галочек: "форма имеет кнопку закрытия с сохранением ввода" и "форма имеет кнопку закрытия с отклонением ввода", а всё остальное будет сделано автоматически?
и сколько таких галочек будет? 5, 10, 100, 100000, миллион?
тут же как получается, если мы хотим сохранить ту же самую мощность выбора, то кол-во галочек должно быть равным кол-ву исходных вариантов, а если начинаем уменьшать галочки, то получаем куцый инструмент который мало что умеет.
Здравствуйте, Real 3L0, Вы писали:
R3>Здравствуйте, gandjustas, Вы писали:
G>>Как ты сделаешь — так и будет.
R3>Т.е. если у меня в базе милион разных объектов, то мне это для каждого надо будет делать? Не интересно.
Миллион разных это как? По структуре или по значениям атрибутов?
Первое — не поверю, второе — в чем проблема?
G>> Придумай реальную задачу, а не сфероконя_в_вакууме. R3>Это самая что ни на есть реальная задача. Не все пользователи компьютеров считают бюджеты и проводят платёжки.
Еще меньше считают что "принтер" это объект. Для большинства людей печать — это функция, объекты тут не при чем.
Здравствуйте, DarkGray, Вы писали:
DG>потому что мы не умеем описывать мир. DG> если использовать имеющиеся инструменты, то вот здесь как раз комбинаторный взрыв и происходит.
Умеем. Я неоднократно описывал.
Правда, конечно, не весь мир. И не очень детально. (Хотя углубиться в детали — не проблема.)
Но все были довольны.
R3>>Почему программист не может просто, например, поставить где-то пару галочек: "форма имеет кнопку закрытия с сохранением ввода" и "форма имеет кнопку закрытия с отклонением ввода", а всё остальное будет сделано автоматически? DG>и сколько таких галочек будет? 5, 10, 100, 100000, миллион?
Ну, вот сейчас, можно сказать, уже есть намёки на эти галочки: в студии, на форме, если она имеет кнопки, можно выбрать, какая кнопка ОК, а какая — Cancel.
Т.е. получается, что часто используемые варианты машина может "обдумать" сама, а что-то более сложное — отдаётся на реализацию программисту.
DG>тут же как получается, если мы хотим сохранить ту же самую мощность выбора, то кол-во галочек должно быть равным кол-ву исходных вариантов, а если начинаем уменьшать галочки, то получаем куцый инструмент который мало что умеет.
Ты недопонял мой текст, который шел после галочек.
Смысл в том, что когда однотипных сущностей становится много — их объеденяют в группы. Пользователь начинает управлять группами сущностей, а компьютер получает навык управления единичными сущностями.
Когда становится много групп сущностей — пользователь переходит ещё выше на уровень. И т.д.
Но, конечно, повышения уровня не произойдёт, пока компьютер не научат управлять предыдущим уровнем.
Здравствуйте, gandjustas, Вы писали:
G>Миллион разных это как? По структуре или по значениям атрибутов? G>Первое — не поверю, второе — в чем проблема?
По структуре. Т.е. ты не веришь, что на свете существует миллион различных объектов (правильнее — классов, если объект — это экземпляр класса)? Открой, например, википедию.
R3>>Это самая что ни на есть реальная задача. Не все пользователи компьютеров считают бюджеты и проводят платёжки. G>Еще меньше считают что "принтер" это объект. Для большинства людей печать — это функция, объекты тут не при чем.
Я не говорил, что пользователь считает "принтер" чем-то там. Я про печать и говорил, но ты посчитал это "сфероконём_в_вакууме".
Здравствуйте, Real 3L0, Вы писали:
R3>Здравствуйте, gandjustas, Вы писали:
G>>Миллион разных это как? По структуре или по значениям атрибутов? G>>Первое — не поверю, второе — в чем проблема?
R3>По структуре. Т.е. ты не веришь, что на свете существует миллион различных объектов (правильнее — классов, если объект — это экземпляр класса)? Открой, например, википедию.
А причем тут объекты существующие на свете? Главное какие объекты в программе. Я вот совершенно не верю что в программе будет миллион или даже тысяча разных объектов.
R3>>>Это самая что ни на есть реальная задача. Не все пользователи компьютеров считают бюджеты и проводят платёжки. G>>Еще меньше считают что "принтер" это объект. Для большинства людей печать — это функция, объекты тут не при чем.
R3>Я не говорил, что пользователь считает "принтер" чем-то там. Я про печать и говорил, но ты посчитал это "сфероконём_в_вакууме".
R3>Ну и как "ложится" вышеприведённый пример с принтером в эти системы?
Здравствуйте, jazzer, Вы писали:
J>Да ладно. COM + VB — отличный кубики, все очень легко и просто. J>Или Дельфи с ее компонентами. J>Кубики писать — да, геморрой, а из имеющихся кубиков все очень легко собирается.
Вот чтобы кубиками можно было эффективно пользоваться и нужно метапрограммирование.
Потому что кубики, имеющиеся в наличии и те что нужны в конкретном случае, не перекрываются полностью, а только частично пересекаются. Либо будет чего-то не хватать, либо будет что-то лишнее. Если бы метапрограммы вырезали лишнее, уже было бы не плохо (вырезать легче чем дописывать). Лишнее это не просто лишние мертвые функции, которые ни разу не вызываются.
Многими хорошими приемами программирования пользуются мало потому что слишком большой оверхед (например реактивное програмирование). Оверхед довольно тупой, метапрограмме его по силам удалить.
Здравствуйте, gandjustas, Вы писали:
R3>>По структуре. Т.е. ты не веришь, что на свете существует миллион различных объектов (правильнее — классов, если объект — это экземпляр класса)? Открой, например, википедию. G>А причем тут объекты существующие на свете? Главное какие объекты в программе. Я вот совершенно не верю что в программе будет миллион или даже тысяча разных объектов.
Потому что эти объекты реально существуют. Сейчас — (максимум) в разных программах.
А при наличии связей между объектами можно получить некоторые автоматически генерируемые вещи. Тогда наличие миллиона объектов нам не страшно.
При отсутствии же связей (что мы сейчас и видим) — каждый разработчик делает либо велосипед (клон, т.е. уже кто-то это делал), либо не связаную с другими вещь.
R3>>>>Это самая что ни на есть реальная задача. Не все пользователи компьютеров считают бюджеты и проводят платёжки. G>>>Еще меньше считают что "принтер" это объект. Для большинства людей печать — это функция, объекты тут не при чем.
R3>>Я не говорил, что пользователь считает "принтер" чем-то там. Я про печать и говорил, но ты посчитал это "сфероконём_в_вакууме". G>
R3>>Ну и как "ложится" вышеприведённый пример с принтером в эти системы?
G>Не выкручивайся.
Так ты начни с самого начала:
Пример команды с принтером:
... надо напечатать документ. Ты говорил, что количество уточняющих деталей (например, какой именно принтер или как именно надо напечатать) не позволит легко пользоваться такими командами.
и далее по ветке всё, что касается этого примера с принтером.
Здравствуйте, DarkGray, Вы писали:
U>>Это сущности, которые заметны или могут быть заметны для пользователя (уточню, что пользователем может быть не только человек, но и программное окружение).
DG>если использовать это определение, то с точки зрения пользователя все наоборот: DG>1. с точки зрения пользователя важно какой будет путь ошибки, что будет прервано, а что не будет, а текущие exception-ы это скрывают. например, при копировании файлов при ошибках будут отменено копирование последующих файлов, или не будет?
В каком месте реализация обработки исключений, к примеру, в шарпе ограничивает возможности программиста по прерыванию операции в нужный момент или, наоборот, глушению ошибки?
DG>2. с точки зрения пользователя нет "операции для каждого элемента", а уж тем более "повторить". похожи хоть один интерфейс где эти операции есть? но есть операции — для всех, для выбранных, отфильтровать, найти и т.д.
Если начать детализировать пользовательские операции, то там тут же окажутся операции — и для каждого элемента, и повторить. И никуда от них не дется, т.к. эти операции диктуются логикой задач. А вот никаких регистров в логическом алгоритме нет, поэтому от них можно и нужно избавляться в коде.
DG>зы DG>и убери из критерия слово "программное окружение", а то я могу привести кучу программных окружений для которых важно размещение по памяти(например, вирусы), или важно размещение по регистрам (например, числомолотилки для которых важен каждый процент скорости)
Вирусы и числомолотилки пишут на шарпе? Я же писал:
Поэтому скрывать аппаратные сущности можно и нужно. При условии, конечно, что это не приводит к критической просадке производительности на том классе задач, для решения которых предназначен язык/библиотека.
Здравствуйте, DarkGray, Вы писали:
S_S>> (вырезать легче чем дописывать) DG>но сложнее это сделать без ошибок
Это програмисту приходится ошибки совершать. А метапрограма либо справится с преобразованием, либо нет, ошибку не сделает.
Например, кто-то написал некий класс ObservableCollection<T> , который при изменениях коллекции составляет списки измененных элементов, и отсылает их через события(колбэки).
Кто-то допустим подключил к нему обработчик только устанавливающий флажок changed=true.
Дальше флажок сбрасывается, вызывается код который вносит кучу изменений в колекцию, по окончанию флажок считывается.
Тут куча лишнего будет делаться, если обработчик не использует параметры:
— составляются списки измененных элементов, отправляются в обработчик а в нем игнорируются. Код составляющий эти списки можно выкинуть.
— за время исполнения куска кода флажок не читается а много раз перезаписывается — предыдущий вычесленный результат отбрасывается. Установку флажка можно вынести за цикл и сделать один раз.
Эти переделки программы не такие уж сложные, не требуется какой-то супер-компилятор который умеет все.
Где-то "в песочнице" на упрощенном языке, где нет Reflection и прочих сложностей, такое переписывание сделать не сложно — удаление кода результаты выполнения которого отбрасываются (игнорируются или перезаписываются без чтения). Кэширование и снятие лишних косвенностей тоже сюда входит.
U>В каком месте реализация обработки исключений, к примеру, в шарпе ограничивает возможности программиста по прерыванию операции в нужный момент или, наоборот, глушению ошибки?
как минимум в отсутствии вариационности по: пропускать ошибку/падать по ошибке и т.д.
т.е. очень сложно написать значительный по объему код, который в качестве параметра принимал бы настройку как действовать по ошибке:
падать сразу,
игнорировать,
накапливать ошибки, а потом падать,
накапливать в виде warning-ов,
повторить операцию пару раз, а потом падать
и т.д.
а все это желательно на такой простой задаче, как, например, брауз директорий, а так же на любой задаче которая взаимодействует с недружелюбным миром
S_S> А метапрограма либо справится с преобразованием, либо нет, ошибку не сделает.
даже метапрограмме проще что-то собирать из кусочков, чем кусочки отпиливать от чего-то существующего.
отпиливать тяжело тем, что очень тяжело аккуратно отпилить также все следствия отпиливаемого.
зы
ты может быть говоришь про случай, когда система спроектирована под конкретные отпилы, и именно эти отпилы и используются — тогда проблем нет, но это частный случай.
S_S>такое переписывание сделать не сложно — удаление кода результаты выполнения которого отбрасываются
это подразумевает, что в коде прописано всё знание, которое имел программист.
обычно это не так, и в код прописывается лишь пара процентов знаний о задаче, остальное используется неявно.
например, в программу не прописывают почему взят именно int: а не short, long или biginteger?
также в программу не прописывается почему взят этот алгоритм, а не другой?
последовательность обратывается последовательно, что это действительно так необходимо, или потому что программисту не было необходимости писать параллельную обработку?
и т.д.
Здравствуйте, DarkGray, Вы писали:
DG>как минимум в отсутствии вариационности по: пропускать ошибку/падать по ошибке и т.д. DG>т.е. очень сложно написать значительный по объему код, который в качестве параметра принимал бы настройку как действовать по ошибке: DG>падать сразу, DG>игнорировать, DG>накапливать ошибки, а потом падать, DG>накапливать в виде warning-ов, DG>повторить операцию пару раз, а потом падать DG> и т.д.
Не понял в чем проблема.
class ExceptionWorker
{
ExceptionSettings settings;
public void Execute(Action action);
}
В зависимости от настроек обрабатываешь ошибку нужным образом и повторяешь действие если нужно.
DG>а все это желательно на такой простой задаче, как, например, брауз директорий, а так же на любой задаче которая взаимодействует с недружелюбным миром
Здравствуйте, Real 3L0, Вы писали:
R3>Здравствуйте, gandjustas, Вы писали:
R3>>>По структуре. Т.е. ты не веришь, что на свете существует миллион различных объектов (правильнее — классов, если объект — это экземпляр класса)? Открой, например, википедию. G>>А причем тут объекты существующие на свете? Главное какие объекты в программе. Я вот совершенно не верю что в программе будет миллион или даже тысяча разных объектов.
R3>Потому что эти объекты реально существуют. Сейчас — (максимум) в разных программах.
И что?
R3>А при наличии связей между объектами можно получить некоторые автоматически генерируемые вещи. Тогда наличие миллиона объектов нам не страшно.
Надо задать как сами объекты, так и связи. Количество связей это примерно N^2.
Физически это невозможно.
Но есть еще и пользователи, которые хотят работать им миллионы не нужны, им нужно гораздо меньше. Так что такое кол-во и не нужно.
Здравствуйте, gandjustas, Вы писали:
R3>>Потому что эти объекты реально существуют. Сейчас — (максимум) в разных программах. G>И что?
То, что ими пользуются.
R3>>А при наличии связей между объектами можно получить некоторые автоматически генерируемые вещи. Тогда наличие миллиона объектов нам не страшно. G>Надо задать как сами объекты, так и связи. Количество связей это примерно N^2. G>Физически это невозможно.
Если есть автоматика, то возможно.
G>Но есть еще и пользователи, которые хотят работать им миллионы не нужны, им нужно гораздо меньше. Так что такое кол-во и не нужно.
Вообще-то, то, про что я говорю, как раз и направлено на уменьшение количества объектов (сущностей).
Предложенные тобой системы наоборот — увеличивают количество объектов.
На примере это выглядит так:
Есть какой-нибудь мессенджер, который предоставляет пользователям обмен текстовыми сообщениями. Возникает необходимость в функциональности голосовой связи. Сейчас либо пишут новый мессенджер (повторно реализуя функционал обмена текстовыми сообщениями), либо присобачивают новую функциональность к существующему так, что лучше они бы этого не делали. Потому что голосовая связь — это тоже сообщения, только другого типа, но она также как и текстовые сообщения должна передавать некоторую информацию в "основную базу" мессенджера, например, время отправки сообщения и т.п.
Т.е. в результате мы либо получаем два мессенджера, что даёт нам один лишний функционал (текстовые сообщения), либо мессенджер будет один, но новый функционал будет плохо коррелировать с сущенствующим.
Здравствуйте, Real 3L0, Вы писали:
R3>Здравствуйте, gandjustas, Вы писали:
R3>>>Потому что эти объекты реально существуют. Сейчас — (максимум) в разных программах. G>>И что?
R3>То, что ими пользуются.
Всеми сразу в одной программе? Снова не верю.
R3>>>А при наличии связей между объектами можно получить некоторые автоматически генерируемые вещи. Тогда наличие миллиона объектов нам не страшно. G>>Надо задать как сами объекты, так и связи. Количество связей это примерно N^2. G>>Физически это невозможно.
R3>Если есть автоматика, то возможно.
Какая автоматика? Что может избавить от описания объектов?
Мало того что компьютер не знает о "реальном мире", так и еще любой срез атрибутов "реального мира" будет или избыточен или недостаточен для конкретной задачи. Поэтому даже если бы автоматика существовала, то все равно необхдимость описывать руками никуда бы не делась.
R3>Предложенные тобой системы наоборот — увеличивают количество объектов.
Счегобы?
R3>На примере это выглядит так: R3>Есть какой-нибудь мессенджер, который предоставляет пользователям обмен текстовыми сообщениями. Возникает необходимость в функциональности голосовой связи. Сейчас либо пишут новый мессенджер (повторно реализуя функционал обмена текстовыми сообщениями), либо присобачивают новую функциональность к существующему так, что лучше они бы этого не делали. Потому что голосовая связь — это тоже сообщения, только другого типа, но она также как и текстовые сообщения должна передавать некоторую информацию в "основную базу" мессенджера, например, время отправки сообщения и т.п.
Есть скайп, Lync и другие сервисы. Писать не надо. Кроме того ты опять путаешь объекты и функции. Я говорю про описание объектов, ты говоришь зачем-то о функциях передачи сообщений и голоса. Если пытаться декомпозировать задачу передачи сообщений, то мы совсем уйдем от "реального мира" и бизнес-задач.
Здравствуйте, gandjustas, Вы писали:
R3>>То, что ими пользуются. G>Всеми сразу в одной программе? Снова не верю.
В разных конечно.
G>>>Физически это невозможно. R3>>Если есть автоматика, то возможно. G>Какая автоматика? Что может избавить от описания объектов?
Пример: есть класс Person { int id; string Name; } и есть класс Auto { string Name; int idPerson }.
Языки программирования предоставляют возможность работать со sting-ами. Ты не занимаешься "обучением" sting-ов для каждого класса отдельно. Но ты будешь заниматься "обучением" класса Auto, чтобы он начал понимать, как работать с idPerson. Вот тут бы автоматика помогла бы.
R3>>На примере это выглядит так: R3>>Есть какой-нибудь мессенджер, который предоставляет пользователям обмен текстовыми сообщениями. Возникает необходимость в функциональности голосовой связи. Сейчас либо пишут новый мессенджер (повторно реализуя функционал обмена текстовыми сообщениями), либо присобачивают новую функциональность к существующему так, что лучше они бы этого не делали. Потому что голосовая связь — это тоже сообщения, только другого типа, но она также как и текстовые сообщения должна передавать некоторую информацию в "основную базу" мессенджера, например, время отправки сообщения и т.п. G>Есть скайп, Lync и другие сервисы. Писать не надо.
Ну, и разве это не дублирование функционала?
G> Кроме того ты опять путаешь объекты и функции. Я говорю про описание объектов, ты говоришь зачем-то о функциях передачи сообщений и голоса. Если пытаться декомпозировать задачу передачи сообщений, то мы совсем уйдем от "реального мира" и бизнес-задач.
Сори, возможно, я в чём-то не последователен: у меня некоторые идеи ещё не обдуманы, а в обдуманных идеях я забегаю вперёд.
Я не путаю объекты и функции. Я их — объединяю.
Если подитожить то, что я хочу сказать:
Если есть объект "принтер", то у него есть функция "печать". Соответственно, если есть объект "файл", то для того, чтобы научить его функции "печать", не надо создавать объект "принтер" — он уже есть. Но вот как именно научить объект "файл" функции "печать" — это вопрос. И мне не нравится, как это делается сейчас.
Здравствуйте, Real 3L0, Вы писали:
R3>Пример: есть класс Person { int id; string Name; } и есть класс Auto { string Name; int idPerson }. R3>Языки программирования предоставляют возможность работать со sting-ами. Ты не занимаешься "обучением" sting-ов для каждого класса отдельно. Но ты будешь заниматься "обучением" класса Auto, чтобы он начал понимать, как работать с idPerson. Вот тут бы автоматика помогла бы.
А не надо делать idPerson, должна быть ссылка. А пусть система сама разбирается как эту ссылку мапить на хранилище. Ты сам пытаешься работать со слишком низким уровнем и тебе "автоматики" не хватает.
R3>>>На примере это выглядит так: R3>>>Есть какой-нибудь мессенджер, который предоставляет пользователям обмен текстовыми сообщениями. Возникает необходимость в функциональности голосовой связи. Сейчас либо пишут новый мессенджер (повторно реализуя функционал обмена текстовыми сообщениями), либо присобачивают новую функциональность к существующему так, что лучше они бы этого не делали. Потому что голосовая связь — это тоже сообщения, только другого типа, но она также как и текстовые сообщения должна передавать некоторую информацию в "основную базу" мессенджера, например, время отправки сообщения и т.п. G>>Есть скайп, Lync и другие сервисы. Писать не надо. R3>Ну, и разве это не дублирование функционала?
Это тут совершенно не при чем. При чем то, что не надо такой функционал писать.
G>> Кроме того ты опять путаешь объекты и функции. Я говорю про описание объектов, ты говоришь зачем-то о функциях передачи сообщений и голоса. Если пытаться декомпозировать задачу передачи сообщений, то мы совсем уйдем от "реального мира" и бизнес-задач.
R3>Сори, возможно, я в чём-то не последователен: у меня некоторые идеи ещё не обдуманы, а в обдуманных идеях я забегаю вперёд. R3>Я не путаю объекты и функции. Я их — объединяю.
Выделенное — очень зря. Функции объективны, а какие объекты — зависит от задачи и от взгляда человека на эту задачу (предельно субъективны).
R3>Если подитожить то, что я хочу сказать: R3>Если есть объект "принтер", то у него есть функция "печать". Соответственно, если есть объект "файл", то для того, чтобы научить его функции "печать", не надо создавать объект "принтер" — он уже есть. Но вот как именно научить объект "файл" функции "печать" — это вопрос. И мне не нравится, как это делается сейчас.
Нету такого объекта, потому что ты банально не сможешь непротиворечиво его описать. Когда начнешь описывать этот объект выродится у тебя в одну функцию печати. И эта функция принимает на вход некоторый объект, который можно печатать. Вот и вся связь. После этого тебе надо согласовать интерфейс для "объекта, который можно печатать" и научить "файл" поддерживать этот интерфейс.
Здравствуйте, gandjustas, Вы писали:
R3>>Языки программирования предоставляют возможность работать со sting-ами. Ты не занимаешься "обучением" sting-ов для каждого класса отдельно. Но ты будешь заниматься "обучением" класса Auto, чтобы он начал понимать, как работать с idPerson. Вот тут бы автоматика помогла бы. G>А не надо делать idPerson, должна быть ссылка. А пусть система сама разбирается как эту ссылку мапить на хранилище. Ты сам пытаешься работать со слишком низким уровнем и тебе "автоматики" не хватает.
Ну пусть ссылка. Да, пусть система сама разбирается. Но таких систем, к сожалению, нет.
G>>>Есть скайп, Lync и другие сервисы. Писать не надо. R3>>Ну, и разве это не дублирование функционала? G>Это тут совершенно не при чем. При чем то, что не надо такой функционал писать.
Основная проблема не в существующем функционале, а том, что этот функционал никто не может просто использовать отдельно от продукта, в котором он реализован.
R3>>Сори, возможно, я в чём-то не последователен: у меня некоторые идеи ещё не обдуманы, а в обдуманных идеях я забегаю вперёд. R3>>Я не путаю объекты и функции. Я их — объединяю. G>Выделенное — очень зря. Функции объективны, а какие объекты — зависит от задачи и от взгляда человека на эту задачу (предельно субъективны).
Не зная объект, ты не сможешь сказать, применима ли к нему определённая функция.
R3>>Если подитожить то, что я хочу сказать: R3>>Если есть объект "принтер", то у него есть функция "печать". Соответственно, если есть объект "файл", то для того, чтобы научить его функции "печать", не надо создавать объект "принтер" — он уже есть. Но вот как именно научить объект "файл" функции "печать" — это вопрос. И мне не нравится, как это делается сейчас.
G>Нету такого объекта, потому что ты банально не сможешь непротиворечиво его описать. Когда начнешь описывать этот объект выродится у тебя в одну функцию печати.
Эээ, я что-то не понял. В первом предложении ты написал о невозможности, а во втором — привёл пример как можно.
Объект может состоять не только из одной функции — от может содержать вызовы других функций. Например, если это "принтер", то он может содержать вызов функции "местоположение" (по GPS), например для того, чтобы разрешать пользоваться функцией "печать" только тем, кто находится недалеко от этого принтера.
G> И эта функция принимает на вход некоторый объект, который можно печатать. Вот и вся связь. После этого тебе надо согласовать интерфейс для "объекта, который можно печатать" и научить "файл" поддерживать этот интерфейс.
Да-да, как-то так. Но этого мало. Надо чтобы было так, чтобы объекты сами могли выдавать другим объектам, что с ними можно сделать. Без обучения.
Здравствуйте, Real 3L0, Вы писали:
R3>Здравствуйте, gandjustas, Вы писали:
R3>>>Языки программирования предоставляют возможность работать со sting-ами. Ты не занимаешься "обучением" sting-ов для каждого класса отдельно. Но ты будешь заниматься "обучением" класса Auto, чтобы он начал понимать, как работать с idPerson. Вот тут бы автоматика помогла бы. G>>А не надо делать idPerson, должна быть ссылка. А пусть система сама разбирается как эту ссылку мапить на хранилище. Ты сам пытаешься работать со слишком низким уровнем и тебе "автоматики" не хватает.
R3>Ну пусть ссылка. Да, пусть система сама разбирается. Но таких систем, к сожалению, нет.
Как это нет? Я вот пользую Entity Framework, он вполне умеет понимать ссылки и генерить из них схему БД.
Есть Orchard CMS, который тоже понимает ссылки.
Более высокоуровневые системы: 1C, SharePoint, Dynamics, в них также ты описываешь ссылки между сущностями, а он сам занимается раскладываением их в хранилище. Вот только если ты будешь путать ссылки и функции, то ниче хорошего у тебя не выйдет изначально.
G>>>>Есть скайп, Lync и другие сервисы. Писать не надо. R3>>>Ну, и разве это не дублирование функционала? G>>Это тут совершенно не при чем. При чем то, что не надо такой функционал писать.
R3>Основная проблема не в существующем функционале, а том, что этот функционал никто не может просто использовать отдельно от продукта, в котором он реализован.
не понял мысли. Ты используешь некоторую платформу, будь это просто dll, подключаемая к проекту или готовое приложение.
R3>>>Сори, возможно, я в чём-то не последователен: у меня некоторые идеи ещё не обдуманы, а в обдуманных идеях я забегаю вперёд. R3>>>Я не путаю объекты и функции. Я их — объединяю. G>>Выделенное — очень зря. Функции объективны, а какие объекты — зависит от задачи и от взгляда человека на эту задачу (предельно субъективны). R3>Не зная объект, ты не сможешь сказать, применима ли к нему определённая функция.
И что? Тебе ведь не нужны объекты сами по себе, тебе (и пользователю) нужны функции. А объекты обеспечивают возможность выполнения функций.
R3>>>Если подитожить то, что я хочу сказать: R3>>>Если есть объект "принтер", то у него есть функция "печать". Соответственно, если есть объект "файл", то для того, чтобы научить его функции "печать", не надо создавать объект "принтер" — он уже есть. Но вот как именно научить объект "файл" функции "печать" — это вопрос. И мне не нравится, как это делается сейчас.
G>>Нету такого объекта, потому что ты банально не сможешь непротиворечиво его описать. Когда начнешь описывать этот объект выродится у тебя в одну функцию печати.
R3>Эээ, я что-то не понял. В первом предложении ты написал о невозможности, а во втором — привёл пример как можно.
Еще раз. Я сказал что ты не сможешь описать объект, и я описал функцию. Ты их смешиваешь — в этом проблема.
R3>Объект может состоять не только из одной функции — от может содержать вызовы других функций.
Объект не может состоять из функций. Пока этого не поймешь дальше не продвинешься.
G>Функции объективны, а какие объекты — зависит от задачи и от взгляда человека на эту задачу (предельно субъективны).
функции настолько же субъективны, насколько и объекты
можно
печатать на принтере,
выводить на принтер,
передавать на принтер,
отправить на принтер,
взаимодействовать с принтером,
вывести в печатном виде,
получить твердую копию,
преобразовать в бумажный вид
и еще 137 видов функций(действий)
зы
это есть опасное заблуждение, культивируемое на рсдн-е и в рядах фя-шников, что функция более объективна, чем объект.
в реальности это не так, и не важно на чем строить модели: на сущностях(объектах) или на действиях(функциях), и то и другое субъективные понятия, которые легко могут меняться от того или иного взгляда на решаемую проблему
G>Объект не может состоять из функций. Пока этого не поймешь дальше не продвинешься.
не путай человека.
функция уж точно не может состоять из функций (не уж тем более из объектов), а их может только вызывать(или оперировать/использовать, если про объекты)
зы
а вообще все эти утверждения: может/не может бессмысленны, пока не зафиксирована задача(цель) и термины
Здравствуйте, DarkGray, Вы писали:
G>>Функции объективны, а какие объекты — зависит от задачи и от взгляда человека на эту задачу (предельно субъективны).
DG>функции настолько же субъективны, насколько и объекты
DG>можно DG>печатать на принтере, DG>выводить на принтер, DG>передавать на принтер, DG>отправить на принтер, DG>взаимодействовать с принтером, DG>вывести в печатном виде, DG>получить твердую копию, DG>преобразовать в бумажный вид DG>и еще 137 видов функций(действий)
По сути это все одно и тоже (синонимы). Важно не название, а суть.
DG>зы DG>это есть опасное заблуждение, культивируемое на рсдн-е и в рядах фя-шников, что функция более объективна, чем объект.
ФЯ тут не при чем. Посмотрите люблю бизнес-постановку задачи. Людям нужны функции, приходится долго анализировать постановку что понять какие там объекты нужны.
А вот программистам проще наоборот, они сначала выдумывают объекты (классы), а потом прилепляют к ним функции.
DG>в реальности это не так, и не важно на чем строить модели: на сущностях(объектах) или на действиях(функциях), и то и другое субъективные понятия, которые легко могут меняться от того или иного взгляда на решаемую проблему
Про реальность я написал выше.
Здравствуйте, lseder, Вы писали:
L>>Марти Фаулер. Архитектура корпоративных программных приложений. L>спасибо, посмотрю. но моя задача по размерам пока не тянет на корпоративные размеры, L>хотя общие принципы разработки знать необходимо.
L> Уже несколько месяцев бьюсь над структурой конструирования мета-конструкций.
Там таки и описаны мета-конструкции с самых верхних уровней. Т.е. абстрагироваться не от текста,
а от визуального представления. Хотя вашу задачу я так и не понял.
Динамически конструирумое дерево. Я так понимаю, это дерево разбора синаксического анализатора+
динамически дополняемое лексемами. Знакомо?
L>>По моему наиболее близко на сегодняшний день, к сабжу. L>>Есть еще книги, "Порождающее программирование". "Фабрики разработки программ". И много много всего по паттернам, UML. L>"Порождающее программирование" наиболее близко к теме, но книгу чарнецки в Украине купить невозможно.
Просто она устарела, я брал лет 5 назад, в Украине в провинции
L>>>- Реализовать хотелось бы на javascript + sql (web kit html5), так как интересно сделать L>>>конструктор на чистом браузере (для тачскринов). L>>А зачем? L>для iPad-а и других тачскринов.
Таки да, объять необъятное
Здравствуйте, gandjustas, Вы писали:
R3>>Ну пусть ссылка. Да, пусть система сама разбирается. Но таких систем, к сожалению, нет. G>Как это нет? Я вот пользую Entity Framework, он вполне умеет понимать ссылки и генерить из них схему БД. G>Есть Orchard CMS, который тоже понимает ссылки. G>Более высокоуровневые системы: 1C, SharePoint, Dynamics, в них также ты описываешь ссылки между сущностями, а он сам занимается раскладываением их в хранилище. Вот только если ты будешь путать ссылки и функции, то ниче хорошего у тебя не выйдет изначально.
Ну тогда я ещё раз прошу тебя описать, как ляжет пример с принтером в эти системы?
R3>>Основная проблема не в существующем функционале, а том, что этот функционал никто не может просто использовать отдельно от продукта, в котором он реализован. G>не понял мысли. Ты используешь некоторую платформу, будь это просто dll, подключаемая к проекту или готовое приложение.
Я написал dll, которая на вход получает string, а на выходе — string, в котором каждая буква "о" заменена на "О".
Потом я запустил Word (Writer).
Что мне надо сделать, чтобы воспользоваться своей dll? Макросы не предлагать, ибо это тоже самое, что написать свой Word.
R3>>>>Сори, возможно, я в чём-то не последователен: у меня некоторые идеи ещё не обдуманы, а в обдуманных идеях я забегаю вперёд. R3>>>>Я не путаю объекты и функции. Я их — объединяю. G>>>Выделенное — очень зря. Функции объективны, а какие объекты — зависит от задачи и от взгляда человека на эту задачу (предельно субъективны). R3>>Не зная объект, ты не сможешь сказать, применима ли к нему определённая функция. G>И что? Тебе ведь не нужны объекты сами по себе, тебе (и пользователю) нужны функции. А объекты обеспечивают возможность выполнения функций.
А почему мне (и пользователям) не нужны объекты? Текст, видео-файл, звук, картинка — это всё объекты, которые нужны.
R3>>Объект может состоять не только из одной функции — от может содержать вызовы других функций. G>Объект не может состоять из функций. Пока этого не поймешь дальше не продвинешься.
Здравствуйте, Real 3L0, Вы писали:
R3>Здравствуйте, gandjustas, Вы писали:
R3>>>Ну пусть ссылка. Да, пусть система сама разбирается. Но таких систем, к сожалению, нет. G>>Как это нет? Я вот пользую Entity Framework, он вполне умеет понимать ссылки и генерить из них схему БД. G>>Есть Orchard CMS, который тоже понимает ссылки. G>>Более высокоуровневые системы: 1C, SharePoint, Dynamics, в них также ты описываешь ссылки между сущностями, а он сам занимается раскладываением их в хранилище. Вот только если ты будешь путать ссылки и функции, то ниче хорошего у тебя не выйдет изначально.
R3>Ну тогда я ещё раз прошу тебя описать, как ляжет пример с принтером в эти системы?
Еще раз говорю: никак. Потому что принтер, это не объект, а функция печати. Во всех указанных системах функция реализована.
R3>>>Основная проблема не в существующем функционале, а том, что этот функционал никто не может просто использовать отдельно от продукта, в котором он реализован. G>>не понял мысли. Ты используешь некоторую платформу, будь это просто dll, подключаемая к проекту или готовое приложение.
R3>Я написал dll, которая на вход получает string, а на выходе — string, в котором каждая буква "о" заменена на "О". R3>Потом я запустил Word (Writer). R3>Что мне надо сделать, чтобы воспользоваться своей dll? Макросы не предлагать, ибо это тоже самое, что написать свой Word.
Опиши какая функция тебе нужна. Напрмиер есть стандартная функция замены, у нее есть некоторый интерфейс. Придумай интерфейс для своего кода, реализуй и пользуй. Можешь например в сторону VSTO посмотреть.
R3>>>>>Сори, возможно, я в чём-то не последователен: у меня некоторые идеи ещё не обдуманы, а в обдуманных идеях я забегаю вперёд. R3>>>>>Я не путаю объекты и функции. Я их — объединяю. G>>>>Выделенное — очень зря. Функции объективны, а какие объекты — зависит от задачи и от взгляда человека на эту задачу (предельно субъективны). R3>>>Не зная объект, ты не сможешь сказать, применима ли к нему определённая функция. G>>И что? Тебе ведь не нужны объекты сами по себе, тебе (и пользователю) нужны функции. А объекты обеспечивают возможность выполнения функций. R3>А почему мне (и пользователям) не нужны объекты? Текст, видео-файл, звук, картинка — это всё объекты, которые нужны.
Ну открой SharePoint там все это есть. В 1С нету, в ней нет функций, для которых нужен объект "файл".
R3>>>Объект может состоять не только из одной функции — от может содержать вызовы других функций. G>>Объект не может состоять из функций. Пока этого не поймешь дальше не продвинешься. R3>Реальный мир с тобой не согласен.
Как раз реальный мир со мной согласен ибо я в неделю как минимум одну постановку\ТЗ\SRS изучаю с целью понять какие объекты нужны для реализации указанных в документе функций.
Здравствуйте, gandjustas, Вы писали:
G>ФЯ тут не при чем. Посмотрите люблю бизнес-постановку задачи. Людям нужны функции, приходится долго анализировать постановку что понять какие там объекты нужны.
Я написал не один десяток функциональных спецификай (да и просто по опыту), и не встречал ни одной системы, состоящей только из функций.
Я соглашусь с этим твоим утверждением только тогда, когда система никогда не будет выдавать ничего, кроме надписи — "Всё хорошо!".
Текущие же системы генерируют отчёты, графики, уведомления, напоминания, предупреждения и т.д. для того, чтобы дальнейшие действия принял человек. Т.е. системы создают объекты.
Здравствуйте, Real 3L0, Вы писали:
R3>Здравствуйте, gandjustas, Вы писали:
G>>ФЯ тут не при чем. Посмотрите люблю бизнес-постановку задачи. Людям нужны функции, приходится долго анализировать постановку что понять какие там объекты нужны.
R3>Я написал не один десяток функциональных спецификай (да и просто по опыту), и не встречал ни одной системы, состоящей только из функций.
И я не встречал. И что?
R3>Я соглашусь с этим твоим утверждением только тогда, когда система никогда не будет выдавать ничего, кроме надписи — "Всё хорошо!".
Ниче не понял.
R3>Текущие же системы генерируют отчёты, графики, уведомления, напоминания, предупреждения и т.д. для того, чтобы дальнейшие действия принял человек. Т.е. системы создают объекты.
Не-а, генерация отчета — функция, напоминание — функция.
Увы, пока этого не поймешь продвинуться дальше не получится.
Здравствуйте, gandjustas, Вы писали:
R3>>Ну тогда я ещё раз прошу тебя описать, как ляжет пример с принтером в эти системы? G>Еще раз говорю: никак. Потому что принтер, это не объект, а функция печати. Во всех указанных системах функция реализована.
Ясно. Значит я не смогу привязать к этой функции что-то своё, например, упомянутое определение местоположения.
Следовательно, данные системы (на данном этапе) не могут предложить ничего более, чем "вариться в собственном соку".
G>Опиши какая функция тебе нужна. Напрмиер есть стандартная функция замены, у нее есть некоторый интерфейс. Придумай интерфейс для своего кода, реализуй и пользуй. Можешь например в сторону VSTO посмотреть.
Здравствуйте, gandjustas, Вы писали:
R3>>Текущие же системы генерируют отчёты, графики, уведомления, напоминания, предупреждения и т.д. для того, чтобы дальнейшие действия принял человек. Т.е. системы создают объекты. G>Не-а, генерация отчета — функция, напоминание — функция.
Главное в генерации отчета не генерация, а отчёт.
G>Увы, пока этого не поймешь продвинуться дальше не получится.
Ну, кое в чём я уже продвинулся. Например всё то, что Apple представил в последнем своём продукте (привязка определения местоположения к планировщику дел или iCloud) — это примеры того, что можно сделать на моей системе.
Вероятно потому, что они считаю что "магазин" — это не только функция "купить".
G>По сути это все одно и тоже (синонимы). Важно не название, а суть.
это тебе так кажется. каждое из этих действий специфицируется по своему: каждое из них берет свой вход, выдает свой выход, используется свой контекст и делает специфичные для себя преобразования.
допустим, мы все-таки хотим получить "объективную" функцию, и попробуем ее специфировать.
выход, на первый взгляд, специфицировать получается достаточно просто: кипа бумаги с нанесенным на нее изображением(текстом),
с входом уже намного сложнее. что на входе? документ? что это такое? набор байт? в каком формате? поток символов? в каком стандарте? postscript-элементы? они в виде массива? потока? дерева? графа?
функция печатать включает в себя получение документа из какого-либо источника? или нет?
функция печатать включает в себя преобразование документов в печатный вид? или уже принимает печатный вид?
функция печатать включает в себя поиск принтера или нет?
функция печатать включает в себя организацию взаимодействия между принтером и пользователем, если например бумага кончилась, или нет?
если принтер понимает несколько форматов, а документ может быть преобразован тоже в несколько форматов, то функция печатать ищет наилучший вариант преобразования или нет?
и таких или/или вагон и маленькая тележка, которая как раз и размывает "объективность" что функций, что объектов
DG>>зы DG>>это есть опасное заблуждение, культивируемое на рсдн-е и в рядах фя-шников, что функция более объективна, чем объект. G>ФЯ тут не при чем. Посмотрите люблю бизнес-постановку задачи. Людям нужны функции, приходится долго анализировать постановку что понять какие там объекты нужны. G>А вот программистам проще наоборот, они сначала выдумывают объекты (классы), а потом прилепляют к ним функции.
с объектами проще, они хотя бы статичны
например, намного проще специфицировать что такое картинка, чем что такое вывод изображения.
Здравствуйте, Real 3L0, Вы писали:
R3>Здравствуйте, gandjustas, Вы писали:
R3>>>Ну тогда я ещё раз прошу тебя описать, как ляжет пример с принтером в эти системы? G>>Еще раз говорю: никак. Потому что принтер, это не объект, а функция печати. Во всех указанных системах функция реализована.
R3>Ясно. Значит я не смогу привязать к этой функции что-то своё, например, упомянутое определение местоположения. R3>Следовательно, данные системы (на данном этапе) не могут предложить ничего более, чем "вариться в собственном соку".
Вполне возможно. Только причем тут объекты?
G>>Опиши какая функция тебе нужна. Напрмиер есть стандартная функция замены, у нее есть некоторый интерфейс. Придумай интерфейс для своего кода, реализуй и пользуй. Можешь например в сторону VSTO посмотреть.
R3>Про что я и говорил — "напиши свой Word".
Это ты сильно перегибаешь палку.
Здравствуйте, Real 3L0, Вы писали:
R3>Здравствуйте, gandjustas, Вы писали:
R3>>>Текущие же системы генерируют отчёты, графики, уведомления, напоминания, предупреждения и т.д. для того, чтобы дальнейшие действия принял человек. Т.е. системы создают объекты. G>>Не-а, генерация отчета — функция, напоминание — функция. R3>Главное в генерации отчета не генерация, а отчёт.
Демагогия. Пользоватею необходимо уметь получать от программы отчет на основании тех данных, которые он вносил. Если ты ему один раз сделаешь отчет толку будет мало. Поэтому как раз наоборот генерация гораздо важнее отчета как такового.
G>>Увы, пока этого не поймешь продвинуться дальше не получится. R3>Ну, кое в чём я уже продвинулся. Например всё то, что Apple представил в последнем своём продукте (привязка определения местоположения к планировщику дел или iCloud) — это примеры того, что можно сделать на моей системе. R3>Вероятно потому, что они считаю что "магазин" — это не только функция "купить".
В магазине самое главное не купть, а помочь пользователю найти то что ему нужно.
Здравствуйте, DarkGray, Вы писали:
G>>По сути это все одно и тоже (синонимы). Важно не название, а суть.
DG>это тебе так кажется. каждое из этих действий специфицируется по своему: каждое из них берет свой вход, выдает свой выход, используется свой контекст и делает специфичные для себя преобразования.
Возможно, но ты сразу по это не написал, поэтому мое утверждение остается верным.
DG>допустим, мы все-таки хотим получить "объективную" функцию, и попробуем ее специфировать. DG>выход, на первый взгляд, специфицировать получается достаточно просто: кипа бумаги с нанесенным на нее изображением(текстом), DG>с входом уже намного сложнее. что на входе? документ? что это такое? набор байт? в каком формате? поток символов? в каком стандарте? postscript-элементы? они в виде массива? потока? дерева? графа? DG>функция печатать включает в себя получение документа из какого-либо источника? или нет? DG>функция печатать включает в себя преобразование документов в печатный вид? или уже принимает печатный вид? DG>функция печатать включает в себя поиск принтера или нет? DG>функция печатать включает в себя организацию взаимодействия между принтером и пользователем, если например бумага кончилась, или нет? DG>если принтер понимает несколько форматов, а документ может быть преобразован тоже в несколько форматов, то функция печатать ищет наилучший вариант преобразования или нет? DG>и таких или/или вагон и маленькая тележка, которая как раз и размывает "объективность" что функций, что объектов
Это ты о чем вообще? Я говорю что функция печати объективна, ибо людям надо получать что-либо на бумаге. А с какими данными (объектами) будет эта функция работать уже зависит от конкретного приложения. Чтобы что-то распечатать пользователь будет искать функцию печати, а не "объект" принтер.
DG>>>зы DG>>>это есть опасное заблуждение, культивируемое на рсдн-е и в рядах фя-шников, что функция более объективна, чем объект. G>>ФЯ тут не при чем. Посмотрите люблю бизнес-постановку задачи. Людям нужны функции, приходится долго анализировать постановку что понять какие там объекты нужны. G>>А вот программистам проще наоборот, они сначала выдумывают объекты (классы), а потом прилепляют к ним функции.
DG>с объектами проще, они хотя бы статичны DG>например, намного проще специфицировать что такое картинка, чем что такое вывод изображения.
Именно. Поэтому программисты часто занимаются спецификациями картинок вместо вывода изображений.
Здравствуйте, gandjustas, Вы писали:
R3>>Ясно. Значит я не смогу привязать к этой функции что-то своё, например, упомянутое определение местоположения. R3>>Следовательно, данные системы (на данном этапе) не могут предложить ничего более, чем "вариться в собственном соку". G>Вполне возможно. Только причем тут объекты?
Извини, но мне надоело объяснять.
R3>>Про что я и говорил — "напиши свой Word". G>Это ты сильно перегибаешь палку.
Это ты скажи всем разрабочикам, которые пишут клоны существующих продуктов.
L>Там таки и описаны мета-конструкции с самых верхних уровней. Т.е. абстрагироваться не от текста, L>а от визуального представления. Хотя вашу задачу я так и не понял.
Задача построить контекстный конструктор кода.
Конструктор — потому что выбор доступных конструкций из списка.
Ввод с клавиатуры только необходимой информации — имена переменных, процедур, параметров...
Контекстный — потому что при выборе элемента дерева — показываются только доступные для вставки элементы.
Тем самым соблюдается принцип видимого интерфейса, все что можно сделать — есть в списке.
Кода — результатом будет программа.
Метаструктура тут нужна лишь для организации всего здесь описанного. с учетом будущего расширения.
Хотя я уже склоняюсь к тому чтобы не усложнять себе жизнь, и сделать только то что пока необходимо.
L>Динамически конструирумое дерево. Я так понимаю, это дерево разбора синаксического анализатора+ L>динамически дополняемое лексемами. Знакомо?
Оно. Зачем нам мучиться, учить структуры программ для каждого из компиляторов разных языков.
Помнить все структуры каждого языка. Хватит только знать основные понятия программирования.
Здравствуйте, gandjustas, Вы писали:
R3>>>>Текущие же системы генерируют отчёты, графики, уведомления, напоминания, предупреждения и т.д. для того, чтобы дальнейшие действия принял человек. Т.е. системы создают объекты. G>>>Не-а, генерация отчета — функция, напоминание — функция. R3>>Главное в генерации отчета не генерация, а отчёт. G>Демагогия. Пользоватею необходимо уметь получать от программы отчет на основании тех данных, которые он вносил. Если ты ему один раз сделаешь отчет толку будет мало. Поэтому как раз наоборот генерация гораздо важнее отчета как такового.
Да, соглашусь. Только, как я уже говорил, у меня функция связана с объектом.
Получается, что у тебя отчёт — это функция: сделали что-то.
У меня это функция + объект: сделали отчёт.
Следовательно, у меня можно создать функции "ждать появления нового отчёта" и "анализировать отчёт".
Здравствуйте, lseder, Вы писали:
L>>Там таки и описаны мета-конструкции с самых верхних уровней. Т.е. абстрагироваться не от текста, L>>а от визуального представления. Хотя вашу задачу я так и не понял. L>Задача построить контекстный конструктор кода. L>Конструктор — потому что выбор доступных конструкций из списка. L> Ввод с клавиатуры только необходимой информации — имена переменных, процедур, параметров... L>Контекстный — потому что при выборе элемента дерева — показываются только доступные для вставки элементы. L> Тем самым соблюдается принцип видимого интерфейса, все что можно сделать — есть в списке. L>Кода — результатом будет программа.
http://blogs.computerra.ru/10717 http://www.computerra.ru/terralab/softerra/547989/
L>>Динамически конструирумое дерево. Я так понимаю, это дерево разбора синаксического анализатора+ L>>динамически дополняемое лексемами. Знакомо? L>Оно. Зачем нам мучиться, учить структуры программ для каждого из компиляторов разных языков. L>Помнить все структуры каждого языка. Хватит только знать основные понятия программирования.
Здравствуйте, Real 3L0, Вы писали:
R3>>>Про что я и говорил — "напиши свой Word". G>>Это ты сильно перегибаешь палку. R3>Это ты скажи всем разрабочикам, которые пишут клоны существующих продуктов.
Уж точно не потому что не могут свою функцию замены сделать.
Здравствуйте, Real 3L0, Вы писали:
R3>Здравствуйте, gandjustas, Вы писали:
R3>>>>>Текущие же системы генерируют отчёты, графики, уведомления, напоминания, предупреждения и т.д. для того, чтобы дальнейшие действия принял человек. Т.е. системы создают объекты. G>>>>Не-а, генерация отчета — функция, напоминание — функция. R3>>>Главное в генерации отчета не генерация, а отчёт. G>>Демагогия. Пользоватею необходимо уметь получать от программы отчет на основании тех данных, которые он вносил. Если ты ему один раз сделаешь отчет толку будет мало. Поэтому как раз наоборот генерация гораздо важнее отчета как такового.
R3>Да, соглашусь. Только, как я уже говорил, у меня функция связана с объектом.
С каким? Пользователь эту функцию как вызывать будет?
Например есть бухгалтерская программа, нужен баланс (отчет для налоговой). Или система управления проектами, нужен burndown chart.
С какими объектами оно будет связано?
R3>Получается, что у тебя отчёт — это функция: сделали что-то. R3>У меня это функция + объект: сделали отчёт. R3>Следовательно, у меня можно создать функции "ждать появления нового отчёта" и "анализировать отчёт".
Тут я перестал понимать что значит отчет...
Здравствуйте, gandjustas, Вы писали:
R3>>>>Про что я и говорил — "напиши свой Word". G>>>Это ты сильно перегибаешь палку. R3>>Это ты скажи всем разрабочикам, которые пишут клоны существующих продуктов. G>Уж точно не потому что не могут свою функцию замены сделать.
Здравствуйте, gandjustas, Вы писали:
R3>>Да, соглашусь. Только, как я уже говорил, у меня функция связана с объектом. G>С каким? Пользователь эту функцию как вызывать будет?
Я решил, что нужна отдельная система со своим интерфейсом под всё это дело.
G>Например есть бухгалтерская программа, нужен баланс (отчет для налоговой). Или система управления проектами, нужен burndown chart. G>С какими объектами оно будет связано?
С теми же, что и сейчас связано.
R3>>Получается, что у тебя отчёт — это функция: сделали что-то. R3>>У меня это функция + объект: сделали отчёт. R3>>Следовательно, у меня можно создать функции "ждать появления нового отчёта" и "анализировать отчёт". G>Тут я перестал понимать что значит отчет...
Здравствуйте, Real 3L0, Вы писали:
R3>Здравствуйте, gandjustas, Вы писали:
R3>>>Да, соглашусь. Только, как я уже говорил, у меня функция связана с объектом. G>>С каким? Пользователь эту функцию как вызывать будет?
R3>Я решил, что нужна отдельная система со своим интерфейсом под всё это дело.
G>>Например есть бухгалтерская программа, нужен баланс (отчет для налоговой). Или система управления проектами, нужен burndown chart. G>>С какими объектами оно будет связано?
R3>С теми же, что и сейчас связано.
Это какими?
R3>>>Получается, что у тебя отчёт — это функция: сделали что-то. R3>>>У меня это функция + объект: сделали отчёт. R3>>>Следовательно, у меня можно создать функции "ждать появления нового отчёта" и "анализировать отчёт". G>>Тут я перестал понимать что значит отчет... R3>Отчёт — это объект.
Отлично, и какие атрибуты у этого объекта? Что значит "анализировать отчет"?
Здравствуйте, gandjustas, Вы писали:
R3>>Я решил, что нужна отдельная система со своим интерфейсом под всё это дело. G>
Т.е. то, что разработчики создают новые интерфейсы (программы) для существующего функционала (программ), у тебя удивления не вызывает, а принципиально новый подход (ну, почти новый) к общению с компьютером это, значит, удивительно и должен использовать старые разработки?
G>>>Например есть бухгалтерская программа, нужен баланс (отчет для налоговой). Или система управления проектами, нужен burndown chart. G>>>С какими объектами оно будет связано? R3>>С теми же, что и сейчас связано. G>Это какими?
Блин, да я не спец в бухгалтерии. Предположу, что если это отчёт для налоговой, то у отчёт должен иметь адрес назначения.
Тебе разве не достаточно примера "сгенерировать отчёт"?
R3>>>>Следовательно, у меня можно создать функции "ждать появления нового отчёта" и "анализировать отчёт". G>>>Тут я перестал понимать что значит отчет... R3>>Отчёт — это объект. G>Отлично, и какие атрибуты у этого объекта?
Например, "дата создания". Это важно?
G> Что значит "анализировать отчет"?
Это значит, что надо выполнить функцию "анализировать" к объекту "отчёт".
G>Это ты о чем вообще? Я говорю что функция печати объективна, ибо людям надо получать что-либо на бумаге. А с какими данными (объектами) будет эта функция работать уже зависит от конкретного приложения. Чтобы что-то распечатать пользователь будет искать функцию печати, а не "объект" принтер.
чему научишь пользователей, то они и будут искать
научишь перетаскивать документ на принтер, будут перетаскивать на принтер.
научишь вызывать функцию, будут вызывать функцию
R3>http://blogs.computerra.ru/10717 R3>http://www.computerra.ru/terralab/softerra/547989/
Очень похоже, только у андроида нет фильтрации доступных элементов по выбраной конструкции. Весь смысл в этом.
На счет микрософта не знаю, видео не смотрел.
Да и таскать блоки мишкой это фигня.
R3>UML?
Очень надеюсь, хотя и его хоронили, и доказывали невозможность синхронизации готового кода с блок схемами.
Только смысл не в таскании объектов по экрану для создания красивых схем, а в вводе только действительно необходимой инфы.
Здравствуйте, DarkGray, Вы писали:
DG>и покажи полный код, например, для: DG> получения дерева директорий и файлов, DG> подсчета размера файлов в поддиректории рекурсивно
Проблема здесь чисто логическая, как обрабатывать ошибки таким образом, чтобы несмотря на ошибки состояние оставалось корректным. Это, да, сложно, т.к. в разных задачах разное понимание корректного состояния, т.е. для каждой задачи нужно думать отдельно.
Здравствуйте, lseder, Вы писали:
L>Задача построить контекстный конструктор кода. L>Конструктор — потому что выбор доступных конструкций из списка. L> Ввод с клавиатуры только необходимой информации — имена переменных, процедур, параметров... L>Контекстный — потому что при выборе элемента дерева — показываются только доступные для вставки элементы. L> Тем самым соблюдается принцип видимого интерфейса, все что можно сделать — есть в списке. L>Кода — результатом будет программа.
Это MPS.
Или я что-то не понял?
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
WH>Это MPS.
Похоже зря я упомянул об мета программировании.
Идея та же, только акцент на более простом использовании в режиме юзера,
который только собирает из блоков код.