## §5.4 Guard predicates

→ Syntax §A.7

The effect of callins can further be controlled using so called guard predicates. Guards appear at four different levels:

- callin method binding
- role method
- role class
- team class

Guards can be specified as regular guards or `base` guards, which affects the exact point in the control flow, where the guard will be evaluated.

#### (a) General syntax for guards

A guard is declared using the keyword `when` followed by a boolean expression in parentheses:

    when (predicateExpression)

Depending on the kind of guard different objects are in scope using special identifiers like `this`, `base`.
Any predicate expression that evaluates to `true` enables the callin binding(s) to which it applies. Evaluation to `false` disables the callin binding(s).

#### (b) No side effects

A guard predicate should have no side effects. A compiler should optionally check this condition, but inter-procedural analysis actually depends on the availability of appropriate means to mark any method as side-effect free.

#### (c) Exceptions

A guard predicate should not throw any exceptions. Yet, any exception thrown within a guard predicate cause the guard to evaluate to `false` rather than propagating the exception, meaning that the evaluation of a guard predicate will never interrupt the current base behaviour.
A compiler should flag any checked exception that is thrown within a guard. Such diagnosis should by default be treated as an error, with the option of configuring its severity to warning or ignore.

### §5.4.1 Regular guards↑ §5.4

This group of guards evaluates within the context of a given role. These guards are evaluated after a callin target is lifted and before a callin bound role method is invoked.

#### (a) Method binding guards

A guard may be attached to a callin method binding as in:

    void roleMethod(int ir) <- after void baseMethod(int ib)
      when (ir > MyTeam.this.threshold);

Such a guard only affects the callin binding to which it is attached, i.e., this specific callin binding is only effective, if the predicate evaluates to `true`.
The following values are within the scope of the predicate expression, and thus can be used to express the condition:

- The role instance denoted by `this`.
  Features of the role instance can also be accessed relative to `this` with or without explicit qualifying `this`.
- The team instance denoted by a qualified this reference as in `MyTeam.this`.
- If the callin binding includes signatures (as in the example above): Parameters of the role method.
  If parameter mappings are involved, they will be evaluated before evaluating the guard.

#### (b) Method guards

A method guard is similar to a method binding guard, but it applies to all callin method bindings of this method.
A method guard is declared between the method signature and the method body:

    void roleMethod(int ir)
      when (ir > MyTeam.this.threshold) { body statements }

#### (c) Role level guards

When a guard is specified at the role level, i.e., directly before the class body of a role class, it applies to all callin method bindings of the role class:

    protected class MyRole
      when (value > MyTeam.this.threshold)
    {
        int value;
        other class body declarations
    }

The following values are within the scope of the predicate expression:

- The role instance denoted by `this` (explicit or implicit, see above). Thus, in the example `value` will be interpreted as a field of the enclosing role.
- The team instance denoted by a qualified this reference as in `MyTeam.this`

#### (d) Team level guards

A guard specified in the header of a team class may disable the callin bindings of all contained role classes. The syntax corresponds to the syntax of role level guards.
The only value directly available within team level guard is the team instance (denoted by `this`) and its features.

Of course all guards can also access any visible static feature of a visible class.

Even if a guard has no direct effect, because, e.g., a role class has no callin bindings (maybe not even a role-base binding), predicates at such abstract levels are useful, because all predicates are inherited by all sub classes (explicit and implicit).

### §5.4.2 Base guards↑ §5.4

The intention behind base guards is to prevent lifting of a callin-target if a guard evaluates to `false` and thus refuses to invoke the callin bound role method. Using base guards it is easier to prevent any side-effects caused by a callin binding, because lifting could cause side-effects at two levels:

- Creating a role on-demand already is a side-effect (observable e.g. by the reflective function `hasRole (§6.1)`)
- Role creation triggers execution of a role constructor (see custom lifting constructor (§2.3.1.(c))) which could produce arbitrary side-effects.

Both kinds of side-effects can be avoided using a base guard which prevents unnecessary lifting.

Any guard (5.4.1 (b)-(e)) can be turned into a base guard by adding the modifier `base` as in:

    protected class MyRole playedBy MyBase
      base when (base.value > MyTeam.this.threshold)
    {
        class body declarations
    }

However, different scoping rules apply for the identifiers that can be used in a base guard:

#### (a) Base object reference

In all base guard predicates the special identifier `base` can be used to denote the base object that is about to be lifted.

#### (b) Method binding guards

A base method binding guard may access parameters as passed to the base method. Parameter mappings are not considered.
Additionally, for `after` callin bindings, the identifier `result` may be used to refer to the result of the base method (if any).

##### Note:

In order to achieve the same effect of accessing the base method's result, a regular binding guard (not a base guard) must use a suitable parameter mapping (see §4.4.(c)).

#### (c) Method guards

In contrast to regular method guards, a base guard attached to a role method cannot access any method parameters. See the next item (d) for values that are actually in scope.

#### (d) Role level guards

Role level base guards may use these values:

- The base instance using the special identifier `base`.
- The team instance using a qualified this references (`MyTeam.this`).

#### (e) Team level guards

Team level base guards have the same scope as role level base guards (d). However, the type of the role instance is not known here, i.e., here `base` has the static type `java.lang.Object`.

#### (f) Unbound roles

In contrast to regular guards, base guards cannot be attached to unbound role classes nor to their methods.
Only team level base guards are independent of role binding.

### §5.4.3 Multiple guards↑ §5.4

Due to the different ranges of applicability different guards may affect the same method binding. In that case all applicable guards are conjoined using a logical `and`.
Any guard is interpreted as the conjunction of these predicates (if present):

- The direct predicate expression of the guard.
- The next outer guard along the chain method binding -> method -> role level -> team level
- The guard at the same level that is inherited from the implicit super role.
- The guard at the same level that is inherited from the explicit super role.

##### Example code (Guard Predicates):

1

    public team class ATM {

2

      private Bank myBank;

3

      public class ForeignAccount playedBy Account

4

        base when (!ATM.this.myBank.equals(base.getBank()))

5

      {

6

        callin void debitWithFee(int amount) {

7

          base.debitWithFee(fee+amount);

8

        }

9

        void debitWithFee(int i) <- replace void debit(int amount)

10

          base when (amount < 1000);

11

      }

12

    }

##### Effects:

The team in this example causes that an additional fee has to be payed while debiting less than 1000 Euros from a "foreign" account.

- The base guard in line 4 ensures that `Account` objects only get `ForeignAccount` roles, if they belong to a different bank than the surrounding `ATM` team.
  It accesses the bank of the base via the `base` identifier.
- The method binding guard in line 10 restricts the callin to `debitWithFee` to calls where the base method argument `amount` is lower than 1000.
- A call to `Account.debit` causes a replace callin to `debitWithFee` only if both predicates evaluate to true.