Closed MohamedGhardallou closed 1 month ago
In Blech, we offer control flow to implement state machines. We think that state machines quickly become too complicated if they grow. So your example could look like this
activity app () ()
var err_code: nat8 = 0
repeat
err_code = run activity_init()()
if err_code != 0 then
run report_error()()
else
repeat
var output: nat8 = 0
err_code = run activity2()(output)
if err_code != 0 then
run report_error()()
elseif output == true then
run activity3()()
else // output == false
run activity4()()
end
until err_code != 0 end
end
end
end
In words: First initialize everything then repeat doing activity2 followed activity3 or activity4 depending on the result. If something goes wrong, report the error and start over with initialization. By the way: activity3 and activity4 cannot terminate with an error.
One more thing. If report_error
is a function - executed immediately, and does not contain await
- you can use error_code
to restart from the beginning by using when .. reset
(https://www.blech-lang.org/docs/user-manual/statements/#abort-and-reset), but you need an additional await
to not leave the when ... reset
-block or repeat the inner loop, in case of an error:
activity app () ()
var err_code: nat8 = 0
when err_code != 0 reset
err_code = run activity_init()()
if err_code != 0 then
report_error()
await true
else
repeat
var output: nat8 = 0
err_code = run activity2()(output)
if err_code != 0 then
report_error()
await true
elseif output == true then
run activity3()()
else // output == false
run activity4()()
end
end
end
end
end
But maybe, the following code with an error reporting function - instead of an activity - is the simplest:
activity app () ()
repeat
var err_code: nat8 = 0
err_code = run activity_init()()
if err_code != 0 then
report_error()
else
repeat
var output: nat8 = 0
err_code = run activity2()(output)
if err_code != 0 then
report_error()
elseif output == true then
run activity3()()
else // output == false
run activity4()()
end
until err_code != 0 end
end
await true
end
end
Hi, Yes this example can be rewritten but i prefer to keep the state machine structure for readability. When you have more states and multiple transitions you can no longer rewrite it using "traditional approach" without loosing the "structure" of you problem.
I believe that supporting Statechart (which enable concurrent and hierarchical state machine) as a language construct can improve developer productivity and code readability ( and also address the state explosion problem ).
I think that Statechart can also be implemented with the current blech language features. For example in [1] without changing the main language, they added Statechart as a high order construct.
what do you think about this ?
In order to keep an overview of the "structure" of your solution. We experimentally added a visualization of the hierarchical state/mode diagrams, that are expressed in the control flow of activities.
During development you can change your control flow and always get an up-to-date visualization.
There is a paper on this: https://ieeexplore.ieee.org/document/9568375 and a slide set, presented at a small workshop: http://synchron2021.inria.fr/slides/synchron2021-vonhanxleden.pdf
Currently it is not integrated into the Blech tools.
Maybe we should take the discussion to our Slack: https://join.slack.com/t/blech-lang/shared_invite/enQtODkyMDg4MDQ2Mjc2LWZjZWI1MmE2NTNhOGU0ZTVmMGEzMzY1ODlmNzBlMDFhMTIwMDRlZDA1MmU2NjY2OTFlZTA1NWIwMzU3NThkY2I
Some more hints from my side:
Thank you very much for the invitation and for the links. I will try to take a more deep look at this.
Hello, When i tried to implement a state machine in blech i ended up with a code like this:
Can't we have a langage construct that we can use to implement state machines. It would be great also if "state changes" are instantaneous
This can make code a lot easier to read and to reason about. What do you think about this ? Thanks