Difference between revisions of "V4 Replacement for SNL"

From EPICSWIKI
Line 1: Line 1:
Warning: The following is work in progress.
Warning: The following is work in progress.<p>


= Deficiencies of current SNL =
= Deficiencies of current SNL =
Line 25: Line 25:


; Introspection
; Introspection
: The current state of all state sets, as well as global diagnostics (like the number of connected PVs) are exported using Data Access. The whole SNL programm will be represented as a propertyCatalog, with sub-properties for each living state set instance.
: The current state of all state sets, as well as global diagnostics (like the number of connected PVs) are exported using Data Access. The whole SNL programm will be represented as a propertyCatalog, with sub-properties for each named state set instance.


== Preliminary Observation ==
== A Preliminary Observation ==


It is widely known that closures (procedure + environment) can be implemented as objects in a language that natively supports objects. It is less well known, that objects can be implemented as closures in languages where closures are a native feature. The two concepts are quite similar. In what follows we will often switch from viewing things as objects to viewing them as closures and vice versa.
It is widely known that closures (procedure + environment) can be implemented as objects in a language that natively supports objects. It is less well known, that objects can be implemented as closures in languages where closures are a native feature. The two concepts are quite similar. In what follows we will often switch from viewing things as objects to viewing them as closures and vice versa.
Line 37: Line 37:
However, we introduce a new view on the concepts of "state set" and "state". A state set is regarded as a (special form of) closure resp. object.
However, we introduce a new view on the concepts of "state set" and "state". A state set is regarded as a (special form of) closure resp. object.


* State sets can be asynchronously "spawned" to run as an independent task. But they can also be synchronously "called", like a normal procedure, where the caller stops and waits for the state set to return.
* State sets can be asynchronously ''spawned'' to run as an independent task. But they can also be synchronously ''called'', like a normal procedure, where the caller stops and waits for the state set to return. In both cases, the caller can specify a name (string) for the state set that will be used to represent the state set to the outside.


* In contrast to the current SNL, all state sets must be instantiated explicitly, even the ones that are meant to "live forever". This has the additional advantage that initialization can be better controlled by the programmer.
* In contrast to the current SNL, all state sets must be instantiated explicitly, even those that are meant to "live forever". This has the additional advantage that initialization can be better controlled by the programmer.


