4.2 Fail-safe Coding

Overloading of Language Constructs

The following language constructs are overloaded:

  • ?A = ?B, which can either be an assignment (if exactly one of ?A and ?B is bound) or a test, evaluating as TRUE or FALSE (if both or neither of ?A and ?B is bound);

  • ?A IN MYSET, which is either a test (if ?A is bound) or a loop (if ?A is FREE); it can also resolve UNKNOWN if ?A is FREE and MYSET is null.

This overloading is a frequent cause of errors when a variable is FREE which the author of the code thought would be bound, or vice versa. Such errors often cause back-tracking and can be difficult to debug.

In order to prevent such problems, a fail-safe approach should be adopted. That is, the aim should be that if a variable is FREE rather than bound (or vice versa), the statement will cause an Aspen SCM Expert System error and stop the interpreter immediately rather than allowing it to continue erroneously.

?A = ?B

When two variables are to be tested for equality, the logical operator EQ should be used (or ==, although it is more similar to = and therefore less good). This will evaluate as TRUE or FALSE and will never change the values of ?A or ?B.

When an assignment is intended and the value of ?B is known to be numeric, the assignment should be written as ?A = ?B + 0. This will produce an Aspen SCM Expert System error if ?B is FREE or is bound and non-numeric. It also has the side-effect of coercing ?A to the numeric value of ?B if ?B happens to be a character representation of a numeric value (e.g. from a read of a string table or from an amper variable).

When an assignment is intended and the value of ?B is known to be character, the assignment should be written as ?A = '?B'. This will produce an Aspen SCM Expert System error if ?B is FREE and has the side-effect of coercing ?A to the character representation of ?B if ?B is numeric. This can go wrong if ?B contains single or double quotes. If it is considered possible that ?B could contain quotes, the statement ?A = ?B will need to be used. In this case it should be immediately preceded by the statement FREE ?A to make it clear that an assignment is intended.

?A IN MYSET

The statement ?A IN MYSET is often used not as a test but to set the internal index of MYSET to ?A. Such a statement often appears without a corresponding OR clause. This is to be deprecated because of the possibility of backtracking if ?A happens not to be in MYSET. Even with the corresponding OR clause it may still become a loop if ?A is FREE. The solution to both these problems is to recast the statement as

AND     ( NOT ?A IN MYSET
           OR . . .
         )

This has the twin advantages of providing an OR clause (in this case null) for the possibility that ?A is not in MYSET and of causing an Aspen SCM Expert System error if ?A is FREE.

Even where the statement ?A IN MYSET is a genuine test with actions and a corresponding OR clause, it is still better to invert it to a NOT ?A IN MYSET . . . OR structure because of the fail-safe handling of the possibility that ?A is FREE.

In order to ensure that loops work as loops, an IN statement which is intended to create a loop should be preceded by a FREE ?A statement. It is also desirable to check that the loop set is non-null:

AND     ?SIZE = SIZEOF MYSET
AND     ( ?SIZE EQ 0
           OR FREE ?A
              AND ?A IN MYSET
         )

Another good practice is to precede assertions of predicates by statements which explicitly FREE the return arguments. This helps the reader of the code and ensures that whether the predicate evaluates TRUE or FALSE it will have the same value in the calling rule, e.g.:

AND     FREE ?IPOS
AND     INDEX ?STRING ?SUBSTR 1 ?IPOS


Back                                Next
Comments