Posts Hello Worlds - Part 3
Post
Cancel

Hello Worlds - Part 3

In the last installment of our conversation with the World, the denouement concludes with a demonstration of how to implement a key feature of Statecharts called hierarchical state machines and the use of the stop message.

The Stop Message

Formal computational theory defines that state machines should have one or more stop states. A stop state is like any other state except that it is considered “correct” if a machine ends in one and “incorrect” if it does not.

These semantics are often related to validation of languages or other streams of activity. In the more mundane activity of developing an application, we often just want to turn the system off no matter what state it is currently in.

To do so in a standardized way, Frame defines the << message token to be a reserved message meaning “stop”. However, system designers are free to ignore this convention as nothing bad will happen if other means are used to stop the system. However, its adoption allows Frame tools to recognize the semantic intent and utilize for other automated capabilities.

Here we see its use in our $Working state and how it drives our system to a proper $End state:

1
2
3
4
5
6
7
8
9
10
  $Working
    |>|
      print("Hello World") ^
    |<<|
      -> $End ^

  $End
    |>|
      print("End of the World") ^

Here is the next World in all its manifestations:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#World_v11

  -interface-

  start @(|>>|)
  stop @(|<<|)

  -machine-

  $Begin
    |>>|
      -> $Working ^

  $Working
    |>|
      print("Hello World") ^
    |<<|
      -> $End ^

  $End
    |>|
      print("End of the World") ^

  -actions-

  print [msg:string]

##

Here is the C# generated from this system definition:

    public partial class System_v11 {

        public World_v11() {

            _state_ = _sBegin_;
        }

        //===================== Interface Block ===================//

        public void start() {
            FrameEvent e = new FrameEvent(">>",null);
            _state_(e);
        }

        public void stop() {
            FrameEvent e = new FrameEvent("<<",null);
            _state_(e);
        }    

        //===================== Machine Block ===================//

        private void _sBegin_(FrameEvent e) {
            if (e.Msg.Equals(">>")) {
                _transition_(_sWorking_);
                return;
            }
        }

        private void _sWorking_(FrameEvent e) {
            if (e.Msg.Equals(">")) {
                print_do("Hello World");
                return;
            }
            else if (e.Msg.Equals("<<")) {
                _transition_(_sEnd_);
                return;
            }
        }

        private void _sEnd_(FrameEvent e) {
            if (e.Msg.Equals(">")) {
                print_do("End of the World");
                return;
            }
        }

        //===================== Actions Block ===================//

        public virtual void print_do(string msg) {}

        //=========== Machinery and Mechanisms ===========//

        private delegate void FrameState(FrameEvent e);
        private FrameState _state_;

        private void _transition_(FrameState newState) {
            FrameEvent exitEvent = new FrameEvent("<",null);
            _state_(exitEvent);
            _state_ = newState;
            FrameEvent enterEvent = new FrameEvent(">",null);
            _state_(enterEvent);
        }    
    }

And the equivalent UML statechart:

Hierarchical State Machines (HSMs)

The pinnacle of Statechart mods to the standard state machine is the idea of factoring common behavior between two or more states into a parent state. This is very similar to object-oriented inheritance but is strictly related to behavior and not data.

UML implements this concept visually. Here we see $A and $B have identical transitions to $C when responding to |e|:

In Frame notation that system looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
#FlatMachine

    -machine-

    $A
        |e| -> $C ^

    $B
        |e| -> $C ^

    $C

##

As we can see, there is redundant behavior between states $A and $B. Hierarchical State Machines (HSMs) allow system designers to factor out common behavior into a parent state using the “dispatch” symbol =>:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#HSM

    -machine-

    $A => $Parent

    $B => $Parent

    $C

    $Parent
        |e| -> $C ^    

##

Thanks to the approach Frame takes with implementing state machines, the mechanism for coding HSM functionality is trivial:

    //===================== Machine Block ===================//

    private void _sA_(FrameEvent e) {
        _sParent_(e);
    }

    private void _sB_(FrameEvent e) {
        _sParent_(e);
    }

    private void _sParent_(FrameEvent e) {
        if (e.Msg.Equals("e")) {
            _transition_(_sC_);
            return;
        }
    }

    private void _sC_(FrameEvent e) {
    }

Let’s apply this to the final incarnation of our World.

Getting in the Final World

And now, the magnum opus of our methodical exploration of “Hello World” in Frame notation:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#FinalWorld

    -interface-

    start @(|>>|)
    stop @(|<<|)
    tick [source:Object elapsedEvent:ElapsedEventArgs]

    -machine-

    $Begin
        |>>|
            print("In the Beginning...")
            -> $Working ^

    $Working => $Default
        |>|
            startTimer(500)
            print("Hello World") ^
        |<|
            stopTimer()
            print("Done working") ^
        |tick|
            -> $Resting ^

    $Resting => $Default
        |>|
            startTimer(1000)
            print("I'm resting") ^
        |<|
            stopTimer()
            print("Done resting") ^
        |tick|
            -> $Working ^

    $Default
        |<<|
            -> $End ^

    $End
        |>|
            print("End of the World") ^

    -actions-

    print [msg:string]
    startTimer [interval:int]
    stopTimer  [interval:int]

    -domain-

    var timer:Timer = null

##

Let us explore each of the states to review what we have learned so far.

The $Begin state utilizes the “start system” message >> symbol to kick things into gear and then transitions to the $Working state to go do stuff.

1
2
3
4
$Begin
    |>>|
        print("In the Beginning...")
        -> $Working ^

The $Working state exercises the enter > and exit < messages by managing a timer with a custom interval. Upon timeout, the event hander for the tick message transitions the system to the $Resting state for a well deserved break.

1
2
3
4
5
6
7
8
9
$Working => $Default
    |>|
        startTimer(500)
        print("Hello World") ^
    |<|
        stopTimer()
        print("Done working") ^
    |tick|
        -> $Resting ^

The $Resting state is functionally equivalent to the $Working state and just cycles back to $Working after a long nap.

1
2
3
4
5
6
7
8
9
$Resting => $Default
    |>|
        startTimer(1000)
        print("I'm resting") ^
    |<|
        stopTimer()
        print("Done resting") ^
    |tick|
        -> $Working ^

Both $Working and $Resting factor out the code to handle the stop system message << to the parent $Default state. This event handler simply transitions the system to the $End state.

1
2
3
$Default
    |<<|
        -> $End ^

In the $End the World says its goodbyes and goes quietly off into /dev/null.

1
2
3
$End
    |>|
        print("End of the World") ^

Here is the Framepiler generated UML documentation for the #FinalWorld:

And at last, here is the final C# output and its running code (with a hand coded print() action):

Conclusion

This concludes our exploration of advanced approaches to the classic “Hello World” program for new languages.

By making full use of both the stop message << as well as our HSM mechanisms we have seens what may well be the most embellished “Hello World” ever.

In the spirit if not the brevity of the original “Hello World”, not enough information has been presented yet to really do much.

In the next article we will explore syntax for conditional branching that will provide the bare minimum architects and developers need to start to utilize Frame notation for system design and programming.

This post is licensed under CC BY 4.0 by the author.

Trending Tags