Expr demystified

From ftm

This is a simple explanation for the use of the EXPR class. See also Expression_Class_Arguments in the FAQ.

Creation - Elements of the call

An EXPRession is a sentence which can be applied to the content of an fmat or an fvec. It can be created in an ftm.object (class expr) or in an FTM message box ftm.mess. In both case, it shares the same syntax:

  1. it starts with expr
  2. it is then followed by any code that could be entered into a ftm.mess but it needs to be surrounded by simple quotes ' '
  3. to be evaluated the code has to be encapsulated within parenthesis (just like any code in ftm.mess)

For example, the expression returning the value 1 is

expr '1'

Expression returning a tuple {1 2 3} could be:

expr '1 (1 + 1) (1 + 2)' 

because a list is automatically converted into a tuple, or more directly:

expr '{1 2 3}'

But the following expression returns just 3:

expr '1, (1 + 1), (1 + 2)'

Although all of the the comma separated parts are executed, only the last one is returned. So in the following example, after first execution the value returned would be 9:

expr '($var += 10), ($var - 1)'

where var is a global variable which was initialized to 0. Since both parts are executed, var is first incremented by 10, but only the result of ($var - 1) is returned. After second execution the returned value would be 19, after third 29, and so on.

You can use all the FTM Functions available to create your expression. Moreover, $1, $2, etc will be replaced by values passed to your instance of expr.

For example, the expression returning the sinus of its input is

expr '(sin $1)'

There are two places you can create a new expr instance:

as shown in the ftm.class.expr.maxhelp document. On the left, you put the expression, on the right its name, the latter being the way to call the expression

(new expr '(sin $1)')

where it can be evaluated using its eval method:

((new expr '(sin $1)') eval $pi)  

pi being a local variable passed as first argument to the expression (replacing $1).

or passed as an argument to a method to another object, like in the following example:

((new fmat 10 3) fill (new expr '(random 1 3)'))

Scope of variables

In the previous example, you could be tempted to use $1 and $2 to choose the boundaries of the random function within the expression but the variables $1 and $2 would not refer to the ftm.mess inputs, but to the expression arguments. We therefore need to pass those input variables (local to the ftm.mess) as arguments to our newly created instance of expr by placing them directly after expr statement:

 ((new fmat 10 3) fill (new expr '(random $1 $2)') $1 $2)

In the case our expression has been previously defined in a ftm.object and named for example randomize the above could look like this:

((new fmat 10 3) fill $randomize $1 $2) 

Special Variables

Depending of context of use, an expr instance has access to some specific variables

  • fmat
    • Fill
      • $row - the row number of currently processed element of a fmat
      • $col - the col number of currently processed element of a fmat
      • $self - reference to currently processed fmat
    For example:
    ((new fmat 10 2) fill (new expr '(($self rows) - $row - $col)'))
    would return a fmat filled with numbers from 10 to 1 in its first column, and 9 to 0 in the second.
    • Apply
      • $x - the value of currently processed element of fmat
      • $self - reference to currently processed fmat
    • Find
      • $x - the value of currently processed element of fmat
      • $i - the index of currently processed element of fmat
      • $self - reference to currently processed fmat

with $i growing row by row in a column and continuing from the beginning of the next column as if the columns were placed on after another in a single vector.

  • fvec
    • Fill
      • $idx - the index number of currently processed element of a fvec
      • $self - reference to currently processed fvec
    • Apply
      • $x - the value of currently processed element of fvec
      • $self - reference to currently processed fvec