IF and SWITCH: Conditional and Alternative


IF: Conditional Actions

A conditional action is a construct that performs different actions depending on whether a programmer-specified boolean condition evaluates to true or false. A conditional action takes the form:

          if (boolean_expression)
          {
                ... actions launched if the condition evaluates to true ...
          }

or

          if (boolean_expression)
          {
                ... actions launched if the condition evaluates to true ...
          }
          else
          { 
                ... actions launched if the condition evaluates to false ...
          }

Like other actions, a conditional action can be prefixed by a delay. Note that the actions in the if and in the else clause are evaluated as if they are in a group. So, the delay of these actions does not impact the timing of the actions which follow the conditional. For example

          if ($x) { 5 print HELLO }
          1 print DONE

will print DONE one beat after the start of the conditional independently of the value of the condition.

The actions of the “true” (resp. of the “else”) parts of a condition are members of an implicit group named xxx_true_body (resp. xxx_false_body) where xxx is the label of the conditional itself. The attribute of if are used for these groups.

There are also conditional expressions (sections Conditional Expression and Extended Expression If) that share a similar syntax.

Any kind of Antescofo value can be interpreted as a boolean value, see sections scalar values and data structures.


SWITCH: Alternative Actions

Alternative actions extend conditional actions to handle several alternatives. At most one of the alternative will be performed. They are two forms of alternative actions, without and with selector, which differ by the way the alternative to execute is chosen.

There are also alternatives expressions (section switch expression) that share a similar syntax in the context of function definitions.

Alternative Actions without Selectors

An alternative action without a selector is simply a sequence of cases guarded by expressions. The guards are evaluated in the sequence order and the action performed is the first case whose guard evaluates to a true value. So :

          switch
          {
               case e₁: a₁  
               case e₂: a₂
               ; ...
          }

(where e₁, e₂... are arbitrary expressions and a₁, a₂... are sequences of actions) can be rewritten in:

          if ( e₁ )  { a₁  }
          else
          {
               switch
               {
                    case e₂: a₂
                    ; ...
               }
          }

If no guard is true, then no action is performed. Notice that several actions can be associated to a case : they are launched as a group.

Here is an example where the evaluation order matters: the idea is to rank the value of the variable $x. The following code

          whenever ($PITCH)
          {
               switch
               {
                    case $PITCH < 80:
                         $octave := 1

                    case $PITCH < 92:
                         $octave := 2

                    case $PITCH < 104:
                         $octave := 3
               } 
         }

uses a whenever to set the variable $octave to some value each time $PITCH is updated for a value below 104.

Note that the actions associated to a case are evaluated as if they are in a group. So the eventual delay of these actions does not impact the timing of the actions which follows the alternative. And like other actions, an alternative action can be prefixed by a delay.

Alternative Action with a Selector

In this form, a selector is evaluated and checked in turn against each guard of the cases:

          switch (s)
          {
               case e₁: a₁  
               case e₂: a₂
               ; ...
          }

The evaluation proceeds as follows: the selector s is evaluated and then, the result is checked in turn with the result of the evaluation of the e_i:

  • If eᵢ evaluates to a function, this function is assumed to be a unary predicate and is applied to s. If the application returns a true value, the sequence of actions aᵢ is performed.

  • If eᵢ is not a function, the values of s and eᵢ are compared with the operator ==. If it returns a true value, the sequence of actions aᵢ is performed.

The evaluation start with e₁ and stops as soon as an action is performed for one of the eᵢ. If no guard checks true, no action is performed.

For example:

          switch ($x)
          {
               case 0: 
                  $zero := true
               case @size: 
                  $empty := false
                  $zero := false
          }

checks a variable $x and sets the variable $zero to true if $x == 0 or 0.0 (because 0.0 == 0). It then sets the variable $empty and $zero to false if $x refers to a non-empty tab or to a non-empty map (because function @size returns an integer which is 0 only if its argument is an empty tab or an empty map).