wizzard: (Default)
[personal profile] wizzard

сделал на досуге крохотный ивент-дривен рантайм, потом подумал “надо бы внести в мир равенство и справедливость, давайте сделаем по потоку на обьект?”

сказано-сделано, работает. правда, в голову лезут два назойливых вопроса:

  1. нафига это надо? :)
  2. как на этом правильно программировать?

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

мысленный понос:
  1. есть обьекты со свойствами (приватными) и методами, а также сообщения, которыми они обмениваются
  2. э-ээ, что-то многовато сущностей, давайте фичекатить.
    зачем нам методы? давайте введем иерархию классов, нет, разобьем их на аспекты, нет, давайте отделим их от обьектов совсем.
    обзовем это rule set’ом. т.е. отдельно от данных существует “мега-паттерн-матчер” который для кортежа (обьект, очередь сообщений) подбирает правило и кормит ему этот вход
  3. зачем нам return? зачем нам стэк? правило = (обьект, очередь сообщений) => (получившиеся сообщения)
  4. зачем нам переменные? по сути, обьект – это (id, state). если предположить, что такты синхронные, то мы можем на каждом такте фигачить весь свой стэйт сообщением себе же. то есть, все сообщения, посланные в этом такте, приходят одновременно.
    ура. мы заодно выбросили очередь сообщений, которая тоже раньше была стэйтом. и решили проблему с лайфтаймом сообщений – все пришедшие сообщения уничтожаются после их обработки. от стэйта остается (id, сообщение)
  5. зачем нам id? потому что object lifetime. и потому что обьекты нужно как-то идентифицировать. сначала разберемся с лайфтаймом. предположим, что обьект после каждого такта работы системы уничтожается. и создает новые обьекты посылкой специального сообщения.
  6. как тогда идентифицировать обьект? очень просто, по его state, т.е. предположим, обьект имеет 2 переменных (x, y).
    тогда чтобы послать сообщение i обьекту, требуется выплюнуть из себя кортеж (i, xDest, yDest). чтобы послать сообщение всем обьектам, x которых = xDest, посылаем (i, xDest, null). чтобы послать вообще всем обьектам, посылаем (i, null, null).
    кстати, это очень приятно напоминает всякие штуки из квантмеха вроде того, что две частицы не могут иметь одинаковую энергию :)
  7. оп, а обьектов у нас уже по сути и нету. есть сообщение (createObjectWithProperties, x, y), и остальные сообщения, которым посчастливилось в тот же такт работы системы попасть в те же координаты (или в общем случае – у которых свойства являются подмножеством свойств сообщения createObjectWithProperties)
    таким образом попутно лечится противный вопрос “сообщение – это обьект или нет?”
  8. для простоты, предположим, что все свойства обьекта дискретны и множество их возможных значений – счетно. а если ограниченно, то вообще шикарно. но вроде счетности достаточно :)
    тогда система представляется битовой матрицей (n^N)*(i+1), где i - кол-во возможных уникальных типов сообщений, n - кол-во возможных значений каждого из свойств обьекта, N - кол-во свойств.
    т.е. в каждой точке “пространства” существует n+1 битная маска, где бит 0 означает наличие там обьекта, а остальные биты отвечают за пришедшие к нему в этом такте сообщения.
  9. как это программировать?
    очевидно, нужно создать набор правил, ну, правда, они будут больше похожи на законы физики, но это даже хорошо. мы автоматически получаем emergent behaviour возведенный в абсолют, т.е. абсолютно гомогенные обьекты формируют всякие сложные гетерогенные бихевьоры.
    потом, выставляя биты, вводим начальные данные. и ставим несколько нулевых битов, ну, чтобы обьекты какие-то посоздавать. добро пожаловать в перфокарты :)
  10. далее можно просто итерировать систему, и она будет работать. система замкнутая и на вид (не помню как формально доказывается) тьюринг-полная, особенно если множество неограниченное.
    а еще она идеально параллелится (хоть по процессору на точку), вот правда всё упирается в bandwidth между точками. о, хехе, мы можем ввести явным образом latency доставки сообщений, ну, к примеру, равную расстоянию Хэмминга между матрицей отправителя и матрицей получателя.
    правда, для этого придется построить гиперкуб – это немного непрактичный способ постройки многопроцессорной системы, ну вообщем можно ввести какую-нибудь другую меру, которая будет соответствовать другой организации связей между процессорами.
    null можно заэмулировать тернарной логикой (по 2 бита на бит получателя), потому что составлять всю матрицу из тритов у меня мозг (пока) отказывается :)
    дети, дети, мы открыли скорость света! :)
  11. а еще, obviously, можно дописывать в нее биты и считывать биты. voila, работает.
  12. оставшийся неотвеченным вопрос – нафига всё это надо? :)
Comments welcome :)

Date: 2009-05-20 12:38 am (UTC)
From: [identity profile] ivan-ghandhi.livejournal.com
ивент-дривен

А в целом - офигенное открытие.

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


Date: 2009-05-20 05:48 am (UTC)
From: [identity profile] i-love-python.livejournal.com
Ура, вы поимели конечный автомат или стейт-машину (кому как нравится).

Есть мнение, что программирование в терминах конечных автоматов -- есть наивысшее благо.

Date: 2009-05-20 04:07 pm (UTC)
From: [identity profile] trippin-witch.livejournal.com
i like it
на этом можно фигачить симуляции всяких забавных хреней. да и вообще, вещь в себе. чем-то напоминает game of life

Date: 2009-05-23 10:01 pm (UTC)
From: [identity profile] dlinyj.livejournal.com
Решение задачи прекрасно реализуется на ПЛИС.

Profile

wizzard: (Default)
wizzard

January 2019

S M T W T F S
  12 345
6789101112
1314 1516171819
202122 23242526
2728293031  

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jan. 7th, 2026 05:31 pm
Powered by Dreamwidth Studios