>> Самомодифицирующаяся программа еще хуже, чем куча goto.
«Пулемет гораздо хуже чем ружье, потому что во всей России не хватит заводов сделать столько патронов»
Как человек который знает толк в извращениях который писал и анализировал самомодифицирующиеся программы я хочу сказать что что они интересны и могут быть исключительно полезны (например в генетическом и мета- программировании) и только несовершенство и неприспособленность инструментов мешает широко использовать этот подход.
Предложение реализовать модельный пример типа тетриса или игры в дурака горячо поддерживаю
Если аннотировать вручную или автоматическим анализом все выходные воздействия внутри ситуации, то топологическая сортировка вовремя предупредит о цикле в графе обработчиков. Я даже представляю как это написать
Предлагаю называть это ситуацией. Тогда ситуация — это абстракция, состоящая из:
— условия входа, т.е. возникновения ситуации (условием можем считать булеву формулу от набора состояний)
— выходного воздействия, т.е. поведения внутри ситуации, выраженного в инициировании других событий и/или изменении состояний.
— Можно еще добавить условие выхода из ситуации, если необходимо отразить некоторые аспекты реальности, когда однажды возникшая ситуация не прекращается если исчезли условия ее возникновения
Таким образом каждая ситуация — это сценарий поведения системы внутри набора условий, которые характеризуют сумму состояний системы.
В примере с машиной — есть ситуация езды, а есть ситуация стоянки. Поведение машины (как реакция на внешние события) в этих состояниях отличается. Если мы пользуемся такой формой абстракции — это упрощает программирование поведения и внесение изменений в код.
Таким образом мы видим, что «ситуация» — это абстрация, построенная вокруг «условий», которые обращаются к состоянию, выбирая из него лишь те, которые для «ситуации» важны
>> На основании чего меняется переменная внутри этого домена?
Она меняется внутри «ситуаций», в которых явно аннотирование изменение этой переменной. А ситуации вызываются диспетчером при срабатывании их условий. Так что можно сказать, что эта переменная меняется на основании срабатывания условий тех ситуаций, которые явно могут менять эту переменную
Не смог успеть до окончания времени редактирования прошлого комментария…
01. Объявить переменную «количество денег на счете» внутри домена «текущий пользователь»
02. Объявить условие «изменение количества денег на счете» для ref:01
03. Обявить ситуацию — обновление кол-ва денег в интерфейсе пользователя, срабатывающий при активации условия «изменилось кол-во денег на счете»
04. Объявить ситуацию «отображение интерфейса денежного перевода», срабатывающий при активации условия «отображение страницы банк-клиента». В интерфейсе аннотировать запуск ситуации перевода средств (когда пользователь нажимает кнопку «выполнить перевод»)
05. Объявить ситуацию «перевод средств», храняющую состояние (текущий пользователь, дата/время, сумма, код завершения, размер тайм-аута, ...). Инициализировать ситуацию при срабатывании условия «получен запрос на перевод средств» ref:04, отправить асинхронный запрос в стороннюю систему на совершение перевода
06. Объявить ситуацию «отказ в переводе», срабатывающую при наступлении условия «получен отрицательный ответ от сторонней системы», отобразить сообщение об отказе пользовалею
07. Объявить ситуацию «успешный перевод» срабатывающую при наступлении условия «получен положительный ответ от сторонней системы», изменить кол-во денег на счете, что вызовет срабатывание условия ref:02
>>>> Управление сложностью становится простым за счет того что мы можем читая описание «ситуаций» явно видеть их взаимосвязь.
>> Читая головой, или читая программным анализатором?
01. Объявить переменную «количество денег на счете» внутри домена «текущий пользователь»
02. Объявить условие «изменение количества денег на счете» для ref:01
03. Обявить «побочный эффект» — перерисовать кол-во денег в интерфейсе пользователя, срабатывающий при активации условия «изменилось кол-во денег на счете»
— Отображать в веб-клиенте кол-во денег на счете. Если оно изменилось — перерисовать кол-во денег
— Дать возможность клиенту иницировать в веб-клиенте перевод
— На сервере асинхронно запустить перевод («условие» — авторизованный клиент пытается совершить перевод". Перевод — это отправка асинхронного запроса в стороннюю систему. Внутри этого «события» мы помним номер запроса"
— Сообщить об ошибке, если («условие») сторонняя система вернула отказ в денежном переводе. Для этого возможно нужно найти событие, которое помнит номер запроса
— Если (условие) сторонняя система успешно перевела деньги — изменить кол-во денег на счете клиента
Однозначно проще по сравнению с ООП. В ООП не требуется явным образом определять какие действия выполняются при изменении какого состояния, и не требуется объяснять почему это сделано так.
Событийно-ориентированное программирование уже выделяет состояние и реакцию на него, но связь между состояниями автоматизированно отследить сложно — нужен анализ кода или IDE. Коссвеную связь практически никак не отследить.
В случае с функционально-реактивным программированием уже есть понятие реагирования и стремление минимизировать состояние, в идеале вообще избавиться от состояния в глобальной области видимости.
Этот подход — это своебразное развитие той же тенденции, кмк
Представим себе, что мы делаем банк-клиент в вебе. Тогда у нас будут такие «ситуации»:
— Отображать в веб-клиенте кол-во денег на счете. Если оно изменилось — перерисовать кол-во денег
— Дать возможность клиенту иницировать в веб-клиенте перевод
— На сервере асинхронно запустить перевод («условие» — авторизованный клиент пытается совершить перевод". Перевод — это отправка асинхронного запроса в стороннюю систему. Внутри этого «события» мы помним номер запроса"
— Сообщить об ошибке, если («условие») сторонняя система вернула отказ в денежном переводе. Для этого возможно нужно найти событие, которое помнит номер запроса
— Если (условие) сторонняя система успешно перевела деньги — изменить кол-во денег на счете клиента
Такие подкейсы легко программировать по частям, минимизируя разделямое общее состояние. И патчить тоже удобно — патч — это замена группы «ситуаций», с мотивированным описанием патча.
Управление сложностью становится простым за счет того что мы можем читая описание «ситуаций» явно видеть их взаимосвязь. Можно еще запретить доступ к состоянию сторонних «ситуаций» без явного объявления в аннотоциях, если хочется оградить программиста от неосторожных шагов
Без проблем — сохраняем «переменные» в реляционной бд, а дальше по индексам.
Я бы несколько расширил «переменные» таким образом, чтобы существовали «ситуации» и «условия срабатывания». Применяя одно к другому можно было бы генерировать «побочные эффекты» и вызывать срабатывание других «ситуаций».
Сверху на это можно накладывать «советы» и все прочее, что есть в аспектно-ориентированном программировании.
Таким образом можно сформировать структуру программы (например, внутри БД) и по ней уже сгенерировать низкоуровневый код, если важна производительность. Отдельные «ситуации», «побочные эффекты» и прочие классы компонентов могут быть реализованы на различных языках при необходимости. Например ситуация, возникшая в веб-клиенте могла бы иницировать транзакцию на сервере итп.
С точки зрения процесса разработки можно обязать документировать «ситуации» в литературном стиле (или хотя бы аннотировать побочные эффекты и писать описания ситуаций) и получить управление сложностью программы существенно лучше чем в среднем по индустрии.
Если говорить о расширяемости (патчи, замена и исправление функциональности) то отдельные «ситуации» и «условия» могут быть перегружены (в смысле override) в ответ на issue в баг-трекере — это уже следующий уровень управления версиями после VCS типа git
В общем, перспективно выглядит. Я бы присмотрелся, и даже попытался взять на вооружение
Большое спасибо за перевод.
Я один из тех, кто разрабатывает веб-приложения на hunchentoot вместо использования лучшего. Теперь присмотрюсь к Clack. Собственно ушел смотреть :)
Спасибо за эту ссылку. Зашел и среди всякой пиротехники про магний и марганцовку отыскал всего Ландавшица и Фейнмановские лекции по физике. И немедленно скачал
«Пулемет гораздо хуже чем ружье, потому что во всей России не хватит заводов сделать столько патронов»
Как человек
который знает толк в извращенияхкоторый писал и анализировал самомодифицирующиеся программы я хочу сказать что что они интересны и могут быть исключительно полезны (например в генетическом и мета- программировании) и только несовершенство и неприспособленность инструментов мешает широко использовать этот подход.Предложение реализовать модельный пример типа тетриса или игры в дурака горячо поддерживаю
— условия входа, т.е. возникновения ситуации (условием можем считать булеву формулу от набора состояний)
— выходного воздействия, т.е. поведения внутри ситуации, выраженного в инициировании других событий и/или изменении состояний.
— Можно еще добавить условие выхода из ситуации, если необходимо отразить некоторые аспекты реальности, когда однажды возникшая ситуация не прекращается если исчезли условия ее возникновения
Таким образом каждая ситуация — это сценарий поведения системы внутри набора условий, которые характеризуют сумму состояний системы.
В примере с машиной — есть ситуация езды, а есть ситуация стоянки. Поведение машины (как реакция на внешние события) в этих состояниях отличается. Если мы пользуемся такой формой абстракции — это упрощает программирование поведения и внесение изменений в код.
Благодарю за отличную концепцию!
Отличается наличием диспетчера, который мониторит состяние и запускает «ситуации», если «условия» сработали.
Позволяет упростить программирования за счет абстрагирования от разделяемого состояния. «Ситуации» и «условия» как раз его и абстрагируют
Рекомендую Шалыто «Программирование с явным выделением состояний» «Автоматное программирование» — там предложена реализация такого диспетчера
$_SESSION[current_user]
>> На основании чего меняется переменная внутри этого домена?
Она меняется внутри «ситуаций», в которых явно аннотирование изменение этой переменной. А ситуации вызываются диспетчером при срабатывании их условий. Так что можно сказать, что эта переменная меняется на основании срабатывания условий тех ситуаций, которые явно могут менять эту переменную
01. Объявить переменную «количество денег на счете» внутри домена «текущий пользователь»
02. Объявить условие «изменение количества денег на счете» для ref:01
03. Обявить ситуацию — обновление кол-ва денег в интерфейсе пользователя, срабатывающий при активации условия «изменилось кол-во денег на счете»
04. Объявить ситуацию «отображение интерфейса денежного перевода», срабатывающий при активации условия «отображение страницы банк-клиента». В интерфейсе аннотировать запуск ситуации перевода средств (когда пользователь нажимает кнопку «выполнить перевод»)
05. Объявить ситуацию «перевод средств», храняющую состояние (текущий пользователь, дата/время, сумма, код завершения, размер тайм-аута, ...). Инициализировать ситуацию при срабатывании условия «получен запрос на перевод средств» ref:04, отправить асинхронный запрос в стороннюю систему на совершение перевода
06. Объявить ситуацию «отказ в переводе», срабатывающую при наступлении условия «получен отрицательный ответ от сторонней системы», отобразить сообщение об отказе пользовалею
07. Объявить ситуацию «успешный перевод» срабатывающую при наступлении условия «получен положительный ответ от сторонней системы», изменить кол-во денег на счете, что вызовет срабатывание условия ref:02
>>>> Управление сложностью становится простым за счет того что мы можем читая описание «ситуаций» явно видеть их взаимосвязь.
>> Читая головой, или читая программным анализатором?
И анализатором тоже
01. Объявить переменную «количество денег на счете» внутри домена «текущий пользователь»
02. Объявить условие «изменение количества денег на счете» для ref:01
03. Обявить «побочный эффект» — перерисовать кол-во денег в интерфейсе пользователя, срабатывающий при активации условия «изменилось кол-во денег на счете»
— Отображать в веб-клиенте кол-во денег на счете. Если оно изменилось — перерисовать кол-во денег
— Дать возможность клиенту иницировать в веб-клиенте перевод
— На сервере асинхронно запустить перевод («условие» — авторизованный клиент пытается совершить перевод". Перевод — это отправка асинхронного запроса в стороннюю систему. Внутри этого «события» мы помним номер запроса"
— Сообщить об ошибке, если («условие») сторонняя система вернула отказ в денежном переводе. Для этого возможно нужно найти событие, которое помнит номер запроса
— Если (условие) сторонняя система успешно перевела деньги — изменить кол-во денег на счете клиента
Событийно-ориентированное программирование уже выделяет состояние и реакцию на него, но связь между состояниями автоматизированно отследить сложно — нужен анализ кода или IDE. Коссвеную связь практически никак не отследить.
В случае с функционально-реактивным программированием уже есть понятие реагирования и стремление минимизировать состояние, в идеале вообще избавиться от состояния в глобальной области видимости.
Этот подход — это своебразное развитие той же тенденции, кмк
Представим себе, что мы делаем банк-клиент в вебе. Тогда у нас будут такие «ситуации»:
— Отображать в веб-клиенте кол-во денег на счете. Если оно изменилось — перерисовать кол-во денег
— Дать возможность клиенту иницировать в веб-клиенте перевод
— На сервере асинхронно запустить перевод («условие» — авторизованный клиент пытается совершить перевод". Перевод — это отправка асинхронного запроса в стороннюю систему. Внутри этого «события» мы помним номер запроса"
— Сообщить об ошибке, если («условие») сторонняя система вернула отказ в денежном переводе. Для этого возможно нужно найти событие, которое помнит номер запроса
— Если (условие) сторонняя система успешно перевела деньги — изменить кол-во денег на счете клиента
Такие подкейсы легко программировать по частям, минимизируя разделямое общее состояние. И патчить тоже удобно — патч — это замена группы «ситуаций», с мотивированным описанием патча.
Управление сложностью становится простым за счет того что мы можем читая описание «ситуаций» явно видеть их взаимосвязь. Можно еще запретить доступ к состоянию сторонних «ситуаций» без явного объявления в аннотоциях, если хочется оградить программиста от неосторожных шагов
На самом деле будет даже проще, т.к. связи между «ситуациями» и их «обработчиками» становятся явными
Я бы несколько расширил «переменные» таким образом, чтобы существовали «ситуации» и «условия срабатывания». Применяя одно к другому можно было бы генерировать «побочные эффекты» и вызывать срабатывание других «ситуаций».
Сверху на это можно накладывать «советы» и все прочее, что есть в аспектно-ориентированном программировании.
Таким образом можно сформировать структуру программы (например, внутри БД) и по ней уже сгенерировать низкоуровневый код, если важна производительность. Отдельные «ситуации», «побочные эффекты» и прочие классы компонентов могут быть реализованы на различных языках при необходимости. Например ситуация, возникшая в веб-клиенте могла бы иницировать транзакцию на сервере итп.
С точки зрения процесса разработки можно обязать документировать «ситуации» в литературном стиле (или хотя бы аннотировать побочные эффекты и писать описания ситуаций) и получить управление сложностью программы существенно лучше чем в среднем по индустрии.
Если говорить о расширяемости (патчи, замена и исправление функциональности) то отдельные «ситуации» и «условия» могут быть перегружены (в смысле override) в ответ на issue в баг-трекере — это уже следующий уровень управления версиями после VCS типа git
В общем, перспективно выглядит. Я бы присмотрелся, и даже попытался взять на вооружение
Я один из тех, кто разрабатывает веб-приложения на hunchentoot вместо использования лучшего. Теперь присмотрюсь к Clack. Собственно ушел смотреть :)