* State sets can receive arguments on creation. In the OO view, this corresponds to constructor arguments. The arguments are visible throughout the state set, but not to any outside entity.
* State sets can receive arguments on creation. In the OO view, this corresponds to constructor arguments. The arguments are visible throughout the state set, but not to any outside entity.
Line 51: Line 51:
* The lifetime of asynchronously (via <tt>spawn</tt>) created state sets is always limited to the enclosing block. For state sets created at the top-level, this means forever (or rather as long as the underlying task doesn't get killed).
* The lifetime of asynchronously (via <tt>spawn</tt>) created state sets is always limited to the enclosing block. For state sets created at the top-level, this means forever (or rather as long as the underlying task doesn't get killed).


* Waiting on a condition to become true is done with the traditional when-clause. However, the clause does determine a new state. Instead 'state x;' is treated like an ordinary SNL action statement and can be used freely inside a when-block.
* Waiting on a condition to become true is done with the traditional when-clause. However, the clause does not determine a new state. Instead 'state x(args...);' is treated like an ordinary SNL action statement and can be used freely inside a when-block.


=== Creation of State Sets ===
=== Creation and Execution of State Sets ===


There are two ways to specify creation and execution of a state set:
There are two ways to specify instance creation and execution of a state set: synchronous


; Synchronous: <tt>call state_set_class_name(arg1, arg2, ...)</tt>
(result_1,...,result_n) = call stateSetName(arg_1,...,arg_n) as instanceName;
: An object of the given state set class is created with the given parameters and started. The calling state set waits (blocks execution) until the called state set returns. A state set can stop execution at any time, returning any number of values back to the caller, with a <tt>return(ret1, ret2, ...);</tt> statement.


; Asynchronous: <tt>spawn state_set_class_name(arg1, arg2, ...)</tt>
and asynchronous
: An object of the given state set class is created with the given parameters and started. The calling state set does ''not'' block execution and cannot receive any return values. Instead <tt>spawn</tt> returns a handle to the newly created state set.


In the old SNL, a state set declaration implied creation of a global top-level state set object. This is no longer the case. Instead, state set objects must be explicitly created at the top-level. If a top-level state set is supposed to run permanently, it must be created with a <tt>spawn</tt> statement.
spawn stateSetName(arg_1,...,arg_n) as instanceName;


A side-effect of this is that the programmer has control over the sequence of initialization.
In both cases an instance of the state set 'stateSetName' is created with the given parameters and started. The 'as instanceName' is optional. If given, 'instanceName' must be a constant string that gives a name to the state set instance. The state set will then be visible from outside of teh SNL program via the Data Access interface to the program.
 
; call
: The caller waits (blocks execution) until the called state set returns, at which point the return values get assigned to the result variables. Assignment to result variables is optional.
 
; spawn
: The caller does not block execution and cannot receive any return values.
 
In the old SNL, a state set declaration implied the creation and execution of a global top-level state set object. This is no longer the case. Instead, state set instances must be explicitly created at the top-level. If a top-level state set is supposed to run permanently, it must be created with a <tt>spawn</tt> statement. This gives the programmer full control over the sequence of initialization.
 
=== Return from a State Set ===
 
A state set can stop its own execution at any time, returning any number of values, with a
 
return(ret_1,...,ret_n);
 
statement. The list of return values (including parenthesis) can be omitted. If the state set instance was created with a <tt>spawn</tt>, then any return values are lost.
 
=== State Set Declaration ===
 
[to be done]
 
=== Local Variables ===
 
[to be done]


=== Access from the Outside ===
=== Access from the Outside ===
Line 73: Line 95:
=== PVs ===
=== PVs ===


We are currently evaluating the idea to introduce a special data type to represent references to PVs. This would replace how PVs are handled now (i.e. with assign, monitor, etc).
We are currently evaluating the idea to introduce a special data type to represent references to PVs. This would replace how PVs are handled now (i.e. with assign, monitor, etc). [to be done]
 
== Syntax ==
 
[to be continued]


== Implementation ==
== Implementation ==


We believe that our proposals can be implemented efficiently and without significantly changing the way SNL code is compiled currently.
We believe that our proposals can be implemented efficiently and without significantly changing the way SNL code is compiled currently.

Revision as of 19:56, 13 July 2005

Warning: The following is work in progress.

Deficiencies of current SNL

The current version of SNL (State Notation Language) has a number of severe deficiencies that should be addressed in a new version for EPICS R4.

No Abstraction Facilities
SNL doesn't support factoring common functionality. Functions cannot be defined in SNL, only by escaping to C, loosing all the features SNL adds (for instance easy access to PVs via 'assigned' variables). A typical workaround is to create additional state sets as a kind of subroutine. However, parameter passing and start/done communication must be simulated via PV-assigned global variables.
State Change is Determined by When Clause
In SNL the next state is already determined by the when-condition. This means that a condition for when to *do* something is coupled to a commitment for what to do next. This is often very inconvenient and to work around this limitation leads to a proliferation of artificial states that have nothing to do with the original state machine model.
Weak Support for Introspection
SNL supports querying internal state via the iocShell, but this is rather inconvenient and doesn't cover continous monitoring of the current state of a state set. In order to achieve this, the programmer has to (1) create a record to contain the value representing the current state, and (2) manually pvPut a value corresponding to the state into the PV on entry to the state, which clutters the code with extremely repetitive code, maintained via cut & paste.

Proposal for a new SNL

We propose a redesign of SNL, building on good and bad experiences with the current version. The goal is to remedy the deficiencies mentioned above, without throwing away what is good and proven to work. The syntax and semantics should be similar, although we adopt a somewhat different viewpoint. This viewpoint naturally leads to a number of new features that, taken together, solve the above mentioned problems. In particular:

Abstraction
Instead of adding ordinary procedures to the language, we propose a new way to instantiate state sets. A state set can be called like a procedure. It accepts parameters and can return a value. This necessitates thinking about the lifetime of state set objects.
State Change
Going to another state becomes a statement. It can be executed from anywhere in the code.
Introspection
The current state of all state sets, as well as global diagnostics (like the number of connected PVs) are exported using Data Access. The whole SNL programm will be represented as a propertyCatalog, with sub-properties for each named state set instance.

A Preliminary Observation

It is widely known that closures (procedure + environment) can be implemented as objects in a language that natively supports objects. It is less well known, that objects can be implemented as closures in languages where closures are a native feature. The two concepts are quite similar. In what follows we will often switch from viewing things as objects to viewing them as closures and vice versa.

Overview of Concepts

The new SNL will still be a programming language in its own right. It will still be based on the notions of "state" and "state set"; it will still support a subset of C for "normal" imperative programming (statements, if/then/else, assignment, etc.).

However, we introduce a new view on the concepts of "state set" and "state". A state set is regarded as a (special form of) closure resp. object.

  • State sets can be asynchronously spawned to run as an independent task. But they can also be synchronously called, like a normal procedure, where the caller stops and waits for the state set to return. In both cases, the caller can specify a name (string) for the state set that will be used to represent the state set to the outside.
  • In contrast to the current SNL, all state sets must be instantiated explicitly, even those that are meant to "live forever". This has the additional advantage that initialization can be better controlled by the programmer.
  • State sets can receive arguments on creation. In the OO view, this corresponds to constructor arguments. The arguments are visible throughout the state set, but not to any outside entity.
  • State sets can also return a value. Returning from a state set always destroys the underlying object. If a value was returned and the state set was created with a call, the caller receives this value. Otherwise the returned value is lost.
  • State sets can have local variables. These are not visible from the outside.
  • Individual states in a state set can also have local variables, as well as parameters (but no return value). Variables and parameters are not visible outside the state. The general syntax for a state change is state state_name(arg,...);.
  • The lifetime of asynchronously (via spawn) created state sets is always limited to the enclosing block. For state sets created at the top-level, this means forever (or rather as long as the underlying task doesn't get killed).
  • Waiting on a condition to become true is done with the traditional when-clause. However, the clause does not determine a new state. Instead 'state x(args...);' is treated like an ordinary SNL action statement and can be used freely inside a when-block.

Creation and Execution of State Sets

There are two ways to specify instance creation and execution of a state set: synchronous

(result_1,...,result_n) = call stateSetName(arg_1,...,arg_n) as instanceName;

and asynchronous

spawn stateSetName(arg_1,...,arg_n) as instanceName;

In both cases an instance of the state set 'stateSetName' is created with the given parameters and started. The 'as instanceName' is optional. If given, 'instanceName' must be a constant string that gives a name to the state set instance. The state set will then be visible from outside of teh SNL program via the Data Access interface to the program.

call
The caller waits (blocks execution) until the called state set returns, at which point the return values get assigned to the result variables. Assignment to result variables is optional.
spawn
The caller does not block execution and cannot receive any return values.

In the old SNL, a state set declaration implied the creation and execution of a global top-level state set object. This is no longer the case. Instead, state set instances must be explicitly created at the top-level. If a top-level state set is supposed to run permanently, it must be created with a spawn statement. This gives the programmer full control over the sequence of initialization.

Return from a State Set

A state set can stop its own execution at any time, returning any number of values, with a

return(ret_1,...,ret_n);

statement. The list of return values (including parenthesis) can be omitted. If the state set instance was created with a spawn, then any return values are lost.

State Set Declaration

[to be done]

Local Variables

[to be done]

Access from the Outside

Each SNL program will be presented to the outside world as a Data Access property catalog. Available properties include diagnostics such as the number of connected/available member variables (if assigned to a PV), a list of all global variables assigned to PVs, and all existing (life) state set objects as subproperties. Properties of a state set include the current state (including the state's parameters), and member variables.

PVs

We are currently evaluating the idea to introduce a special data type to represent references to PVs. This would replace how PVs are handled now (i.e. with assign, monitor, etc). [to be done]

Implementation

We believe that our proposals can be implemented efficiently and without significantly changing the way SNL code is compiled currently.