Как известно, существует три вида алгоритмов: линейные, разветвленные и циклические:

image

Основой всего, что сделано в методологии программирования, включая и объектное программирование стало структурное программирование, предложенное Эдсгером Дейкстрой в 1970-х годах. Одной из основных идей было введение блочных операторов ветвления (IF, THEN, ELSE) и цикличности (WHILE, FOR, DO, UNTIL и др.) вместо проблемного оператора GOTO, который приводил к получению запутанного, неудобочитаемого «спагетти-кода».

Для использования в интеллектуальных системах структурное программирование обладает серьезным недостатком. Любая интеллектуальная система подразумевает наличие процесса обучения — изменения своего поведения посредством обучения с учителем, или по мере накопления опыта на основе собственных наблюдений. Такое изменение поведения должно выполнятся специальными средствами метапрограммирования и в конечном счете приводит к внесению изменений в исходный код интеллектуальной программы. Недостаток блочной парадигмы структурного программирования заключается в возможности неограниченной вложенности одних блоков в другие. Необдуманное исправление кода одного блока может повлечь некорректную работу вложенных блоков, а иногда и блоков уровнями выше. Такое внесение изменений в исходный код требует наличия специально подготовленного человека (разработчика программного обеспечения), который перед внесением изменений обязан изучить не только блок кода, предназначенный для исправления, но и вложенные, а так же смежные с ним блоки.

Особую сложность создает «строкозависимость» структурного подхода к программированию. Другими словами, изменение значения определенной переменной необходимо производить в определенной строке кода, поскольку значение этой переменной может быть связано со значениями других переменных. Таким образом, неправильный выбор строки может привести к критическим ошибкам, которые, к тому же, могут носить несистемный характер и быть труднообнаруживаемыми.

Все это создает определенные трудности для внесения изменений в исходный код программы неподготовленным человеком и делает практически невозможным изменение программой самой себя.

В парадигме ситуационно-ориентированного программирования сделана попытка ухода от использования алгоритмов ветвления и циклов непосредственно в исходном коде. Вместо этого, второй и третий виды алгоритмов вынесены в отдельный механизм описания ситуаций. Исходный код, таким образом, представляет собой только линейный алгоритм. Процедура разработки программного кода сводится к объявлению набора ситуаций и назначению обработчика для каждой из них.

Ситуация представляет собой аналог условного выражения из алгоритма ветвления или цикла. Ситуация однозначно описывает состояние значений переменных программы. Как только все описанные в ситуации переменные принимают указанные значения, обработчик ситуации получает управление и выполняется его исходный код. Обработчик ситуации представляет собой линейный алгоритм из очень небольшого количества инструкций.

Такой подход позволяет выполнять изменение обработчика определенной ситуации независимо от остального кода. При этом не нужно заниматься поиском подходящего места для изменения переменной. Система сама заботится об этом при помощи специального механизма приоритетов выполнения. Это означает, что из двух обработчиков сначала будет вызван тот, в котором значение переменной изменяется, после чего будет вызван обработчик, в котором значение этой переменной используется.

Отличие сутуационно-ориентированного подхода от блочного можно рассмотреть на примере. Допустим, имеется программа на языке Си, которая удаляет все вхождения символа «C» из исходной строки «ABCABCABC» и печатает результат. Исходный код такой программы будет выглядеть примерно следующим образом:

image

Результатом работы такой программы станет строка:
ABABAB


Ситуационно-ориентированная программа на условном алгоритмическом языке будет выглядеть иначе:

image

При запуске программы на выполнение произойдет следующее. Изначальное значение переменной i не определено, после присваивания переменной i нулевого значения сработает ситуация S2, так как она срабатывает при каждом изменении значения переменной i, а также при истинности условия s[i]!=c. Поскольку s[0]=='A', то условие s[i]!=c для первого символа строки является истинным. При вызове обработчика ситуации S2 выполнятся инструкции:

s[j]=s[i];
j=j+1;

После завершения обработчика ситуации S2 будет вызван обработчик ситуации S1, так как она также срабатывает при каждом изменении значения переменной i. Обработчик S1 увеличит значение переменной i на единицу:
i=i+1;

В следствии очередного увеличения значения переменной i произойдет новая итерация вызовов обработчиков ситуаций S2 и S1. Так будет происходить до перебора всех символов строки s. В случае, когда очередной символ s[i] будет равен «C», вызов обработчика S2 производится не будет, поскольку условие s[i]!=c будет ложным.

После того, как все символы входной строки s будут обработаны и программа встретит символ завершения строки '\0', будет вызван обработчик ситуации S3. Ситуация S3 срабатывает каждый раз, когда условие s[i]=='\0' истинно. В результате вызова обработчика ситуации S3 будут выполнены следующие инструкции:
Удалить ситуацию S1;
s[j]='\0';
printf ("%s\n", s);

Таким образом, вызов обработчика ситуации S3 удалит ситуацию S1. Обработчик ситуации S1 перестанет вызываться, а значение переменной перестанет постоянно увеличиваться на единицу. Программа выйдет из циклического состояния и завершит выполнение. Результат работы будет такой же, как у программы на языке Си, а именно, вывод строки «ABABAB» на экран.

Теперь, допустим, появилась необходимость доработать обе программы таким образом, чтобы первое вхождение символа 'C' не удалялось из строки s. То есть результатом работы программ должна быть строка «ABCABAB».

Доработка программы на Си заключается в объявлении переменной k — счетчика вхождений символа 'С' в строку s, а также в добавлении инструкции копирования символа в выходную строку, при условии, что k==1:

image

Основная сложность такой доработки состоит во все той же строковой зависимости инструкций, которой обладает структурный подход. Во-первых, дополнительное условие if (s[i]==c) нельзя добавить в произвольное место программы, а только внутрь цикла FOR. Будь программа немного сложнее, то и этого было бы недостаточно. То есть условие нужно было бы добавлять не в любое место цикла FOR, а только в определенную его строку. Во-вторых, поскольку внутри цикла FOR теперь большее одной инструкции, его нужно дополнить фигурными скобками. В-третьих, порядок добавляемых инструкций

k++;
if (k==1) s[j++]=s[i];


не является произвольным. Их перестановка приведет к некорректному поведению программы. Такая взаимная зависимость инструкций заставляет уделять большое время поиску подходящего места для вставки инструкции, создает дополнительные трудности для неспециалиста и усложняет процесс автоматизированного изменения кода.

Получив задачу доработать программу, человек, не являющийся разработчиком ПО, рассуждал бы так:

  1. В ситуации, когда во входной строке встречается символ «C», необходимо увеличивать на единицу счетчик вхождений символа 'C' в строку s.
  2. В ситуации, когда во входной строке символ 'C' встречается первый раз, необходимо скопировать символ из входной строки в выходную.

Таким образом, имеем две дополнительных ситуации, для которых нужно предусмотреть два обработчика. Доработанная программа на основе ситуационно-ориентированной парадигмы будет выглядеть следующим образом:

image

Резюмируя вышесказанное, ситуационно-ориентированный подход:

  • избавляет от изучения смежных блоков кода
  • делает исходный код менее строкозависимым
  • выносит ветвление и цикличность за рамки кода, оставляя только простой линейный алгоритм
  • допускает изменение исходного кода непосредственно в момент выполнения программы
  • делает разработку кода более похожей на процесс мышления человека, что может снизить требуемый уровень подготовки разработчика
  • потенциально может упростить процесс автоматизированного изменения поведения программ

