A function takes zero or more values, and produce another value. A function call consists of a function name (an identifier), followed by its arguments enclosed in parentheses. An argument can be any expression. Different arguments are separated by commas (,) or semicolons (;) — for one function call, all separators must be the same. 

Examples:

  • NOW()
  • ROUND(storyPoints / 10)
  • FILTER(sprint, $.state = "active")

  • MAKE_DATETIME(2017; 12; 31; 23; 59; 59)
  • myUserFunction("argument1", "argument2")

A function call can evaluate only some or even none of the arguments, depending on the function. This is useful for functions that perform choices. For example, in an IF function, the argument that wasn't chosen is not evaluated, so the whole expression doesn't produce an error when that argument produces an error.

System and User Functions

System functions are provided by Structure. The functions are listed in the Expr Function Reference. Each function expects a certain number and type of parameters.

User functions are explained in the next section. A user function is called using the same syntax as a system function.

User functions can take any number of arguments, regardless of how many arguments are declared. If a parameter was declared, but a value was not provided when calling the function, the parameter's value will be undefined.

Chained Function Calls

A different way to call a function is by "chaining" it to its first argument by adding a period ("."), a function name, parentheses, and any additional parameters, if any.

For example, sprint.FILTER($.state = "active") is the same as FILTER(sprint, $.state = "active").

This allows nice, readable expressions, where a value is sequentially transformed by applying functions to the result of a previous function call:

  • affectsVersion.MAP($.releaseDate - $.startDate).MAX()

  • linkedIssues.FILTER(x -> NOT x.resolution).MAP(x -> x.remainingEstimate).SUM()

Unlike some other languages, in Expr any function may be written in the chained syntax, regardless of what the value is.

Applying Functions to Arrays

When a function is applied to an array value (meaning that an array is passed as the first argument of the function), the result may be calculated in a number of ways, depending on which function is called and what type of argument it expects.

You can always apply a function to each element of an array using the MAP function. For example:

  • array.MAP(SOME_FUNCTION($))

The cases below relate to cases where an array is passed directly as an argument: SOME_FUNCTION(array).

Using an Array Function

There are special functions that expect an array as their first argument – FILTERMAP, and others.

There's no special behavior in this case – an array is expected. In fact, if the value passed is not an array, it will be converted to either an array of one element (containing that value), or an empty array if the value is undefined.

Passing Array as an Argument of Text/Joined Type

If a function declares that it expects "Text/Joined" as an argument, then the system will try to convert an array into a text value. See the "Text vs Text/Joined" section above.

For example:

  • CONCAT("Versions: ", fixVersion) → "Versions: v1, v2, v3"

Passing Array as an Argument of /Each Type

If a function declares that it expects "Number/Each" or "Text/Each" or any other "/Each" type as an argument, then it would work on that simple type, but if an array is passed, it will apply its logic to each element in that array. The result of calling this function will be an array, where each element is a result of applying the function to the original element.

For example:

  • UPPER(fixVersion) → ARRAY("V1", "V2", "V3")

In addition, when applying a function to an array in this way, the resulting array is "flattened" (elements from any sub-arrays moved to be the elements of the top array) and "compacted" (all undefined elements are removed).

Passing Array to a User Function

You can call a user function and pass an array as an argument. No special handling takes place – just as with a system function expecting an array.

All Other Cases

If a system function does not expect an array, but it is passed as an argument, it will try to convert it to the value type it expects. A one-element array will be converted to its single element and an empty array will be converted to undefined. See "Value Conversions" above.

If the conversion is not possible, the result will be an error.