Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

По мотивам LOR'а #1

Open
o-pikozh opened this issue Jul 2, 2016 · 0 comments
Open

По мотивам LOR'а #1

o-pikozh opened this issue Jul 2, 2016 · 0 comments

Comments

@o-pikozh
Copy link

o-pikozh commented Jul 2, 2016

Пишу сюда, хотя часть почти наверняка относится к AnandamideAPI, но мне лень разбивать на issue'ы.

  1. Сейчас в block'е есть независимые друг от друга набор event'ов и набор output'ов, и любой block, непосредственно или косвенно принимающий поток управления от любого event'а данного block'а, может получать из любой output данного block'а. Однако в общем случае это не всегда так — output'ы могут «предназначаться» для block'ов, принимающих поток управления от конкретного event'а / конкретных event'ов, а не любых. В этом плане event'ы можно сравнить с callback'ами, а output'ы с их параметрами:
void functionWithCallbacks(
    void (*callback1)(t1 p1, t2 p2),
    void (*callback2)(t1 p1, t3 p3, t4 p4)
);
//Как видим, в реальной жизни разные callback'и могут получать разные наборы параметров.

То же самое касается action'ов и input'ов, input'ы могут «предназначаться» для конкретных action'ов, а не для всех. Типичный пример: input'ы start и from в block'ах For/ForWait — они предназначаются только для action'а start (а не action'ов next и break).
Поэтому, в общем случае block скорее должен выглядеть как-то так:
untitled3
2. Далее мы замечаем, что не все action'ы равноценны. Некоторые action'ы могут предназначаться только для block'ов, принимающих поток управления от конкретных event'ов данного block'а. Типичный пример: action'ы next и break в block'ах For/ForWait — они предназначаются только для block'ов, принявших поток управления от event'а loop. В этом плане часть action'ов можно сравнить с callback'ами, передаваемыеми в callback'и:

void ForWait(
    int from, int count,
    void (*loop)( int index, void (*next)(), void (*break)() ),
    void (*end)( int index )
);

Поэтому, более «правильный» block ForWait должен выглядеть как-то так:
untitled6
При этом, хотя в данном случае event-специфические action'ы (next и break) не принимают параметров (input'ов), в общем случае они их могут принимать — то есть внутри «стрелок влево», входящих в состав «стрелок вправо», могут быть свои «кружочки».
3. Далее я считаю необходимым ввести органичение: ко всему, что относится к данному event'у (т.е. к его output'ам и event-специфическим action'ам), можно обращаться только из блоков, непосредственно или косвенно принимающих управление от данного event'а. Иначе и аналтически (пользователю), и технически (программисту, реализующему машину) нереально отследить неиспользование undefined value. Чтобы пользователю было проще за этим следить и чтобы в принципе было понятнее, предлагаю визуализировать потоки управления отличным образом от потоков данных (тут на этой картинке не полностю используются обозначения, предлагаемые в предыдущих пунктах: input'ы/output'ы не кружочки, а action'ы/event'ы не ̲̅〉 и Ʃ — мне было лень перерисовывать, но надеюсь в целом идея относительно потоков управления понятна):
untitled4
(Это условно; главное, что «мега-стрелка», отображающая поток управления, начинается и заканчивается во всю высоту соответствующих event'ов/action'ов; необязательно градиентом, можно в её фоне что-то нафигачить, лучше показывающее направление; но полупрозрачная, чтобы были видны пересечения.)
untitled7

Update:

И ещё по поводу потоков управления и потоков данных. Из написанных выше трёх пунктов следует, что потоки данных сами по себе (без потоков управления) должны быть невозможны (что input'ы должны мочь быть только в составе action'ов, а output'ы — только в составе event'ов).

Ну то есть могут быть блоки вроде IntAdd, arrayGet и т.п., которым не нужны потоки управления (и которые не имеют action'ов/event'ов). Однако я считаю, что это должны быть блоки особого вида и они должны отображаться специальным образом, например:
1

Почему нельзя иметь блоки только одного типа и просто разрешить тянуть потоки данных от чего угодно к чему угодно? Вот конкретный пример:
2
Как прикажете его интерпретировать:

//так:
for(int i = 0; i!=10; ++i) {
    int r = IntRandom(1, 100);
    DoSomething(r);
    ...;
}

//или так:
int r = IntRandom(1, 100);
for(int i = 0; i!=10; ++i) {
    DoSomething(r);
    ...;
}

//?

Т.е. я считаю, что блоки, которые потенциально могут содержать side-effect'ы (т.е. обычные блоки) должны мочь содержать input'ы только в составе action'ов, а output'ы -- только в составе event'ов, и читать output блока должно быть можно только из тех блоков, которые непосредственно или косвенно принимают поток управления от соответствующего event'а.

Но также можно реализовать отдельный тип блоков -- назовём «evaluation blocks» -- которые не могут содержать action'ов и event'ов, которые не работают с потоками управления (только с потоками данных), которые содержат input'ы и output'ы прямо в себе (а не в action'ах/event'ах), которые имеют отдельную визуализацию и которые при создании самим пользователем в составе себя могут иметь только другие evaluation block'и (а не обычные блоки) -- например, IntAdd, arrayGet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant