Evaluation at Score Loading Time

When a score loads, some expressions can be evaluated and some actions can be performed. This makes it possible to pre-compute some data or to run some initialization before the real running of the program.

Constant Expressions

Constant expressions are expressions whose values do not depend on context and are independent of the date at which the expression is evaluated.

Determining if an expression is a constant expression is difficult. But Antescofo detects a large subset of constant expressions and evaluates them when the score is loaded. The idea is to speed up the actual program run as much as possible by doing some evaluations beforehand.

So for instance

        let $x := 1 + @sin(3.1415)

is internally rewritten in

        let $x :=  1.00009

Expression with variables are not constant expression (even if there no assignment in scope, variables can be assigned externally using setvar and their value is always supposed unknown). The application of a user-defined functions is not a constant expression like the impure predefined functions.

Constant expressions are detected in actions. However, it is also possible to write constant expressions in a BPM specification.

          BPM (1.1*120)

This seems useless but it combines well with macro-definition:

          @macro_def @BaseTempo { 120 }
          ; ...
          BPM @BaseTempo
          ; ...
          BPM (@BaseTempo + 10)

Which makes it possible to change the base tempo of a piece by changing only the macro-definition.

@eval_when_load Clause

A @eval_when_load clause specifies a list of actions that must be performed just after loading a file and before the run of the program. Several such clauses may exist in a file: they are performed in the order of appearance right after having completed the parsing of the full score.

Such a clause can be used, for instance, to read some parameter saved in a file or to precompute some values. For example

          @fun_def fib($x)
            if ($x < 2) { return 1 }
            else { return @fib($x-1) +@fib($x-2) }

          @eval_when_load {
            $fib36 := @fib(36)

          ; ...

          NOTE C4
            print $fib36

When this file is loaded, the clause is evaluated to compute @fib(36) which takes a noticeable amount of time because it is uses a doubly recursive function. This value is then used when the program is started and the C4 event occurs, without requiring a costly computation. If not for evaluation at load time, the performance would be interrupted by complex computations like this one.

By using @insert, @insert_once, @eval_when_load and the Antescofo preload commands, together with functions @dumpvar, @loadvar, @loadvalue and @savevalue, one can manage a library of reusable functions and reusable setups mutualized between pieces.