The Frame Interface Block

Mark Truluck
3 min readNov 6, 2018

Frame Machine Notation (FMN) is a notation for designing state machines or, more generally, automata. Previous articles have explored the basics of the -machine- block (or section) where the machine is defined in FMN. This article will delve into the -interface- block and show how these two blocks work together through the FrameEvent.

Basic Interface Block

The Frame -interface- block defines the public interface of the controller. The simplest interface method takes no parameters and returns no values:

#Controller    -interface-        start
stop

The interface above declares two methods — start and stop. Here is their implementation:

class Controller {    // -interface-    func start() {
_state( new FrameEvent("start") )
}
func stop() {
_state( new FrameEvent("stop") )
}

As we can see, the primary job of an interface method is to create a FrameEvent with the correct message and send it to the machine. By default the event message is the name of the method.

Lets now explore working with parameters and return types.

Parameters

If the method call has parameters, they are bundled into an object, map or list data structure (implementors choice) and sent along with the FrameEvent. FMN uses brackets to list the parameters:

run[speed]

FMN uses whitespace rather than commas as list item delineators:

buttonClick[x y]

Additionally, interface parameters can be typed if needed or desired:

addUser[firstName:String lastName:String]

Return Values

Interface methods that return a value simply declare the value after the function name or the optional parameter list:

isOn:boolean
wantMoreOf[thing:Object]:boolean

Event Message Aliasing

By default, the interface sends a message with the same name as the interface method. However, sometimes we want to change the message sent to the machine. This is easily accomplished with the following syntax:

method @(|alias message|)

This notation indicates to change the default message for the event to|alias message|:

#Controller    -interface-    buttonClick[x y] @(|click|)
addUser[firstName:String lastName:String] @(|create user|)

The aliases can be any string, which enables the machine to be designed to handle arbitrary symbols as the messages. We will show the use of these later.

Interface Block Implementation

Bringing these all together we can see how straightforward implementing the interface block is:

//--------------------------------------//
// FMN //
//--------------------------------------//
#Controller -interface- buttonClick[x y] @(|click|)
addUser[firstName:String lastName:String] @(|create user|)
isOn:boolean
//--------------------------------------//
// Implementation //
//--------------------------------------//
class Controller { // -interface- func buttonClick(x,y) { var params = { x:x, y:y } _state( new FrameEvent("click", params) )
}
func addUser(firstName:String lastName:String) { var params = { firstName:firstName, lastName:lastName } _state( new FrameEvent("create user", params) )
}
func isOn():boolean { var e = new FrameEvent("isOn") _state(e) return (boolean) e._return
}
}

Special Frame Events

Frame’s message aliasing enables tremendous flexibility in designing machines as any valid string can be used. For instance, the following event handlers are possible:

|200| success() ^
|&| append() ^
|~close| horseshoes() ^
|(╯°□°)╯︵ ┻━┻| aaaarrrrgggg() ^

Frame proposes 4 special message tokens with the following meanings:

  • |>>| — start machine
  • |<<| — stop machine
  • |>| — enter state
  • |<| — exit state

Use of these message tokens is optional, but much of the documentation for Frame utilizes them. In general, Frame attempts to use suggestive symbols as part of its language and conventions.

Conclusion

The Frame interface block pattern is key to turning object-oriented classes into automata in a clean and standardized way. While it may seem like a lot of effort to turn every interface call into a FrameEvent, the full utility of these events will unlock tremendous computational flexibility, power, and simplicity that we explore in future articles.

The simple switch type controller below demonstrates these new notations and their implementation patterns.

Related Articles

--

--

Mark Truluck

A professional software developer and manager. I believe Agile planning is a real thing.