Introduction to UserFuncs and Expressions

A UserFunc Block is like an STFunc or OAFunc or NAFunc, etc., but the UserFunc framework is more general and powerful (and complicated). UserFuncs can call other (user-defined) UserFuncs, and they allow more general function signatures, with vector arguments and results

This is an example of a very simple UserFunc that takes a single scalar argument (of float type) and squares it:

<UserFunc square>
  kind = expression
  inputOrder = [b]
  <Input b>
    kind = arbitraryVector
    types = [float]
  </Input>
  expression = b^2
</UserFunc>

A few terms, very briefly:

  • An <Expression> block is like a UserFunc of kind = expression, except that the <Expression> block does not have to specify the inputOrder or <Input> blocks. See expression.
  • An Input Block block describes the (vector-)length and types of an input argument to the function. Along with the inputOrder attribute, the <Input> blocks give the input signature of the function: the number and types of arguments.
  • Local UserFuncs are UserFunc (sub)blocks that appear within a UserFunc block (usually of kind = expression).
  • A Term Block is a cross between an <Input> and a local <UserFunc>. It is a term that can be used (e.g., in an expression), but its value is not passed to the function as an argument, but rather found by evaluating a local function. Even when a Term appears more than once (or not at all) in an expression, the Term is evaluated exactly once; in contrast, a local UserFunc may be evaluated once for each time it appears, or not at all if its result is not needed. Moreover, a local UserFunc can be called multiple times in the same expression with different arguments.