Комментарии (170)


  1. lair
    14.09.2015 15:31
    +4

    Как найти все обработчики, которые зависят от значения переменной x?

    (но вообще, конечно, событийно-ориентированное программирование в полный рост)


    1. rimsleur
      14.09.2015 16:21
      -1

      В момент первоначальной загрузки обработчика в память. Можно анализировать его код и выставить приоритеты всем обработчикам. Но работоспособность такого подхода еще предстоит доказать.


      1. lair
        14.09.2015 16:22
        +2

        В момент первоначальной загрузки обработчика в память.

        Я про момент работы с кодом (т.е., разработку), а не рантайм.


      1. lair
        14.09.2015 16:25
        +1

        Можно анализировать его код и выставить приоритеты всем обработчикам.

        и еще
        Система сама заботится об этом при помощи специального механизма приоритетов выполнения. Это означает, что из двух обработчиков сначала будет вызван тот, в котором значение переменной изменяется, после чего будет вызван обработчик, в котором значение этой переменной используется.

        А это точно не SAT problem?


        1. rimsleur
          14.09.2015 17:09

          Не знаком с такой, посмотрю.


  1. rimsleur
    14.09.2015 16:45

    Хороший вопрос. В статье я действительно это не описал, чтобы не усложнять.
    Ситуация это обертка для одного или нескольких событий. Одно событие только на одну переменную. Типов событий два:
    1. На изменение значения переменной
    2. На конкретное значение переменной.
    Такой пример:
    Есть переменные X=0, Y=0, Z=0. Создаем: событие E1 для X=2, событие E2 для Y=3, событие E3 для изменения значения переменной Z. Создаем ситуацию S1, которая объединяет в себе все три события E1, E2 и E3.
    Теперь, в момент выполнения программы, переменной Y присваиваем значение 3. Срабатывает событие E2, но поскольку оно задействовано в ситуации S1, то в данных ситуации делается пометка, что E2 активировалось.
    Далее присваиваем переменной X значение 2. Срабатывает событие E1 и делается пометка в S1. Но сама ситуация S1 пока не сработала, т.к. не активировалось событие E3
    Изменение значения переменной Z с нулевого на любое другое вызовет активацию события E3, что в свою очередь уже активирует ситуацию S1 и вызовет ее обработчик.
    По поводу Вашего вопроса: в каждом событии указано для какой переменной оно создано, а в каждой ситуации указано какие события в ней задействованы.


    1. lair
      14.09.2015 16:54

      Хороший вопрос. В статье я действительно это не описал, чтобы не усложнять.

      Какой именно?

      По поводу Вашего вопроса: в каждом событии указано для какой переменной оно создано, а в каждой ситуации указано какие события в ней задействованы.

      Как, имея под курсором переменную, узнать, какой обработчик(-и) будет вызван, когда значение этой переменной изменится с 2 на 3?


      1. rimsleur
        14.09.2015 17:08

        Какой именно?

        Этот: Я про момент работы с кодом (т.е., разработку), а не рантайм.

        Как, имея под курсором переменную, узнать, какой обработчик(-и) будет вызван, когда значение этой переменной изменится с 2 на 3?

        По ключу, состоящему из имени переменной + ее значения (это предварительно) находим соответствующее событие для данной переменной и ее значения 3. Т.е. ключ такой 'имя_переменной=3'. По идентификатору события просматриваем все ситуации, к которым оно привязано.


        1. lair
          14.09.2015 17:10

          По ключу, состоящему из имени переменной + ее значения (это предварительно) находим соответствующее событие для данной переменной и ее значения 3. Т.е. ключ такой 'имя_переменной=3'. По идентификатору события просматриваем все ситуации, к которым оно привязано.

          Угу, теперь представьте, что у вас число «переменных» измеряется тысячами, а значений — доменом значений (а их, скажем, у строк — больше, чем мы можем разумно держать в памяти). Насколько просто будет анализировать, что именно происходит в программе и в каком порядке?


          1. Rigidus
            14.09.2015 18:47

            Без проблем — сохраняем «переменные» в реляционной бд, а дальше по индексам.

            Я бы несколько расширил «переменные» таким образом, чтобы существовали «ситуации» и «условия срабатывания». Применяя одно к другому можно было бы генерировать «побочные эффекты» и вызывать срабатывание других «ситуаций».

            Сверху на это можно накладывать «советы» и все прочее, что есть в аспектно-ориентированном программировании.

            Таким образом можно сформировать структуру программы (например, внутри БД) и по ней уже сгенерировать низкоуровневый код, если важна производительность. Отдельные «ситуации», «побочные эффекты» и прочие классы компонентов могут быть реализованы на различных языках при необходимости. Например ситуация, возникшая в веб-клиенте могла бы иницировать транзакцию на сервере итп.

            С точки зрения процесса разработки можно обязать документировать «ситуации» в литературном стиле (или хотя бы аннотировать побочные эффекты и писать описания ситуаций) и получить управление сложностью программы существенно лучше чем в среднем по индустрии.

            Если говорить о расширяемости (патчи, замена и исправление функциональности) то отдельные «ситуации» и «условия» могут быть перегружены (в смысле override) в ответ на issue в баг-трекере — это уже следующий уровень управления версиями после VCS типа git

            В общем, перспективно выглядит. Я бы присмотрелся, и даже попытался взять на вооружение


            1. lair
              14.09.2015 18:50
              +1

              Без проблем — сохраняем «переменные» в реляционной бд, а дальше по индексам.

              Что «по индексам»? Как вы себе представляете такой анализ?

              С точки зрения процесса разработки можно обязать документировать «ситуации» в литературном стиле (или хотя бы аннотировать побочные эффекты и писать описания ситуаций) и получить управление сложностью программы существенно лучше чем в среднем по индустрии.

              За счет чего управление сложностью будет лучше?


              1. Rigidus
                14.09.2015 19:04

                Нужен наверно какой-то модельный пример.

                Представим себе, что мы делаем банк-клиент в вебе. Тогда у нас будут такие «ситуации»:

                — Отображать в веб-клиенте кол-во денег на счете. Если оно изменилось — перерисовать кол-во денег
                — Дать возможность клиенту иницировать в веб-клиенте перевод
                — На сервере асинхронно запустить перевод («условие» — авторизованный клиент пытается совершить перевод". Перевод — это отправка асинхронного запроса в стороннюю систему. Внутри этого «события» мы помним номер запроса"
                — Сообщить об ошибке, если («условие») сторонняя система вернула отказ в денежном переводе. Для этого возможно нужно найти событие, которое помнит номер запроса
                — Если (условие) сторонняя система успешно перевела деньги — изменить кол-во денег на счете клиента

                Такие подкейсы легко программировать по частям, минимизируя разделямое общее состояние. И патчить тоже удобно — патч — это замена группы «ситуаций», с мотивированным описанием патча.

                Управление сложностью становится простым за счет того что мы можем читая описание «ситуаций» явно видеть их взаимосвязь. Можно еще запретить доступ к состоянию сторонних «ситуаций» без явного объявления в аннотоциях, если хочется оградить программиста от неосторожных шагов


                1. lair
                  14.09.2015 19:13
                  +1

                  Тогда у нас будут такие «ситуации»:

                  Это не ситуации, а требования.

                  Разберем пошагово.

                  Отображать в веб-клиенте кол-во денег на счете. Если оно изменилось — перерисовать кол-во денег

                  Что здесь переменная, что — ситуация, а что — обработчик?

                  Дать возможность клиенту иницировать в веб-клиенте перевод

                  Это вообще не ситуация.

                  На сервере асинхронно запустить перевод («условие» — авторизованный клиент пытается совершить перевод". Перевод — это отправка асинхронного запроса в стороннюю систему. Внутри этого «события» мы помним номер запроса"

                  Опять-таки, что здесь переменная, а что — обработчик?

                  Сообщить об ошибке, если («условие») сторонняя система вернула отказ в денежном переводе. Для этого возможно нужно найти событие, которое помнит номер запроса

                  Сообщить кому? Как узнать, что был отказ?

                  Если (условие) сторонняя система успешно перевела деньги — изменить кол-во денег на счете клиента

                  Как определить, что сторонняя система успешно перевела деньги? И, если вы изменяете количество денег на счете, то как вы ограждаете себя от конфликтов со множественными изменениями на одном и том же счете?

                  При этом, заметим, все, что вы описали (как требования), без единой проблемы и противоречия реализуется в actor-based-системе навроде akka, причем для этой реализации не потребуется никакого общего состояния вообще.

                  Управление сложностью становится простым за счет того что мы можем читая описание «ситуаций» явно видеть их взаимосвязь.

                  Читая головой, или читая программным анализатором?


                  1. Rigidus
                    14.09.2015 19:22

                    Редактируется…

                    01. Объявить переменную «количество денег на счете» внутри домена «текущий пользователь»
                    02. Объявить условие «изменение количества денег на счете» для ref:01
                    03. Обявить «побочный эффект» — перерисовать кол-во денег в интерфейсе пользователя, срабатывающий при активации условия «изменилось кол-во денег на счете»
                    — Отображать в веб-клиенте кол-во денег на счете. Если оно изменилось — перерисовать кол-во денег
                    — Дать возможность клиенту иницировать в веб-клиенте перевод
                    — На сервере асинхронно запустить перевод («условие» — авторизованный клиент пытается совершить перевод". Перевод — это отправка асинхронного запроса в стороннюю систему. Внутри этого «события» мы помним номер запроса"
                    — Сообщить об ошибке, если («условие») сторонняя система вернула отказ в денежном переводе. Для этого возможно нужно найти событие, которое помнит номер запроса
                    — Если (условие) сторонняя система успешно перевела деньги — изменить кол-во денег на счете клиента


                    1. lair
                      14.09.2015 19:33

                      Даже если рассмотреть только этот пример, то:

                      • Что такое «текущий» пользователь?
                      • На основании чего меняется переменная внутри этого домена?


                      1. Rigidus
                        14.09.2015 19:39

                        >> Что такое «текущий» пользователь?

                        $_SESSION[current_user]

                        >> На основании чего меняется переменная внутри этого домена?

                        Она меняется внутри «ситуаций», в которых явно аннотирование изменение этой переменной. А ситуации вызываются диспетчером при срабатывании их условий. Так что можно сказать, что эта переменная меняется на основании срабатывания условий тех ситуаций, которые явно могут менять эту переменную


                  1. Rigidus
                    14.09.2015 19:35

                    Не смог успеть до окончания времени редактирования прошлого комментария…

                    01. Объявить переменную «количество денег на счете» внутри домена «текущий пользователь»
                    02. Объявить условие «изменение количества денег на счете» для ref:01
                    03. Обявить ситуацию — обновление кол-ва денег в интерфейсе пользователя, срабатывающий при активации условия «изменилось кол-во денег на счете»
                    04. Объявить ситуацию «отображение интерфейса денежного перевода», срабатывающий при активации условия «отображение страницы банк-клиента». В интерфейсе аннотировать запуск ситуации перевода средств (когда пользователь нажимает кнопку «выполнить перевод»)
                    05. Объявить ситуацию «перевод средств», храняющую состояние (текущий пользователь, дата/время, сумма, код завершения, размер тайм-аута, ...). Инициализировать ситуацию при срабатывании условия «получен запрос на перевод средств» ref:04, отправить асинхронный запрос в стороннюю систему на совершение перевода
                    06. Объявить ситуацию «отказ в переводе», срабатывающую при наступлении условия «получен отрицательный ответ от сторонней системы», отобразить сообщение об отказе пользовалею
                    07. Объявить ситуацию «успешный перевод» срабатывающую при наступлении условия «получен положительный ответ от сторонней системы», изменить кол-во денег на счете, что вызовет срабатывание условия ref:02

                    >>>> Управление сложностью становится простым за счет того что мы можем читая описание «ситуаций» явно видеть их взаимосвязь.

                    >> Читая головой, или читая программным анализатором?

                    И анализатором тоже


                    1. lair
                      14.09.2015 21:36
                      +1

                      01. Объявить переменную «количество денег на счете» внутри домена «текущий пользователь»

                      Сюда же допишем из соседнего комментария:
                      «текущий» пользователь — $_SESSION[current_user]
                      [...]
                      Она [эта переменная] меняется внутри «ситуаций», в которых явно аннотирование изменение этой переменной.


                      А теперь обратите внимание, что эта переменная живет только до тех пор, пока у вас есть сессия. Нет сессии — нет переменной. Нет переменной — нет денег на счету. Правда, здорово?

                      02. Объявить условие «изменение количества денег на счете» для ref:01
                      03. Обявить ситуацию — обновление кол-ва денег в интерфейсе пользователя, срабатывающий при активации условия «изменилось кол-во денег на счете»

                      И зачем вам это все счастье, когда есть простой датабиндинг?

                      05. Объявить ситуацию «перевод средств», храняющую состояние (текущий пользователь, дата/время, сумма, код завершения, размер тайм-аута, ...).

                      Видите? У вас ситуация стала состоянием. Была событием (как мы обсуждали в соседних комментариях), а стала состоянием.

                      06. Объявить ситуацию «отказ в переводе», срабатывающую при наступлении условия «получен отрицательный ответ от сторонней системы», отобразить сообщение об отказе пользовалею
                      07. Объявить ситуацию «успешный перевод» срабатывающую при наступлении условия «получен положительный ответ от сторонней системы», изменить кол-во денег на счете, что вызовет срабатывание условия ref:02

                      И как вы свяжете эту ситуации с предыдущей (05)?

                      Что интереснее — на каком счете вы будете менять количество денег? А что, если у вас в момент изменения количества денег произойдет ошибка?


  1. rimsleur
    14.09.2015 17:47
    +1

    Это первая статья, далее я хотел бы объединить этот подход с некоторым другим, что может позволить (в теории) не смотреть в код, а объяснять машине что и когда делать. А именно к описанному ситуационно-ориентированному подходу лучше относиться не как к замене ООП, а как к возможной альтернативе для узкого круга задач (предположительно в интеллектуальных системах).
    Действительно, для задач сравнения длинных строк такая реализация не подойдет. Но если взять например переводчик, который должен перевести предложение, то значениями переменных могут быть токены (слова). Допустим для каждой части предложения (главный глагол, актор, актант и все их валентности) будет предусмотрена своя переменная, то их будет не так и много.


    1. lair
      14.09.2015 18:13

      что может позволить (в теории) не смотреть в код, а объяснять машине что и когда делать.

      Любой код — это объяснение машине, что и когда делать. И эти объяснения вам надо поддерживать. Ваши «переменные», по факту, глобальны, что нарушает принцип information hiding.

      Допустим для каждой части предложения (главный глагол, актор, актант и все их валентности) будет предусмотрена своя переменная, то их будет не так и много.

      Угу, а еще контексты, значения соседних предложений, и далее по тексту. И это не считая того, что сами значения у вас все равно из словарного домена, т.е. их десятки тысяч.


      1. rimsleur
        14.09.2015 18:23

        Проблема с глобальной видимостью есть. Надо будет думать, что с ней делать.
        Событий и ситуаций действительно будет очень много. Но к ним можно получать доступ ассоциативно. Т.е. перед изменением ситуации ее нужно будет выбрать, указав условия ее срабатывания. На первый взгляд это может показаться минусом, но это не так.


        1. lair
          14.09.2015 18:26
          +1

          Вы, похоже, не понимаете проблемы.

          Основной вопрос в поддержке крупного программного проекта — это «что изменится, если я изменю этот код». Структурное программирование во всех его вариантах борется с этой проблемой уменьшением видимости. А вы?


          1. rimsleur
            14.09.2015 18:29

            Почему, понимаю. Инкапсуляции нет. Но это не значит, что проблема нерешаема совсем.


            1. lair
              14.09.2015 18:30

              Как вы предлагаете ее решать?


              1. rimsleur
                14.09.2015 18:38

                Пока трудно сказать. Возможно введением возможности объединения их в структуры, а также при объявлении указывать глобальная, или локальная для процедуры.


                1. lair
                  14.09.2015 18:40

                  Но вы понимате, что пока эта проблема не решена, ни о каком упрощении процесса разработки речи идти не может?

                  (более того, вы не уменьшаете, а увеличиваете количество кода, которое необходимо прочесть для понимания работы программы)


                  1. rimsleur
                    14.09.2015 18:47

                    Да, конечно


                  1. Rigidus
                    14.09.2015 18:50
                    +1

                    Никто не мешает продолжать бороться с проблемой «что изменится, если я изменю этот код» и в рамках этого подхода.

                    На самом деле будет даже проще, т.к. связи между «ситуациями» и их «обработчиками» становятся явными


                    1. lair
                      14.09.2015 18:53
                      +1

                      Проще по сравнению с чем? Почему в этом подходе связи явные, а в том, в котором вы сравниваете — нет?


                      1. rimsleur
                        14.09.2015 19:04

                        Они как бы более понятны для человека. Набор событий (если упаковать их в ситуацию) можно рассмотривать как одну неделимую сущность, которой проще оперировать в уме.


                        1. lair
                          14.09.2015 19:15

                          Набор событий по определению не может быть неделимой сущностью, события же автономны.

                          Приведите пример хотя бы одной реальной «ситуации», которую вы бы легко и понятно собрали из отдельных «событий»?


                          1. rimsleur
                            14.09.2015 19:32

                            Они вроде и сами по себе, но у нас в голове это одна сущность.
                            С примером не проблема. Дело в том что все вокруг работает по этому принципу.
                            Рассмотрим ситуацию, когда игрока учат играть в карты и говорят ему: «В игре „Дурак“, когда противник походил мастью, которой у тебя нет, ты должен бить козырем» Это целая сложная ситуация, которая внутри машины будет распределена на несколько переменных и их состояний. Так, например понадобится переменная, указывающая что система вовлечена в игровой процесс, следующая переменная будет содержать вид игры — карточный, следующая будет содержать название игры — «в дурака», следующая будет содержать номер игрока который последним совершил ход, следующая будет содержать масть карты, которая остается не побитой…


                            1. lair
                              14.09.2015 19:34

                              А ничего, что у вас только одно событие — ход противника (карта), а все остальное — это состояние системы?

                              Не надо путать события и состояния.


                              1. rimsleur
                                14.09.2015 19:38
                                +1

                                Я понял, в чем недопонимание :)
                                Действительно, с точки зрения ООП событие выстреливает, запускается его обработчик и все. Тут не так. Эти события остаются активными, пока не изменится содержимое соответствующей переменной. Для программиста это больше состояние, чем событие


                                1. lair
                                  14.09.2015 21:41

                                  Ага, то есть это не событие, а состояния. Но если это состояния, то вы немедленно получаете все проблемы stateful-систем.

                                  Во-первых, не всякое состояние дискретно. Положение машины, движущейся по дороге, меняется ровно с частотой дискретизации датчиков, и это делает неработоспособным концепцию «событие остается активным, пока».

                                  Во-вторых, у вас начинаются конкурентные гонки. Вот у вас есть две «ситуации» с условием «сумма на счету превысила сто рублей» (типичный отложенный платеж). Они обрабатываются параллельно или последовательно?

                                  Если последовательно, то как вы гарантируете последовательность — у вас же много факторов состояния, вам надо либо делать всю систему строго последовательной (прощай, производительность и масштабируемость), либо изолировать те состояния, к которым осуществляется доступ из более чем одной ситуации (и, заметим, вам надо отслеживать не только условия, но и обработчики).

                                  А если параллельно, то у вас банальная гонка — два списания на 75 рублей при балансе в 100 дадут ошибку.


                                  1. rimsleur
                                    14.09.2015 21:57

                                    Для встроенных систем такой подход не самое лучшее решение из-за быстродействия. Возможно сигналы от датчика будет обрабатывать промежуточный микроконтроллер, который уже будет подавать сигнал «наверх». В таком случае машина будет продолжать движение, пока не встретилась преграда, срабатывает ситуация и машина либо пытается объехать препятствие, либо остановиться.

                                    Параллельно две ситуации «сумма на счету превысила сто рублей» возникнуть не могут. Мы загружаем проводки из файла последовательно, запись за записью. Для каждой строки в процессе ее обработки может взвестись флажок и включиться соответствующий обработчик.


                                    1. lair
                                      14.09.2015 22:01

                                      В таком случае машина будет продолжать движение, пока не встретилась преграда, срабатывает ситуация и машина либо пытается объехать препятствие, либо остановиться.

                                      Что такое «встретилась преграда»? Событие? Состояние?

                                      Возможно сигналы от датчика будет обрабатывать промежуточный микроконтроллер, который уже будет подавать сигнал «наверх».

                                      А код для микроконтроллера откуда берется? Кто определяет логику преобразования информации из датчика в состояния?

                                      Параллельно две ситуации «сумма на счету превысила сто рублей» возникнуть не могут. Мы загружаем проводки из файла последовательно, запись за записью.

                                      А при чем тут вообще загрузка проводок из файла? У вас честный онлайн, операции идут сервисами.

                                      Ну и да, то, что вы описываете — это полностью последовательная система, со всеми описанными недостатками.


                                      1. rimsleur
                                        14.09.2015 22:34
                                        +1

                                        Что такое «встретилась преграда»? Событие? Состояние?

                                        Давайте рассмотрим ситуацию, более подробно. Имеет ли смысл машине задействовать тормоз, если двигатель выключен, но перед ней появился пешеход? Нет.
                                        Имеет ли смысл машине задействовать тормоз, если двигатель включен, но коробка в режиме нейтрали или паркинга, хотя опять же перед ней появился пешеход? Нет. Значит ситуация, при которой нужно останавливается актуальна только тогда, когда двигатель работает, и передача включена. Стало быть у нас есть переменная на Вкл./Выкл двигателя и переменная на номер текущей передачи, ну и конечно переменная отражающая наличие препятствия на дороге. У нас есть 3 события на каждую их переменных. Первое событие на то что двигатель включен, второе, на то что включена соответствуяющая передача. И последнее событие на наличие помехи спереди. На основе 3х событий создаем ситуацию.
                                        Теперь. Робот включает двигатель, срабатывает первое событие. Оно превращается в состояние. Т.е. это флажок и он будет взведен, пока робот не выключит двигатель. После включения двигателся робот включает первую передачу и начинает движение. Срабатывает второе событие и переводится в режим состояния. Но ситуация вызваться не может, т.к. остается неактивированным последнее событие. Имеем 2 активированных события и одно неактивное. Если сейчас выключить двигатель, то деактивируется первое событие, а для того, чтобы сработала ситуация и выполнился ее обработчик должны быть одновременно активными все события, привязанные к ситуации.


                                        1. lair
                                          14.09.2015 22:41
                                          +1

                                          Имеет ли смысл машине задействовать тормоз, если двигатель выключен, но перед ней появился пешеход? Нет.

                                          Да, потому что включенный двигатель не является единственным способом движения машины.

                                          Имеет ли смысл машине задействовать тормоз, если двигатель включен, но коробка в режиме нейтрали или паркинга, хотя опять же перед ней появился пешеход? Нет.

                                          См. выше.

                                          Значит ситуация, при которой нужно останавливается актуальна только тогда, когда двигатель работает, и передача включена.

                                          Нет, но для упрощения будем рассматривать ее.

                                          переменная отражающая наличие препятствия на дороге.

                                          Вот, прекрасно, откуда вы ее возьмете?

                                          Робот включает двигатель, срабатывает первое событие. Оно превращается в состояние. Т.е. это флажок и он будет взведен, пока робот не выключит двигатель. После включения двигателся робот включает первую передачу и начинает движение. Срабатывает второе событие и переводится в режим состояния. Но ситуация вызваться не может, т.к. остается неактивированным последнее событие. Имеем 2 активированных события и одно неактивное. Если сейчас выключить двигатель, то деактивируется первое событие, а для того, чтобы сработала ситуация и выполнился ее обработчик должны быть одновременно активными все события, привязанные к ситуации.

                                          Угу. И все это вместо «перед нами есть препятствие — если машина движется — прекратить движение» (маневры уклонения я не рассматриваю). В чем выгода?

                                          Ну и самое главное. Пока вы работаете с состояниями — вы вынуждены разделять состояния между обработчиками. Как вы будете разрешать возникающие коллизии? Полной сериализацией? Грубо говоря, может ли что-то выключить двигатель в тот момент, пока ваш обработчик нажимает на тормоз?


                                          1. rimsleur
                                            14.09.2015 22:50

                                            Нет, но для упрощения будем рассматривать ее.
                                            Предполагается что перед выключением двигателя робот переключил трансмиссию в паркинг и колеса блокированы. Ну можно еще показания спидометра анализировать.
                                            Вот, прекрасно, откуда вы ее возьмете?
                                            Да хоть аппаратным прерыванием. Это не важно.
                                            В чем выгода?
                                            Тут ее либо сразу видишь, либо нет.
                                            Ну и самое главное. Пока вы работаете с состояниями — вы вынуждены разделять состояния между обработчиками. Как вы будете разрешать возникающие коллизии?
                                            Тут не уловил, какие коллизии?


                                            1. lair
                                              14.09.2015 22:52
                                              +1

                                              Тут ее либо сразу видишь, либо нет.

                                              Плохой аргумент. Я точно так же могу сказать, что ошибки в вашем подходе «либо видишь сразу, либо нет».

                                              Тут не уловил, какие коллизии?

                                              Еще раз: в предлагаемой вами системе обработчики выполняются последовательно или параллельно?


                                              1. rimsleur
                                                14.09.2015 22:57

                                                Конечно я не все вижу, но объяснить плюсы тоже не могу. Есть альтернатива, это пока все.
                                                А, только последовательно. Они могут друг от друга зависеть.


                                                1. lair
                                                  14.09.2015 22:59
                                                  +1

                                                  объяснить плюсы тоже не могу.

                                                  Это странно. Пример-то тривиальный.

                                                  А, только последовательно. Они могут друг от друга зависеть.

                                                  Сразу возникает два вопроса.

                                                  1. Как вы будете определять порядок выполнения?
                                                  2. Что вы будете делать в многопользовательских системах (да даже в однопользовательских ничего не менятся, все современное программирование в той или иной мере асинхронно)?


                                                  1. rimsleur
                                                    14.09.2015 23:21

                                                    С первого вопроса начиналась наша дисуссия. Планирую определять порядок выполнения приоритетами. В момент начальной загрузки каждого обработчика в нем проверяются зависимости и выставляется приоритет. Это пока первый приоритет.
                                                    По второму вопросу не ясно, блокировки на переменные может какие-то.


                                                    1. lair
                                                      14.09.2015 23:39
                                                      +1

                                                      С первого вопроса начиналась наша дисуссия. Планирую определять порядок выполнения приоритетами. В момент начальной загрузки каждого обработчика в нем проверяются зависимости и выставляется приоритет. Это пока первый приоритет.

                                                      Вы представляете себе алгоритмическую сложность решения такой задачи? По идее, конечно, это обычная топологическая сортировка с выявлением колец, но мне почему-то кажется, что наличие условий либо сделает этот граф гигантским (а там все-таки NC2), либо переведет в другой класс.

                                                      По второму вопросу не ясно, блокировки на переменные может какие-то.

                                                      Во-первых, «блокировки на переменные» вам не нужны: если вы сказали, что у вас обработчики выполняются только последовательно, у вас никогда не будет одновременного обращения.
                                                      А во-вторых, именно поэтому они ничего не изменят. Непараллелизуемая система (а вы предлагаете именно такую) в наше время применима к очень узкому кругу задач.

                                                      Кстати, а для каких задач оправдан ваш подход, по-вашему?


                                                      1. rimsleur
                                                        14.09.2015 23:57

                                                        Вы представляете себе алгоритмическую сложность решения такой задачи? По идее, конечно, это обычная топологическая сортировка с выявлением колец, но мне почему-то кажется, что наличие условий либо сделает этот граф гигантским (а там все-таки NC2), либо переведет в другой класс.
                                                        Потому тогда вначале и написал, что работоспособность такого подхода еще предстоит доказать.
                                                        Во-первых, «блокировки на переменные» вам не нужны: если вы сказали, что у вас обработчики выполняются только последовательно, у вас никогда не будет одновременного обращения.
                                                        Теоретически, могут быть обращения из других потоков, между вызовами обработчиков в текущем потоке. Но это потом, не заморачиваюсь я сейчас темой параллелизма.

                                                        Кстати, а для каких задач оправдан ваш подход, по-вашему?

                                                        Не хотелось бы чтобы ответ получился вырванным из контекста. Я хочу проверить это на базе знаний со встроенным языком. Т.е. когда запрос к базе знаний создается на естественном языке и база знаний отвечает. Так вот лингвистический процессор возможно сможет работать на таком подходе. Тогда в него можно будет добавлять новые возможности (разбор более сложных форм вопросов) без непосредственного вмешательства в код. Можно будет на естественном языке описывать ситуацию и как нужно действовать, когда она наступит.


                                                        1. lair
                                                          15.09.2015 00:01

                                                          Теоретически, могут быть обращения из других потоков, между вызовами обработчиков в текущем потоке.

                                                          Если обработчики выполняются последовательно, то не важно, из каких потоков.

                                                          Так вот лингвистический процессор возможно сможет работать на таком подходе.

                                                          Что вы понимаете под лингвистическим процессором? Разбор фразы?

                                                          Можно будет на естественном языке описывать ситуацию и как нужно действовать, когда она наступит.

                                                          Описать ситуацию на естественном языке — это одно дело. А среагировать на нее — это другое дело.

                                                          Предположим, ситуация описана (не важно, естественным языком, или DSL). Какую функцию будет выполнять сама система, которая эти ситуации обрабатывает и реагирует на них?


                                                          1. rimsleur
                                                            15.09.2015 00:10

                                                            Если обработчики выполняются последовательно, то не важно, из каких потоков.
                                                            В одном потоке точно будут выполняться только последовательно, но для разных пока не регламентировано.

                                                            Что вы понимаете под лингвистическим процессором? Разбор фразы?
                                                            Да, разбор вопроса и поиск ответа.

                                                            Описать ситуацию на естественном языке — это одно дело. А среагировать на нее — это другое дело.
                                                            Инструкции будут на том же языке. Это как раз второй подход, про который я говорил. Т.е. один язык для обмена информацией и для ее обработки. Эта тема заслуживает отдельной статьи. Подход тоже спорный и также не всем будет понятен.

                                                            Предположим, ситуация описана (не важно, естественным языком, или DSL). Какую функцию будет выполнять сама система, которая эти ситуации обрабатывает и реагирует на них?
                                                            Обработчик будет содержать инструкции на том же языке, которые будут надиктовываться системе через тот же интерфейс, что и запросы к базе данных.


                                                            1. lair
                                                              15.09.2015 00:15

                                                              В одном потоке точно будут выполняться только последовательно, но для разных пока не регламентировано.

                                                              (серьезно?)
                                                              В одном потоке обработчики очевидно выполняются последовательно, тут даже спрашивать ничего не надо. Параллелизм возникает, когда у вас больше одного потока. Окей, выясняется, что вы не думали, как это будет реализовано. Собственно, дальше возвращаемся к вопросу выше: если вы не сериализуете все обработчики, то как вы разрешаете конфликты?

                                                              Например, есть n обработчиков ситуации «баланс счета выше 100». Как обеспечить консистентность их работы?

                                                              (Замечу, что даже в вашем предполагаемом применении без параллелизма не обойтись)

                                                              Да, разбор вопроса и поиск ответа.

                                                              Эта задача вообще не требует «событий» и «ситуаций», она фиксирована и не меняется во времени.

                                                              Обработчик будет содержать инструкции на том же языке, которые будут надиктовываться системе через тот же интерфейс, что и запросы к базе данных.

                                                              Вы не поняли мой вопрос. Я спрашиваю, какие задачи будет решать эта система — проще говоря, зачем она нужна?

                                                              (приведите, что ли, живой пример)


                                                              1. rimsleur
                                                                15.09.2015 00:40

                                                                (серьезно?)
                                                                Да, разве не возможна псевдопараллельность в одном потоке, когда изменениями состояний эмулируется одновременное выполнение нескольких циклов?

                                                                Например, есть n обработчиков ситуации «баланс счета выше 100». Как обеспечить консистентность их работы?
                                                                Не понимаю я этого. N перегруженных обработчиков? Но такого ничего не будет. А если в рантайме, то в единицу времени одни обработчик для текущего обрабатываемого счета. Мы же проводки все равно поодиночке грузим, хоть сервис, хоть что. А если нужно параллельно, то запускаем отдельный процесс и грузим отдельно, экземпляры обработчиков там свои будут.

                                                                (Замечу, что даже в вашем предполагаемом применении без параллелизма не обойтись)
                                                                Пока обходился. Для каждого нового запроса создаю новый поток со своим экземпляром интерпретатора.

                                                                Эта задача вообще не требует «событий» и «ситуаций», она фиксирована и не меняется во времени.
                                                                Это процесс обучения, добавление нового поведения, корректировка уже заложенного поведения.
                                                                Вот сечас более точно сформулировался ответ на ваш вопрос. Этот подход может пригодиться в машинном обучении с учителем (а возможно и без). Когда доступ к коду не обязателен, или отсутствует.

                                                                Вы не поняли мой вопрос. Я спрашиваю, какие задачи будет решать эта система — проще говоря, зачем она нужна?
                                                                Информационно-поисковая система позволяющая точно описывать то, что требуется найти. Не коммерция, чисто исследовательская работа.
                                                                Позвольте и мне задать ворос. Отчего такой интерес? Вы же никаких преимуществ для себя не отметили.


                                                                1. lair
                                                                  15.09.2015 11:04

                                                                  Да, разве не возможна псевдопараллельность в одном потоке, когда изменениями состояний эмулируется одновременное выполнение нескольких циклов?

                                                                  Вы сами ответили на свой вопрос приставкой «псевдо».

                                                                  Не понимаю я этого.

                                                                  Я вижу.

                                                                  А если в рантайме, то в единицу времени одни обработчик для текущего обрабатываемого счета.

                                                                  Как вы это гарантируете? Я еще могу понять — для одного счета, но ведь у вас такие же гонки могут быть за любые данные, которые участвуют в обработчике или условии.

                                                                  Мы же проводки все равно поодиночке грузим, хоть сервис, хоть что.

                                                                  Да нет никакого «грузим проводки», откуда вы его берете?

                                                                  Вот у вас игрушечная платежная система в интернетике. В один и тот же момент (а) пользователь решил перевести деньги на другой счет (б) активировалась запланированная операция и (ц) пришло списание из интернет-магазина. Вот вам три одновременных списания, которые вы либо принудительно сериализуете, либо будете разруливать конфликты.

                                                                  А если нужно параллельно, то запускаем отдельный процесс и грузим отдельно, экземпляры обработчиков там свои будут.

                                                                  Экземпляры обработчиков-то ладно, а что вы с данными будете делать?

                                                                  Это процесс обучения, добавление нового поведения, корректировка уже заложенного поведения.

                                                                  Это не имеет отношения к парсингу текста. Вы постоянно перепрыгиваете из задачи в задачу.

                                                                  Когда доступ к коду не обязателен, или отсутствует.

                                                                  Причем тут вообще доступ к коду? Для систем, изменяющихся в рантайме (как самостоятельно, так и снаружи), есть тысяча и один подход, и они вообще никак не связаны с использованной парадигмой программирования.

                                                                  Информационно-поисковая система позволяющая точно описывать то, что требуется найти.

                                                                  Продолжаю не понимать, откуда у вас там события.

                                                                  Отчего такой интерес? Вы же никаких преимуществ для себя не отметили.

                                                                  Я пытаюсь понять, что на самом деле вы пытаетесь предложить.


                                                                  1. rimsleur
                                                                    15.09.2015 11:48
                                                                    +1

                                                                    Да нет никакого «грузим проводки», откуда вы его берете?
                                                                    Оттуда что разрабатывал и внедрял банковское ПО.

                                                                    Вот у вас игрушечная платежная система в интернетике. В один и тот же момент (а) пользователь решил перевести деньги на другой счет (б) активировалась запланированная операция и (ц) пришло списание из интернет-магазина.
                                                                    Ну а как такие конфликты решаются обычно. При помощи Logical unit of work, или по нашему ранзакциями. Какой платеж первым заблокировал данные, тот и обрабатывается. Остальные лочатся и ждут завершения транзакции. Эти механизмы можно надеть на любую парадигму. Не стоит на них сосредотачиваться.

                                                                    Экземпляры обработчиков-то ладно, а что вы с данными будете делать
                                                                    Ничего не буду делать. В каждом отдельном потоке: ждем, пока остатки на счетах отпустят другие потоки, лочим их, меняем остатки обоих счетов, отпускаем для других потоков.
                                                                    Это не имеет отношения к парсингу текста. Вы постоянно перепрыгиваете из задачи в задачу.
                                                                    Имеет, никто никуда не прыгает. Непосредственно разбор предложения и построение синтаксического дерева это только полдела. Если база знаний содержит даты рождений и может ответить на вопрос «Когда родлися Х?» то не факт, что имея данные об объемах двигателей она сможет ответить на вопрос «Объем двигателя модели Х больше объема двигателя модели Y?» Этот вопрос сравнительного характера, он более сложный, система должна его распознать. Кто будет добавлять возможность отвечать на новые типы вопоросов? Вы ответите — программист, и будете правы. А я отвечу — обычный человек будет это делать, не программист, он даже в код смотреть не будет. И я тоже буду прав. Только этому человеку соответствующий инструмент нужно дать.

                                                                    есть тысяча и один подход,
                                                                    Ок, этот будет тысяча вторым. Я же не говорю, что на нем свет клином сошелся.

                                                                    Продолжаю не понимать, откуда у вас там события.

                                                                    На любые входные данные можно наложить события. А для вычленения определенной совокупности входных данных (конкретный набор слов) эти события можно сложить в ситуацию и и работать как с целым.

                                                                    Пример:
                                                                    Допустим имеем на входе простое предложение из подлежащего (актор) сказуемого (действие) и дополнения (актант): «Мама мыла раму.» Мы можем навесить на слово «мама» событие, которое будет выстреливать каждый раз когда на входе актором будет слово «мама». На слово мыть мы тоже навешиваем событие, как и событие на слово «рама» в качестве актанта. Объединяем все ри события в ситуацию. Не смотря на то, что поотдельности эти 3 события будут активироваться на совершенно разные предложения, вместе, т.е. ситуация их объединившая, активируется только для одного конкретного случая, а именно входного предложения «мама мыла раму». И только для этого предложения сработает обработчик этой ситуации.


                                                                    1. lair
                                                                      15.09.2015 11:55

                                                                      Оттуда что разрабатывал и внедрял банковское ПО.

                                                                      Банковским ПО жизнь не ограничивается.

                                                                      Какой платеж первым заблокировал данные, тот и обрабатывается. Остальные лочатся и ждут завершения транзакции. Эти механизмы можно надеть на любую парадигму. Не стоит на них сосредотачиваться.

                                                                      Вопрос в том, какова стоимость «надевания» этих механизмов на конкретную парадигму.

                                                                      Кто будет добавлять возможность отвечать на новые типы вопоросов? Вы ответите — программист, и будете правы. А я отвечу — обычный человек будет это делать, не программист, он даже в код смотреть не будет. И я тоже буду прав. Только этому человеку соответствующий инструмент нужно дать.

                                                                      Вот не надо за меня додумывать мои ответы. Если нам нужна система со внешним обучением, то совершенно не обязательно, что ее обучает программист. И да, ему надо дать инструмент для этого обучения… вот только вы определитесь, вы хотите разработать такой инструмент, или парадигму программирования?

                                                                      На любые входные данные можно наложить события. А для вычленения определенной совокупности входных данных (конкретный набор слов) эти события можно сложить в ситуацию и и работать как с целым.

                                                                      Можно и презерватив на глобус натянуть, но зачем? Ваши входные данные не имеют временного аспекта (точнее, имеют, но вы его нигде не описываете и не используете), к ним не применимо понятие «событие».

                                                                      Мы можем навесить на слово «мама» событие, которое будет выстреливать каждый раз когда на входе актором будет слово «мама». На слово мыть мы тоже навешиваем событие, как и событие на слово «рама» в качестве актанта. Объединяем все ри события в ситуацию.

                                                                      Вот в этом примере наглядно видно, что у вас не события, а условия. Не «произошло А», а «есть А».

                                                                      Проще говоря, то, что вы описываете — это набор условий на синтаксическом дереве, приводящих к определенным последствиям. Вы, конечно, можете называть такой набор условий «ситуацией», но вот называть каждое условие событием — строго ошибочно.


                                                                      1. rimsleur
                                                                        15.09.2015 12:14

                                                                        Вот не надо за меня додумывать мои ответы. Если нам нужна система со внешним обучением, то совершенно не обязательно, что ее обучает программист. И да, ему надо дать инструмент для этого обучения… вот только вы определитесь, вы хотите разработать такой инструмент, или парадигму программирования?
                                                                        Инструмент. Но на этом подходе. Описал его, чтобы потом иметь возможность ссылаться. Да и сам тогда понимаешь лучше.
                                                                        но вот называть каждое условие событием — строго ошибочно.
                                                                        Ну это игра терминов. Собствено, почему изначально назвалось событием, потому что переменная означающая актора изменилась со значения Х на значение «мама». Произошло событие. Это потом стало ясно, что оно имеет свойства и состояния, потому что оно не перестанет быть активным, пока значение переменной не измениться на другое. А ситуация это уже больше похоже на условие, когда одновременно имеют значение несколько событий.


                                                                        1. lair
                                                                          15.09.2015 12:21

                                                                          Инструмент. Но на этом подходе. Описал его, чтобы потом иметь возможность ссылаться. Да и сам тогда понимаешь лучше.

                                                                          А почему обязательно на этом подходе? Чем этот подход лучше любого другого?

                                                                          Ну это игра терминов

                                                                          Когда вы обсуждаете теорию, терминология важна.

                                                                          Собствено, почему изначально назвалось событием, потому что переменная означающая актора изменилась со значения Х на значение «мама».

                                                                          Она не изменялась, она была инициализирована таким значением. Что важнее, вас никогда не интересует, какое значение у нее было до — вы имеете дело сразу с результатом парсинга, когда дерево уже сформировано и неизменно.

                                                                          И никакого «значение переменно изменится на другое» у вас тоже не будет — вы просто выбросите все дерево целиком, распарсите заново, и проверите по новому дереву все наборы условий.


                                                                          1. rimsleur
                                                                            15.09.2015 12:31
                                                                            +1

                                                                            А почему обязательно на этом подходе? Чем этот подход лучше любого другого?
                                                                            Он похож на подход, которым человек объясняет правила (чего либо) другому человеу. Я приводил пример с объяснением хода в карточной игре. Вот в этом причина. Программирование по фотографии посредством процесса коммуникации. Этот подход по моему скромному мнению как раз то, что нужно.

                                                                            И никакого «значение переменно изменится на другое» у вас тоже не будет — вы просто выбросите все дерево целиком
                                                                            Как раз этого не планировал. Раз уж переменные глобальные (по крайней мере пока), будем посторно их использовать. А это значит, что в переменной до слова «мама» было значение из предыдущего предложения. И после его обработки это уже неинтересный мусор


                                                                            1. b_oberon
                                                                              15.09.2015 12:36

                                                                              Программирование по фотографии посредством процесса коммуникации. Этот подход по моему скромному мнению как раз то, что нужно.

                                                                              Smalltalk, Erlang, SOA?


                                                                              1. lair
                                                                                15.09.2015 12:39

                                                                                Он не это понимает под коммуникацией.


                                                                            1. lair
                                                                              15.09.2015 12:39
                                                                              +1

                                                                              Он похож на подход, которым человек объясняет правила (чего либо) другому человеу.

                                                                              Если вкратце, то нет. Это вам кажется, что человек так объясняет правила другому человеку, но на самом деле, описания сильно отличаются от ситуации к ситуации. И, что показательно, человек чаще оперирует условиями, чем событиями (точнее, это зависит от природы описываемого процесса — статический он или динамический).

                                                                              Я приводил пример с объяснением хода в карточной игре.

                                                                              В этом примере, как мы уже обсуждали, ровно одно событие (и оно, на самом деле, просто триггер, в реальности мы анализируем набор данных, начинающийся с карты, с которой сходил противник).

                                                                              А это значит, что в переменной до слова «мама» было значение из предыдущего предложения. И после его обработки это уже неинтересный мусор

                                                                              Именно: неинтересный мусор. Поэтому это эквивалентно «выбросили и построили новый экземпляр» (и чтобы избежать глупых ошибок, именно так и надо делать).

                                                                              В итоге цикл обработки в вашей системе выглядит так:
                                                                              1. Получи от пользователя команду
                                                                              2. Преобразуй команду в синтаксическое дерево
                                                                              3. Проанализируй синтаксическое дерево
                                                                              4. Получи от пользователя команду
                                                                              5. Выполни команду


                                                                              Каждый шаг (кроме первого и последнего) — это чистая функция, работающая с неизменными данными, там нет никаких событий. После последнего шага (и перед первым) систему можно полностью перезапустить, и ничего не изменится.


                                                                              1. rimsleur
                                                                                15.09.2015 13:09

                                                                                В этом примере, как мы уже обсуждали, ровно одно событие (и оно, на самом деле, просто триггер, в реальности мы анализируем набор данных, начинающийся с карты, с которой сходил противник).
                                                                                Так и есть одно событие, остальные уже стали состояниями. Правильно ли я понимаю, что переименование события в условие (так сказать, элементатное, неделимое условие) решит проблему? Ну а ситуация стало быть это сложное (составное) условие.


                                                                                1. rimsleur
                                                                                  15.09.2015 13:15

                                                                                  Тогда элементарные условия будут двух типов: события и состояния.
                                                                                  Это хорошо заметно, если давать таким условиям символические имена. Например условие 'Двигатель работает' явно имеет преобладающей тип состояния. А условие 'Соперник совершил ход' имеет преобладающий тип события.


                                                                                  1. lair
                                                                                    15.09.2015 13:20

                                                                                    А условие 'Соперник совершил ход' имеет преобладающий тип события.

                                                                                    А в вашем примере с карточной игрой вообще не нужны события (кстати, во многих правилах настольных игр это хорошо видно). Там простая очередность: игрок делает ход, остальные игроки его анализируют, и делают ответные ходы.


                                                                                1. lair
                                                                                  15.09.2015 13:16

                                                                                  Правильно ли я понимаю, что переименование события в условие (так сказать, элементатное, неделимое условие) решит проблему?

                                                                                  Какую проблему?


                                                                                  1. rimsleur
                                                                                    15.09.2015 13:20

                                                                                    Терминологии, пока только терминологии.

                                                                                    но вот называть каждое условие событием — строго ошибочно
                                                                                    человек чаще оперирует условиями, чем событиями (точнее, это зависит от природы описываемого процесса — статический он или динамический)


                                                                                    1. lair
                                                                                      15.09.2015 13:21

                                                                                      Проблему терминологии — решит.


                                      1. rimsleur
                                        14.09.2015 22:41
                                        +1

                                        Ну и да, то, что вы описываете — это полностью последовательная система, со всеми описанными недостатками.
                                        Вы цепляетесь к деталям. Си тоже последовательный, а параллельность работы потоков контроллируется объектами ядра (семаформаи, мьютексами). Проблема параллельности СУБД решается транзакциями. Это все наживные детали.


                                        1. lair
                                          14.09.2015 22:43

                                          Угу, вот только у всех блокирующих примитивов (что семафоры, что транзакции) есть врожденные проблемы, которых как раз стремятся избежать реактивные системы (в том числе — построенные на событиях). А вы, судя по вашей аргументации, игнорируете эти наработки.


                                          1. rimsleur
                                            14.09.2015 22:54

                                            Какой-то подход может что-то позволять, а что-то нет. Я только думаю над теорией. Только практика покажет, придется проблему решать, или лучше игнорировать. Сейчас это больше похоже не на игнорирование, а на неполное видение полной картины.


                                            1. lair
                                              14.09.2015 22:55
                                              +1

                                              Когда вы думаете над теорией, неплохо сразу предположить, что другие люди над этой теорией уже подумали, наткнулись на проблемы, и попробовали их решить. В современном программировании нельзя игнорировать параллелизм.


                            1. rimsleur
                              14.09.2015 19:35

                              В рамках ситуационной парадигмы, мы навешиваем на все эти переменные определенные события и объединяем их в ситуацию. Именно эту конкретную ситуацию. И тогда, в определенный момент запуститься ее обработчик, который будет смотреть «есть ли у меня козырь?»


                              1. Rigidus
                                14.09.2015 19:42
                                +1

                                Таким образом мы видим, что «ситуация» — это абстрация, построенная вокруг «условий», которые обращаются к состоянию, выбирая из него лишь те, которые для «ситуации» важны


                      1. Rigidus
                        14.09.2015 19:14
                        +1

                        Однозначно проще по сравнению с ООП. В ООП не требуется явным образом определять какие действия выполняются при изменении какого состояния, и не требуется объяснять почему это сделано так.

                        Событийно-ориентированное программирование уже выделяет состояние и реакцию на него, но связь между состояниями автоматизированно отследить сложно — нужен анализ кода или IDE. Коссвеную связь практически никак не отследить.

                        В случае с функционально-реактивным программированием уже есть понятие реагирования и стремление минимизировать состояние, в идеале вообще избавиться от состояния в глобальной области видимости.

                        Этот подход — это своебразное развитие той же тенденции, кмк


                        1. lair
                          14.09.2015 19:18

                          В ООП не требуется явным образом определять какие действия выполняются при изменении какого состояния, и не требуется объяснять почему это сделано так.

                          Потому что в ООП (обычно) не реактивный, а императивный подход, и сначала происходит действие, а потом — изменяется состояние.

                          Этот подход — это своебразное развитие той же тенденции, кмк

                          Я пока не вижу, чем он отличается от событийно-ориентированного программирования, прямо скажем (кроме того, что мы объявили, что у все объекты доступны глобально, и у любого объекта есть ровно два события — «значение изменилось» и «значение равно x»).


                          1. Rigidus
                            14.09.2015 19:45
                            +1

                            Это надстройка над событийно-ориентированным программированием.

                            Отличается наличием диспетчера, который мониторит состяние и запускает «ситуации», если «условия» сработали.

                            Позволяет упростить программирования за счет абстрагирования от разделяемого состояния. «Ситуации» и «условия» как раз его и абстрагируют

                            Рекомендую Шалыто «Программирование с явным выделением состояний» «Автоматное программирование» — там предложена реализация такого диспетчера


                            1. lair
                              14.09.2015 21:44

                              Это надстройка над событийно-ориентированным программированием.

                              К сожалению, вы противоречите автору статьи. Тот утверждает, что его парадигма оперирует не событиями, а состояниями.

                              Позволяет упростить программирования за счет абстрагирования от разделяемого состояния. «Ситуации» и «условия» как раз его и абстрагируют

                              К сожалению, никак не абстрагируют. Состояние «сумма на счету» все так же используется совместно, не важно, оперируете вы им через прямую проверку или абстракцию «условие по сумме на счету».


                              1. rimsleur
                                14.09.2015 22:08
                                +1

                                Нет, он как раз очень хорошо подметил. На переменные навешиваются события (состояния), которые группируются в ситуации. Одно событие может быть привязано к разным ситуациям.


                                1. lair
                                  14.09.2015 22:12

                                  Определитесь, пожалуйста, у вас центром системы является событие или состояние. Пока вы в разных комментариях пишете разное, а это, заметим, взаимоисключающие вещи.


                          1. rimsleur
                            14.09.2015 22:14
                            +1

                            и у любого объекта есть ровно два события — «значение изменилось» и «значение равно x»).
                            Тут нельзя ставить точку, самое главное в продолжении: события объединяются в логические группы, образую нечто, описывающее реальную ситуацию из жизни


                            1. lair
                              14.09.2015 22:16

                              Выше мы уже обсудили, что в группы у вас объединяются не события, а состояния. Привести иной пример вам пока не удалось.

                              (я, впрочем, с удовольствием его выслушаю)


                            1. Rigidus
                              15.09.2015 17:28
                              +1

                              Предлагаю называть это ситуацией. Тогда ситуация — это абстракция, состоящая из:
                              — условия входа, т.е. возникновения ситуации (условием можем считать булеву формулу от набора состояний)
                              — выходного воздействия, т.е. поведения внутри ситуации, выраженного в инициировании других событий и/или изменении состояний.
                              — Можно еще добавить условие выхода из ситуации, если необходимо отразить некоторые аспекты реальности, когда однажды возникшая ситуация не прекращается если исчезли условия ее возникновения

                              Таким образом каждая ситуация — это сценарий поведения системы внутри набора условий, которые характеризуют сумму состояний системы.

                              В примере с машиной — есть ситуация езды, а есть ситуация стоянки. Поведение машины (как реакция на внешние события) в этих состояниях отличается. Если мы пользуемся такой формой абстракции — это упрощает программирование поведения и внесение изменений в код.

                              Благодарю за отличную концепцию!


                              1. lair
                                15.09.2015 17:37

                                В примере с машиной — есть ситуация езды, а есть ситуация стоянки. Поведение машины (как реакция на внешние события) в этих состояниях отличается. Если мы пользуемся такой формой абстракции — это упрощает программирование поведения и внесение изменений в код.

                                Поздравляю вас, вы открыли для себя новый и прекрасный мир акторов.


                              1. lair
                                15.09.2015 17:43

                                В примере с машиной — есть ситуация езды, а есть ситуация стоянки. Поведение машины (как реакция на внешние события) в этих состояниях отличается. Если мы пользуемся такой формой абстракции — это упрощает программирование поведения и внесение изменений в код.

                                … если еще подальше отмотать — просто Состояние.


  1. BjornValor
    14.09.2015 20:50
    +1

    Мне кажется или спагетти-код в таком «событийном» программировании наплодить еще проще?
    Например сделать каскад зависимых условий/событий/обработчиков, а потом случано или нет закольцевать, а потом забыть и вытащить в процессе какой-то — и все поламается.


    1. rimsleur
      14.09.2015 22:02
      +1

      Поскольку циклы и ветвления реализуются каскадами событий/условий, то ввести в бесконечный цикл систему также просто, как и на любом другом языке.


      1. lair
        14.09.2015 22:08
        +3

        Проще, потому что причинно-следственные связи не так очевидны.


        1. rimsleur
          14.09.2015 22:11

          Очевидность тут субъективное понятие. Довольно тяжело было переходить на ООП после процедурного в конце 90х. Теперь же тяжело дается понимание функциональщины. Вроде и понятно, но мозг уже привык к ООП.


          1. lair
            14.09.2015 22:13
            +2

            Очевидность вполне объективное понятие — мы либо знаем, где смотреть на связи, либо нет.

            (и да, последовательность и датировка у вас прекрасные, конечно)


            1. rimsleur
              14.09.2015 22:59

              Ну я привел пример трудности перехода из собственного опыта. Врядли тут есть о чем спорить.

              Вроде бы всегда отвечаю на конкретное сообщение, но хабр иногда перепривязывает не туда. Не знаю что это


              1. lair
                14.09.2015 23:02
                +1

                Понимаете ли, ваши трудности перехода с процедурного кода на ООП, а с того — на ФП ничего не говорят о том, насколько [не]очевидны причинно-следственные связи в вашем коде.

                Вот вам простой пример.

                int Main(int arg)
                {
                  var n = SomeFunc(arg);
                  return 0;
                }
                


                Рассмотрите этот код с точки зрения (а) процедурного (б) чисто функционального и (ц) вашего подхода. Сколько побочных эффектов вы можете предположить в каждом из случаев?


    1. Rigidus
      15.09.2015 17:31

      Если аннотировать вручную или автоматическим анализом все выходные воздействия внутри ситуации, то топологическая сортировка вовремя предупредит о цикле в графе обработчиков. Я даже представляю как это написать


  1. schroeder
    14.09.2015 21:25
    +3

    это ж конечный автомат, не?


    1. rimsleur
      14.09.2015 22:04

      Ну, примерно. Вот хорошо написали:

      Это надстройка над событийно-ориентированным программированием.
      Отличается наличием диспетчера, который мониторит состяние и запускает «ситуации», если «условия» сработали.
      Позволяет упростить программирования за счет абстрагирования от разделяемого состояния. «Ситуации» и «условия» как раз его и абстрагируют


    1. Rigidus
      15.09.2015 17:32
      +1

      На нижнем уровне — именно так. Но программировать с этим легче — проще думать о ситуации и поведении внутри нее, а все остальное спрятать под капотом


  1. speakingfish
    15.09.2015 01:01

    Это же en.wikipedia.org/wiki/Reactive_programming?
    Уже лет 20 при программировании GUI на разных языках использую вариации на тему en.wikipedia.org/wiki/Functional_reactive_programming


    1. Rigidus
      15.09.2015 17:34

      Мне кажется что это близко к нему


    1. rimsleur
      15.09.2015 17:43

      Чистое реактивное программирование, в моем понимании, это автоматический пересчет ячеек в экселе. Для табличного процессора этого хватает, но для реального программирования это ограниченный подход. Приходится городить всякие «реакторы» или события. Возможно именно этот подход используется в каких-то реактивных языках, которых похоже довольно много.


      1. speakingfish
        16.09.2015 17:11

        Автоматический пересчет ячеек в экселе — вполне себе тьюринг-полный механизм habrahabr.ru/post/254569 habrahabr.ru/post/246975
        Вопрос только в удобстве.
        Какие-то вещи, да — становятся линейными. Циклы — нет, но их можно заменить на более удобные вещи наподобие итераторов, рекурсий, монад и Y-комбинаторов. Но они так же будут более удобны и в примере, рассматриваемом вами, а не только в functional-reactive.


  1. michael_vostrikov
    15.09.2015 07:57
    +2

    Любая интеллектуальная система подразумевает наличие процесса обучения… Такое изменение поведения должно выполнятся специальными средствами метапрограммирования и в конечном счете приводит к внесению изменений в исходный код интеллектуальной программы.

    Не знаю вашей специализации, возможно вы хороший специалист в этой области, но насколько мне известно, экспертные системы или распознающие нейросети не меняют своего исходного кода в процессе обучения. Меняется реакция программы на данные, но движок остается тот же.

    и делает практически невозможным изменение программой самой себя

    И хорошо, что делает. Самомодифицирующаяся программа еще хуже, чем куча goto.

    Во-первых, дополнительное условие if (s[i]==c) нельзя добавить в произвольное место программы, а только внутрь цикла FOR.

    И хорошо, что нельзя. Где его потом искать в произвольном месте среди сотни тысяч строк кода.

    Во-вторых, поскольку внутри цикла FOR теперь больше одной инструкции, его нужно дополнить фигурными скобками.

    Хороший аргумент, чтобы начать писать в другой парадигме. Кстати, некоторые стандарты кодирования обязывают заключать в фигурные скобки даже один оператор.

    В-третьих, порядок добавляемых инструкций не является произвольным. Их перестановка приведет к некорректному поведению программы

    Перестановка инструкций в теле обработчика события тоже приведет к некорректному поведению программы.

    И тогда, в определенный момент запустится ее обработчик, который будет смотреть «есть ли у меня козырь?»…
    Только практика покажет, придется проблему решать, или лучше игнорировать ...

    Кстати, почему вы не попробовали реализовать свою идею на практике? Возьмите игру в дурака, или к примеру тетрис, и попробуйте реализовать на javascript, в нем есть средства для работы с событиями и их обработчиками. Результат опубликуете в статье. Предполагаю, что первая проблема, с которой вы столкнетесь — зацикливание событий change, когда в обработчике изменения одной переменной меняется вторая, а в обработчике второй первая.


    1. Rigidus
      15.09.2015 17:39

      >> Самомодифицирующаяся программа еще хуже, чем куча goto.

      «Пулемет гораздо хуже чем ружье, потому что во всей России не хватит заводов сделать столько патронов»

      Как человек который знает толк в извращениях который писал и анализировал самомодифицирующиеся программы я хочу сказать что что они интересны и могут быть исключительно полезны (например в генетическом и мета- программировании) и только несовершенство и неприспособленность инструментов мешает широко использовать этот подход.

      Предложение реализовать модельный пример типа тетриса или игры в дурака горячо поддерживаю


  1. AlexLeonov
    15.09.2015 11:37

    Вы переизобрели машину Тьюринга. Поздравляю!


    1. Rigidus
      15.09.2015 17:39

      ИМХО Вы ошиблись, пожалуйста перечитайте статью


  1. FiresShadow
    15.09.2015 11:38
    +2

    избавляет от изучения смежных блоков кода
    делает исходный код менее строкозависимым


    Зря вы не опробовали предлагаемый вами подход на практике, прежде чем выставлять его на всеобщее обозрение. Если бы опробовали, то поняли бы, что перед модификацией кода вместо n строк императивных инструкций вам приходится изучать столько же строк обработчиков событий. Если в алгоритме переменная используется в нескольких местах по-разному, то в подходе «только события» придётся или производить отписку\подписку, или заводить новую переменную, и значение этой новой переменной в любом случае зависит от событий предыдущей переменной, т.е. смежного блока кода.

    выносит ветвление и цикличность за рамки кода, оставляя только простой линейный алгоритм

    Вместо двух ветвлений в if у вас появляются два обработчика событий, навешанных на разные условия. Утверждать, что раз не используется слово if, то «ветвление вынесено за рамки кода», всё равно что утверждать, что при использовании if и goto на метку до if-а мы избавляемся от цикла — это некорректное утверждение.

    допускает изменение исходного кода непосредственно в момент выполнения программы

    Зря вы не поискали в интернете, возможно ли изменение исходного кода непосредственно в момент выполнения программы. Ещё как возможно, уже на ассемблере такое делали. В интерпретируемых языках такая возможность тоже как правило реализована на уровне языка.

    делает разработку кода более похожей на процесс мышления человека, что может снизить требуемый уровень подготовки разработчика

    Утверждение, что человек всегда мыслит в терминах событий — голословно. Имхо, иногда он мыслит в терминах условий и циклов, иногда — в терминах событий, иногда в терминах отношений между сущностями, иногда ещё как то.

    потенциально может упростить процесс автоматизированного изменения поведения программ

    Потенциально, я — Папа Римский. Могу же я потенциально стать католиком и пробиться в верха католической церкви? Вот только какой прок от таких потенциальных возможностей с вероятностью меньше 0,00001%? Тем более, что упрощение процесса кодогенерации — не такое уж и достижение, всё равно в скриптовых языках это «за кулисами» на уровне языка делается, без дополнительных действий со стороны программиста.

    В общем, предлагать публике трюк, который вы не проверили на практике хотя бы раз (при условии простоты его воспроизведения) — пустая трата времени публики. Ай-ай-ай, нехорошо.


    1. Rigidus
      15.09.2015 17:46

      >> придётся или производить отписку\подписку…

      Действительно, этот момент не был рассмотрен в статье автора. Неявно как бы предполагалось, что все подписки и отписки сделаны во время инициализации. Но я думаю, что эта дополнительная сложность не смутит пытливый ум :)

      >> потенциально может упростить процесс автоматизированного изменения поведения программ

      Уважаемый потенциальный Папа Римский, задумайтесь о возможностях, которые открываются, когда одни программы могут автоматизированно (и осмысленно) изменять другие программы. Может быть если поднапрячься и стать католиком, пробраться на самый верх католической церкви и сделать ее инструментом прогресса — оно таки будет стоить того?


      1. lair
        15.09.2015 17:49

        задумайтесь о возможностях, которые открываются, когда одни программы могут автоматизированно (и осмысленно) изменять другие программы.

        А что о них задумываться — метапрограммирование к вашим услугам.

        Вопрос в том, действительно ли предлагаемый в статье подход как-то упрощает метапрограммирование.


        1. Rigidus
          15.09.2015 17:57

          Стоит опробовать подход чтобы это понять


          1. lair
            15.09.2015 17:58

            Где прототип и пример использования в применении к метапрограммированию, чтобы «попробовать»?


            1. Rigidus
              15.09.2015 18:00

              «Сделай сам» (с)


              1. lair
                15.09.2015 18:04
                +1

                А смысл?

                Речь о том и идет, что автор статьи сделал некое утверждение («ситуационно-ориентированный подход [...] потенциально может упростить процесс автоматизированного изменения поведения программ»), никак его не аргументировал и не приложил никакого демонстрационного примера. Здравый смысл «рецензентов» подсказывает им, что нет, никак не упростит. Доказать отсутствие — невозможно (см. чайник Рассела); как следствие, бремя доказательства лежит на утверждающем.


                1. rimsleur
                  15.09.2015 18:07

                  Будет, но не скоро


                1. Rigidus
                  15.09.2015 18:26

                  Накладные расходы на критику подхода несопоставимо меньше усилий, потребующихся чтобы просто сделать модельный пример. Я бы мог сколько угодно докапываться до терминологии или каких-либо второстепенных аспектов вроде блокировок — это не требует особого труда.

                  Пока я не вижу заинтересованности в предложенном подходе с вашей стороны, так как не вижу усилий в конструктивном русле. Однако я вижу множество негативных комментариев — как прикажете вас понимать?


                  1. lair
                    15.09.2015 18:28

                    А что вам не понятно?


                    1. Rigidus
                      15.09.2015 18:34

                      Если подход вам кажется бесперспективным — Смысл тратить время на комментирование? Иначе: почему бы не приложить усилия и сделать прототип самостоятельно, чтобы продвинуть обсуждение вперед?


                      1. lair
                        15.09.2015 18:47

                        Иначе: почему бы не приложить усилия и сделать прототип самостоятельно, чтобы продвинуть обсуждение вперед?

                        Потому что я не могу сделать прототип в рамках подхода, который я считаю внутренне противоречивым, неполным и неподходящим для решения описанной задачи. То, что мой прототип не будет решать задачу, будет свидетельствовать не о том, что подход неуместен, а о том что я намеренно или по незнанию применил подход неправильным образом.


                        1. Rigidus
                          15.09.2015 18:51

                          Я тоже считаю подход внутренне противоречивым. Однако, как на ваш взгляд можно было было бы устранить хотя бы часть этих противоречий?


                          1. lair
                            15.09.2015 18:54

                            Выкинуть подход, затем начать с нуля: определить цели и задачи, определить принципиальные недостатки существующих подходов, преследующих те же цели, найти новый подход, лишенный этих недостатков.


      1. b_oberon
        15.09.2015 18:00
        +2

        Уважаемый потенциальный Папа Римский, задумайтесь о возможностях, которые открываются, когда одни программы могут автоматизированно (и осмысленно) изменять другие программы.

        [sarcasm] Тогда мы сможем писать трансляторы и полиморфные вирусы! [/sarcasm]


        1. Rigidus
          15.09.2015 18:31

          Полиморфные вирусы — отличный пример. Выскажу гипотезу, что самомодификация используется только в полиморфных вирусах именно потому, что инструменты, которые мы используем затрудняют написание в самомодифицирующем стиле чего-то большего по объему и сложности, чем полиморфный вирус.

          Я думаю, что если бы самомодифицирующиеся (и программы, модифицирующие другие программы) программы было как-то проще писать — в индустрии было бы существенно больше интересных и эффективных подходов, особенно в части унаследованного кода и его поддержки


          1. michael_vostrikov
            15.09.2015 19:14

            Cамомодификация редко используется не потому, что такие программы сложно писать, а потому, что их сложно понимать (и, как следствие, поддерживать). Для вирусов или обфускаторов это цель, для упаковщиков программного кода техническая необходимость. Можете привести примеры, когда самомодификация упрощает написание и поддержку кода?


            1. rimsleur
              15.09.2015 19:31

              Можете привести примеры, когда самомодификация упрощает написание и поддержку кода?
              Когда она их полностью заменяет


              1. lair
                15.09.2015 21:07

                Пример привести можете?


                1. rimsleur
                  15.09.2015 21:17

                  1. lair
                    15.09.2015 21:18

                    К сожалению, не смешно.

                    (вы правда думаете, что в искусственном интеллекте самомодификация заменяет написание и поддержку кода?)


                    1. rimsleur
                      15.09.2015 21:26

                      К сожалению, не смешно.
                      За время переписки я достаточно о вас узнал, чтобы предугадать это.

                      вы правда думаете, что в искусственном интеллекте самомодификация заменяет написание и поддержку кода?
                      Нет, там работает CLIPS, которая просто модифицирует правила.
                      Вы про искусственный интеллект вроде ботов в играх, или про сильный искусственный интеллект, сродни человвеку? Если первое, то эти примитивы создает и поддерживает программист, а самомодификация заменяется адаптивным алгоритмом. Что же до сильного ИИ, то я не знаю, как он устроен, т.к. его еще не создали. Потому не помешает рассмотреть и возможность такого подхода.
                      Конечно же со временем и он может быт заменен на что-то более результативное.


                      1. lair
                        15.09.2015 21:28

                        Вот именно, что о сильном ИИ ни вы, ни я ничего не знаем, поэтому не можем аргументированно рассуждать.

                        Поэтому давайте спустимся на землю и вернемся к вопросу — в каких же реальных случаях самомодификация упрощает написание и поддержку кода?


                      1. lair
                        15.09.2015 21:33

                        На самом деле, я, конечно, не прав, и правильнее вопрос поставить (и поделить) следующим образом:

                        1. (более важный) действительно ли предлагаемая парадигма упрощает написание самомодифицирующихся программ?
                        2. (мене важный) приносит ли способность програм к самомодификации выигрыш при их написании и поддержке?


                        1. rimsleur
                          15.09.2015 21:49

                          (более важный) действительно ли предлагаемая парадигма упрощает написание самомодифицирующихся программ?
                          Тут стоит разделить на самомодификацию с учителем и без. С учителем однозначное да. По тому видео вы возможно и сами это понимаете, но не хотите признавать. Т.к. там приведен яркий пример ситуативного программирования. Что касается обучения без учителя, то на данный момент нет. Вернее я пока такой возможности не вижу, но она потенциально присутствует. Собственно я много чего не видел, до начала реализации. Только не спрашивайте чего именно не видел, т.к. конкретно ответить не смогу. Не видел в целом картины взаимодействия компонентов, так, как вижу ее сейчас. И это видение постоянно расширяется в результате обсуждений и попыток реализации. При этом важно как первое, так и второе, даже неизвестно что важенее больше. Я к тому, что не реализовав подход, мы этого не узнаем наверняка.


                          1. lair
                            15.09.2015 21:51

                            Тут стоит разделить на самомодификацию с учителем и без.

                            Что такое «самомодификация с учителем»?


                            1. rimsleur
                              15.09.2015 21:55

                              Процесс обучения (изменение поведения) с учителем. Когда у учителя нет непосредственного доступа к коду. При этом процесс программирования может проходить не в императивном режиме, как сейчас, а в консультанционном, в режиме коммуникации, обсуждения (на самом высшем уровне взаимодействия)


                              1. lair
                                15.09.2015 21:57
                                -1

                                Стоп-стоп, а с какой радости обучение — это самомодификация? Вы (тоже) путаете самомодификацию и изменение поведения.


                                1. rimsleur
                                  15.09.2015 22:00

                                  Возможно, тогда попрошу вас дать определения тому и тому


                                  1. lair
                                    15.09.2015 22:01
                                    -1

                                    Самомодификация — это когда программа изменяет собственный исполняемый код. А изменение поведения — это когда (сюрприз) меняется поведение программы.


                                    1. rimsleur
                                      15.09.2015 22:06
                                      +1

                                      Я бы попросил не использовать этих саркастических выпадов.
                                      Давайте уходить от бихейвиористической оценки поведения интеллекта. Изменение поведения это только часть самомодификации.


                                      1. rimsleur
                                        15.09.2015 22:07

                                        Код это набор инструкций, изменение которого может привести к изменению поведения (внешнему отражению). А может изменять глубинные процессы, которые на поведении не факт, что отразятся


                                        1. lair
                                          15.09.2015 22:09
                                          -1

                                          Зачем нужно изменение программы, не отражающееся на ее поведении?


                                          1. rimsleur
                                            15.09.2015 22:46
                                            +1

                                            Это глубокий вопрос, затрагивающий облать ИИ, которую вы не рассматриваете.
                                            Самомодификация может быть направлена на изменение глубинных процессов системы, которые могут внешне не проявляться (или проявлять потом, но без ее изучения это можно показаться несвязным). Например планирование своего поведения, прогнозирование поведения других объектов.


                                            1. lair
                                              15.09.2015 22:48
                                              -1

                                              Зачем изменять «глубинные процессы системы», которые внешне не проявляются? Зачем нужно прогнозировать поведение других объектов?

                                              (Планирование поведение — изменение поведения)

                                              И да, вы, возможно, не поняли. Программа — это инструмент, у него есть задача, которую он решает. Зачем пользователю программы изменение, которое не отражается на ее (программы) поведении?


                                              1. rimsleur
                                                15.09.2015 22:57
                                                +1

                                                Программа, которая управляет механизмом не обязательно нуждается в пользователях. Тут появляется вопрос о развитии такой программы по желанию самой программы, а не какого-то там пользователя


                                                1. lair
                                                  15.09.2015 22:59
                                                  -1

                                                  Если у программы нет пользователей (в том числе — косвенных, то есть пользователей того механизма, которым управляет программа), зачем она нужна?

                                                  А развитие программы по желанию самой программы — это, простите, самоосознание; и, как следствие, за пределами нашей дискуссии.


                                      1. lair
                                        15.09.2015 22:09
                                        -1

                                        Я не занимаюсь оценкой поведения интеллекта, я обсуждаю программы и программирование. И в этом контексте мое разделение верно.

                                        Грубо говоря, когда вы меняете флажок «использовать визард/использовать детальные настройки» — поведение программы меняется, но сама программа — нет.


                                        1. rimsleur
                                          15.09.2015 22:13
                                          +1

                                          Ну вопросы самомодификации наверное не сильно актуальны для обычных программ. Я потому и указал для статьи раздел «машинное обучение». А стало быть она так или иначе затрагивает область интеллекта (пока не СИИ) и это стоит учитывать.


                                          1. lair
                                            15.09.2015 22:16
                                            -1

                                            Много вы знаете самомодифицирующихся систем искусственного интеллекта? (не изменяющих собственное поведение, а именно изменяющих собственный код)

                                            Что характерно, все это никак не отвечает на вопрос «почему ваш подход упрощает написание самомодифицирующихся программ».


                                            1. rimsleur
                                              15.09.2015 22:42
                                              +1

                                              Много вы знаете самомодифицирующихся систем искусственного интеллекта?
                                              Кроме вредоносных, пытающихся изменить свою сигнатуру, не знаю


                                              1. lair
                                                15.09.2015 22:45
                                                -1

                                                (Что-то я не слышал, чтобы малварь считалась искусственным интеллектом.)

                                                Итого, вернемся к вопросу. На основании чего вы утверждаете, что ваш подход упрощает написание самомодифицирующихся программ?


                                                1. rimsleur
                                                  15.09.2015 22:59
                                                  +1

                                                  Упрощает по сравнению с чем? С подходами, которые не подразумевают саморазвитие?


                                                  1. lair
                                                    15.09.2015 23:01
                                                    -1

                                                    Со всеми остальными существующими парадигмами программирования, позволяющими самомодификацию — например, структурным программированием.

                                                    (не надо приравнивать самомодификацию и саморазвитие)


                              1. rimsleur
                                15.09.2015 21:59
                                +1

                                Степень того, насколько программа может отклоняться от навязываемого ей, может быть изначально жестко задано. В таком поведении может быть и плюс. Например мы говорим программе «найти то-то», а она сама выбирает самый быстродействующий алгоритм (из тех, что она уже знает) поиска, при этом может сразу же протестировать его и сменить, если другой показывает более лучший результат для конкретно этой задачи.


                        1. rimsleur
                          15.09.2015 21:52
                          +1

                          (мене важный) приносит ли способность програм к самомодификации выигрыш при их написании и поддержке?
                          Тут главное, что мы ожидаем от этого, и что получим в результате. Всем известно, что программист во время написания кода должен сосредотачиватся, чтобы держать как можно больше объектов в голове. Если программа сама будет брать на себя хотя бы это, уже будет выиграш. Меньше нагрузка на мозг, меньше ошибок.


                          1. lair
                            15.09.2015 21:58

                            Что программа будет «брать на себя»?

                            (Кстати, вы не правы. Чем лучше устроена программа, тем меньше объектов программисту нужно держать в голове. Именно для этого нужен information hiding, который вашим подходом отвергается.)


                            1. rimsleur
                              15.09.2015 22:26

                              Что программа будет «брать на себя»?
                              Будет уменьшать количество объектов, состояние которых программист должен учитывать в один момент времени. Если он оперирует ситуацией, то держит в голове только объекты задействованные в ней.


                              1. lair
                                15.09.2015 22:29

                                И чем это отличается от любого современного варианта структурированного программирования, когда программист держит в голове только объекты, существующие в интересующей его области видимости?

                                В частности, если (для простоты) приравнять вашу «ситуацию» к Transaction Script (из PoEAA), то и в одном, и в другом случае программист будет «видеть» одинаковое количество объектов.


                            1. rimsleur
                              15.09.2015 22:28

                              Кстати, вы не правы. Чем лучше устроена программа, тем меньше объектов программисту нужно держать в голове. Именно для этого нужен information hiding, который вашим подходом отвергается
                              Не отвергается. Этот вопрос пока не урегулирован. Незначимые для глобального уровня объекты возможно будут прятаться.


                              1. lair
                                15.09.2015 22:30

                                И в чем это будет выражаться?


                                1. rimsleur
                                  15.09.2015 22:33

                                  И в чем это будет выражаться?
                                  Слово «возможно» подразумевает, что это на данном этапе реализации не известно.


                                  1. lair
                                    15.09.2015 22:44

                                    Угу. Из этого мы делаем вывод, что на данный момент программисту в вашей парадигме надо иметь дело со всеми объектами в системе, без какого-либо разделения или сокрытия (и вы не знаете, можно ли решить эту проблему, и как).

                                    Поэтому нет, сейчас вы не можете говорить, что ваша парадигма позволяет программе что взять на себя, и тем самым упростить работу разработчика.


                                    1. rimsleur
                                      15.09.2015 23:06

                                      Извините, вы постоянно ставите меня в положение защищающегося. Мне надоела эта однобокая дискуссия и я пожалуй ее прекращу.


                                      1. lair
                                        15.09.2015 23:08

                                        От человека, который делает публичные заявления, обычно ожидают, что он готов их обосновать.


                                        1. rimsleur
                                          15.09.2015 23:13

                                          Все, что я мог сказать, я уже сказал. Остальное мне неизвестно и является лишь предположением, возможно наталкивающим кого-то на поиск решений. Обосновывать я ничего не подписывался.


                                          1. Rigidus
                                            16.09.2015 20:35

                                            Поддерживаю и считаю далее ненужным кормить тролля


            1. Rigidus
              15.09.2015 19:33

              en.wikipedia.org/wiki/Intentional_programming и «исполняемые спецификации»

              Описывая поведение в таком стиле мы можем модифицировать уже работающую программу с возможностью отката без остановки (горячая замена кода, отвечающего за поведение) и удобно разделять знания между коллективами разработчиков


              1. lair
                15.09.2015 21:08

                Вы путаете самомодификацию и изменение поведения программы без ее остановки. Для второго не нужна самомодификация, достаточно разумного разделения исполняющей платформы и исполняемых инструкций.


      1. rimsleur
        15.09.2015 18:26
        +1

        Действительно, этот момент не был рассмотрен в статье автора. Неявно как бы предполагалось, что все подписки и отписки сделаны во время инициализации.

        Условия (так сказать триггеры) могут создаваться к значениям переменных непосредственно в рантайме. Как и группироваться в новые ситуации. Если я правильно понял про подписку.


    1. rimsleur
      15.09.2015 18:21

      Если в алгоритме переменная используется в нескольких местах по-разному.

      Не совсем понятно, как это по-разному.
      Есть переменная eng_state, например, ознаначающая состояние двигателя (включен/выключен) и содержащая значения TRUE либо FALSE. К одному значению переменной можно создать только одно условие (в старом варианте — событие). Плюс одно общее условие на изменение значения переменной с любого на любое. Т.е. условие eng_state==TRUE активируется в момент изменения значения с FALSE на TRUE. Если это условие привязано к каким-то ситуациям, то оно может спровоцировать и их активацию, следовательно вызывать обработчики тех ситуаций.
      Можно дать условию eng_state==TRUE символическое имя 'Двигатель включен' и обращаться к условию уже через него. Т.е. при объяснении системе с какой конкретно ситуацией мы хотим работать (изменить) можно так и указывать Если 'Двигатель включен' то… (набор инструкций)


  1. b_oberon
    15.09.2015 12:10
    +2

    Мне кажется, автор вплотную подошел к написанию либо курсовой работы, либо дипломного проекта. Навскидку предложенная (довольно сырая, надо сказать) концепция обладает несколькими серьезными недостатками.

    Самый очевидный — это зацикливание: если обработчик события «переменная равна точно X» не изменяет значение X, то он будет выполняться вечно. Следующий случай зацикливания — обработчик A запускается при изменении X и меняет Y, обработчик B запускается при изменении Y и меняет X. Чтобы отловить такие ситуации в статике, необходимо построить полный граф конечного автомата, а он для любой более-менее серьезной программы будет ОЧЕНЬ большим.

    Отказ от ветвлений и циклов заставляет все такие конструкции преобразовывать в обработчики событий, а все локальные переменные переносить в глобальную область видимости и сопоставлять с обработчиками. Производительность системы будет не просто низкой, а сверхнизкой; заодно и требования к памяти непомерно вырастут. Управлять (в терминах разработки) таким количеством обработчиков тоже будет непросто.

    Проблему отслеживания связей «ситуационно-ориентированное программирование» тоже не решает: изменение одного обработчика по-прежнему слабо предсказуемо влияет на работу остальной части программы. Того же самого эффекта можно достичь в структурном программировании применением средств статического анализа кода (ресурсоемкость опускаю) и/или аккуратного документирования всех побочных эффектов функций.

    В изложенном подходе ничего принципиально нового не обнаружилось: достаточно посмотреть на системы моделирования годов так 80-х прошлого века. Навскидку парадигма «ситуационно-ориентированного программирования» была реализована в языке VHDL (1983+, если верить вики).

    Обработчики событий называются в нем процессами (process), состояние хранится в сигналах (signal). Процесс запускается при изменении одного из сигналов, к которым привязан процесс; значения измененных в процессе сигналов обновляются в момент завершения процесса. Все процессы выполняются параллельно и мгновенно (абстракция виртуальной машины VHDL). Каждый сигнал может изменяться только одним процессом, что частично снимает проблему конкурентного изменения состояния. Зацикливание выявляется в рантайме (нет, мы не будем решать проблему останова).

    Следует учитывать, что в VHDL не отказались ни от ветвлений, ни от циклов: в противном случае написание кода стало бы адом для программиста. Кроме того, процесс может хранить свое внутреннее состояние в локальных переменных (на них, кстати, обработчики событий навесить нельзя): это также сокращает объем кода и разгружает глобальную область видимости.

    Чтобы сделать код модульным и управляемым, в VHDL поддерживаются дополнительный уровень абстракции в виде функциональных блоков (entity), все общение между которыми происходит только путем изменения входных и выходных сигналов.

    В современном варианте тот же подход реализуется конечными автоматами (привет, case) в простых случаях или паттернами типа publisher/subscriber и message broker'ами — в более сложных.


    1. Rigidus
      15.09.2015 17:51

      Мне кажется автору стоит взять вас в научные руководители при написании этой курсовой работы или дипломного проекта. Я бы тоже присоединился ради того чтобы опробовать подход. Спасибо за ценное указание на VHDL и информацию о способе его работы


      1. rimsleur
        15.09.2015 18:45

        Опробация в процессе и началась не вчера. В разработке я объединил этот подход с другим, который заключается в том, что язык исполнения = языку общения (коммуникации). Т.е. программные инструкции выглядят, практически как естественный язык. На нем же предполагается и описание действий (программирование) интеллектуальной системы, чтобы не лезть в код. Это я по поводу присоединиться. Проект открытый, но если этот подход проблемно встречают, то тот точно засрут.


        1. rimsleur
          15.09.2015 18:52

          А о том, как с набегу проверить теорию на одном из существующих языков (в плане использования в обработчиках ситуаций например С++, или С#) честно говоря не думал.


        1. Rigidus
          15.09.2015 18:52

          Можно в личку скинуть ссылку на гитхаб с исходниками?


        1. nsinreal
          16.09.2015 01:14

          язык исполнения = языку общения — это lisp что-ли? Интересно, скиньте в личку. Не присоединюсь, но посмотреть интересно. Засирать не буду, конструктивную критику по возможности напишу.


  1. dtestyk
    10.10.2015 13:22

    может будет полезным в рамках разрабатываемого вами подхода:
    >Робот включает двигатель, срабатывает первое событие. Оно превращается в состояние.
    SetEvent из WinAPI

    >чтобы сработала ситуация и выполнился ее обработчик должны быть одновременно активными все события, привязанные к ситуации
    WaitForMultipleObjects


    1. rimsleur
      10.10.2015 17:10

      Это известно. Функции общения с ядром для мультипоточных приложений в Windows. Но кто будет арбитром при одновременном возникновении нескольких ситуаций, обработчик одной из которых должен выполняться строго после обработчика другой? Для этого нужно анализировать код и выдавать всем обработчикам приоритеты. Ядро этим заниматься не будет, это дело интерпретатора/компилятора.