You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Пишу сюда, хотя часть почти наверняка относится к AnandamideAPI, но мне лень разбивать на issue'ы.
Сейчас в 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 скорее должен выглядеть как-то так:
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 должен выглядеть как-то так:
При этом, хотя в данном случае event-специфические action'ы (next и break) не принимают параметров (input'ов), в общем случае они их могут принимать — то есть внутри «стрелок влево», входящих в состав «стрелок вправо», могут быть свои «кружочки».
3. Далее я считаю необходимым ввести органичение: ко всему, что относится к данному event'у (т.е. к его output'ам и event-специфическим action'ам), можно обращаться только из блоков, непосредственно или косвенно принимающих управление от данного event'а. Иначе и аналтически (пользователю), и технически (программисту, реализующему машину) нереально отследить неиспользование undefined value. Чтобы пользователю было проще за этим следить и чтобы в принципе было понятнее, предлагаю визуализировать потоки управления отличным образом от потоков данных (тут на этой картинке не полностю используются обозначения, предлагаемые в предыдущих пунктах: input'ы/output'ы не кружочки, а action'ы/event'ы не ̲̅〉 и Ʃ — мне было лень перерисовывать, но надеюсь в целом идея относительно потоков управления понятна):
(Это условно; главное, что «мега-стрелка», отображающая поток управления, начинается и заканчивается во всю высоту соответствующих event'ов/action'ов; необязательно градиентом, можно в её фоне что-то нафигачить, лучше показывающее направление; но полупрозрачная, чтобы были видны пересечения.)
Update:
И ещё по поводу потоков управления и потоков данных. Из написанных выше трёх пунктов следует, что потоки данных сами по себе (без потоков управления) должны быть невозможны (что input'ы должны мочь быть только в составе action'ов, а output'ы — только в составе event'ов).
Ну то есть могут быть блоки вроде IntAdd, arrayGet и т.п., которым не нужны потоки управления (и которые не имеют action'ов/event'ов). Однако я считаю, что это должны быть блоки особого вида и они должны отображаться специальным образом, например:
Почему нельзя иметь блоки только одного типа и просто разрешить тянуть потоки данных от чего угодно к чему угодно? Вот конкретный пример:
Как прикажете его интерпретировать:
//так:
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.
The text was updated successfully, but these errors were encountered:
Пишу сюда, хотя часть почти наверняка относится к AnandamideAPI, но мне лень разбивать на issue'ы.
То же самое касается action'ов и input'ов, input'ы могут «предназначаться» для конкретных action'ов, а не для всех. Типичный пример: input'ы
start
иfrom
в block'ахFor
/ForWait
— они предназначаются только для action'аstart
(а не action'овnext
иbreak
).Поэтому, в общем случае block скорее должен выглядеть как-то так:
2. Далее мы замечаем, что не все action'ы равноценны. Некоторые action'ы могут предназначаться только для block'ов, принимающих поток управления от конкретных event'ов данного block'а. Типичный пример: action'ы
next
иbreak
в block'ахFor
/ForWait
— они предназначаются только для block'ов, принявших поток управления от event'аloop
. В этом плане часть action'ов можно сравнить с callback'ами, передаваемыеми в callback'и:Поэтому, более «правильный» block
ForWait
должен выглядеть как-то так:При этом, хотя в данном случае event-специфические action'ы (
next
иbreak
) не принимают параметров (input'ов), в общем случае они их могут принимать — то есть внутри «стрелок влево», входящих в состав «стрелок вправо», могут быть свои «кружочки».3. Далее я считаю необходимым ввести органичение: ко всему, что относится к данному event'у (т.е. к его output'ам и event-специфическим action'ам), можно обращаться только из блоков, непосредственно или косвенно принимающих управление от данного event'а. Иначе и аналтически (пользователю), и технически (программисту, реализующему машину) нереально отследить неиспользование undefined value. Чтобы пользователю было проще за этим следить и чтобы в принципе было понятнее, предлагаю визуализировать потоки управления отличным образом от потоков данных (тут на этой картинке не полностю используются обозначения, предлагаемые в предыдущих пунктах: input'ы/output'ы не кружочки, а action'ы/event'ы не ̲̅〉 и Ʃ — мне было лень перерисовывать, но надеюсь в целом идея относительно потоков управления понятна):
(Это условно; главное, что «мега-стрелка», отображающая поток управления, начинается и заканчивается во всю высоту соответствующих event'ов/action'ов; необязательно градиентом, можно в её фоне что-то нафигачить, лучше показывающее направление; но полупрозрачная, чтобы были видны пересечения.)
Update:
И ещё по поводу потоков управления и потоков данных. Из написанных выше трёх пунктов следует, что потоки данных сами по себе (без потоков управления) должны быть невозможны (что input'ы должны мочь быть только в составе action'ов, а output'ы — только в составе event'ов).
Ну то есть могут быть блоки вроде
IntAdd
,arrayGet
и т.п., которым не нужны потоки управления (и которые не имеют action'ов/event'ов). Однако я считаю, что это должны быть блоки особого вида и они должны отображаться специальным образом, например:Почему нельзя иметь блоки только одного типа и просто разрешить тянуть потоки данных от чего угодно к чему угодно? Вот конкретный пример:
Как прикажете его интерпретировать:
Т.е. я считаю, что блоки, которые потенциально могут содержать side-effect'ы (т.е. обычные блоки) должны мочь содержать input'ы только в составе action'ов, а output'ы -- только в составе event'ов, и читать output блока должно быть можно только из тех блоков, которые непосредственно или косвенно принимают поток управления от соответствующего event'а.
Но также можно реализовать отдельный тип блоков -- назовём «evaluation blocks» -- которые не могут содержать action'ов и event'ов, которые не работают с потоками управления (только с потоками данных), которые содержат input'ы и output'ы прямо в себе (а не в action'ах/event'ах), которые имеют отдельную визуализацию и которые при создании самим пользователем в составе себя могут иметь только другие evaluation block'и (а не обычные блоки) -- например,
IntAdd
,arrayGet
.The text was updated successfully, but these errors were encountered: