Пока размышлял над Драконизацией программирования, пришла мысль, что, возможно, удобной штукой будет добавить coroutines в ST.
Гипотеза в том, что последовательный код писать проще чем "автоматный".
Да, есть CASE, но расщеплять состояния приходится вручную.
Что можно было бы сделать: добавить оператор "пауза" в ST. Тогда код с паузами при компиляции автоматически бы превращался в CASE автомат.
Пример:
Эта программа выглядит как бесконечный цикл (WHILE TRUE снаружи), но после компиляции она будет возвращать управление в момент "пауз". При повторном вызове она будет продолжать с места прошлой паузы.Код:PROGRAM запуск_насоса VAR номер_насоса: INT; WHILE TRUE номер_насоса := найти_рабочий_насос(); IF номер_насоса=-1 THEN авария_всех_насосов(); ПАУЗА t#1s; CONTINUE; END_IF; увеличить_количество_запусков(номер_насоса); запустить_насос(номер_насоса); ПАУЗА t#10s; WHILE давление_есть ПАУЗА; END_WHILE; (* Давление пропало, значит насос сломался *) остановить_насос(номер_насоса); установить_признак_аварии(номер_насоса); END_WHILE; END_PROGRAM
Иными словами, скомпилированный код может выглядеть вот так:
С одной стороны, конечно, невелика наука расставить CASE.Код:PROGRAM запуск_насоса VAR номер_насоса: INT; состояние : INT; ton1: TON; ton2: TON; WHILE TRUE CASE состояние OF 0: номер_насоса := найти_рабочий_насос(); IF номер_насоса=-1 THEN авария_всех_насосов(); состояние := 1; (* ПАУЗА 1s *) ton1(IN := FALSE, PT := t#1s); RETURN; (* возвращаем управление *) END_IF; состояние := 2; 1: ton1(IN := TRUE); (* ПАУЗА 1s *) IF ton1.Q THEN состояние := 0; (* continue *) ELSE RETURN; (* возвращаем управление *) END_IF; 2: увеличить_количество_запусков(номер_насоса); запустить_насос(номер_насоса); ton2(IN := FALSE, PT := t#10s); состояние := 3; RETURN; 3: ton2(IN := TRUE); (* ПАУЗА 10s; *) IF ton2.Q THEN состояние := 4; ELSE RETURN; END_IF; 4: IF давление_есть THEN RETURN; ELSE (* Давление пропало, значит насос сломался *) состояние := 5; END_IF; 5: остановить_насос(номер_насоса); установить_признак_аварии(номер_насоса); состояние := 0; END_WHILE; END_PROGRAM
Но, с другой стороны, на паузах код гораздо внятнее. Особенно, когда паузы внутри. Была одна строка "ПАУЗА t#1s;", а превратилась в 9 строк кода (запуск таймера, заход, выход)
Да и сам подход с async/await довольно широко сейчас используется в JavaScript, C#, Kotlin.
Что думаете?




Ответить с цитированием