Skip to main content

FEEL Syntax

Friendly Enough Expression Language (FEEL) is standardized by OMG. It is a side-effect-free expression language designed to be easy for business professionals to read and write.

Data Types​

FEEL allows you to work with rich data types.

Primitive Types​

TypeDescriptionExamples
NumberHigh-precision decimal numbers. Supports scientific notation.10, -5.2, 1.5e3
StringText enclosed in double quotes. Special characters can be escaped."Hello World", "Bob's ID", "\u0009"
BooleanLogical true or false.true, false
NullRepresents a missing or unknown value.null

Temporal Types​

FEEL has first-class support for dates and times.

Date: date("2023-12-31") Time: time("14:30:00") or time("14:30:00@Europe/Paris") Date and Time: date and time("2023-12-31T14:30:00") Duration: Day-Time: duration("P2DT5H") (2 Days, 5 Hours) Year-Month: duration("P1Y6M") (1 Year, 6 Months)

Composite Types​

Lists​

Ordered collections of values. Elements can be of any type, including other lists.

[1, 2, 3, 4]
["Red", "Green", "Blue"]
[{x:1}, {x:2}]

Contexts​

A set of key-value pairs, similar to a JSON object or a Map.

{
"Customer Name": "Alice",
"Age": 30,
"Address": {
"City": "New York",
"Zip": "10001"
}
}

Expressions​

Arithmetic​

Standard mathematical operations are supported.

10 + 5      // 15
10 - 2 // 8
10 * 3 // 30
20 / 4 // 5
2 ** 3 // 8 (Exponentiation)
(10 + 2) * 3 // 36

Boolean Logic​

FEEL uses three-valued logic (true, false, null).

  • AND: true and true -> true
  • OR: true or false -> true
  • Equality: Price = 100
  • Inequality: Price != 100
  • Comparison: Price > 50, Price <= 200

Conditional (If-Then-Else)​

Evaluates a condition and returns one of two values.

if Age >= 18 then "Adult" else "Minor"

Flow Control​

For Loops​

Iterate over lists to transform primitive values or objects.

for x in [1, 2, 3] return x * 2  // [2, 4, 6]

Quantified Expressions​

Check if some or every element in a list satisfies a condition.

some price in [10, 20, 30] satisfies price > 25  // true
every price in [10, 20, 30] satisfies price > 5 // true

Unary Tests​

Unary tests are expressions that test a single input value (implicit ?). They are primarily used in Decision Tables (in the input entries) or with the in operator.

Test TypeSyntaxMeaning
Literal"High"The input MUST match "High"
Numeric10The input MUST be 10
Comparison&lt; 10The input MUST be less than 10
Interval[1..10]Inclusive: 1 <= input <= 10
Interval(1..10)Exclusive: 1 < input < 10
Negationnot(10)Any value EXCEPT 10
List1, 2, 3Input matches any item (OR logic)
Generalizednot(1, 2)Neither 1 nor 2

Runtime Errors and Null​

A runtime error is an expression that parses but cannot work with the values it gets, such as string length(null), context(null), 10 / 0 or date("not a date"). What happens next depends on the error mode the deployment runs in (ERROR_MODE, see configuration):

  • Strict (the default) stops the evaluation and reports where the failing part starts, for example line 2, column 5: context: entries argument cannot be null.
  • Lenient follows the FEEL spec. Only the failing part becomes null, the rest of the expression keeps its value, and the error is reported as a warning next to the result.
{a: 1, b: context(null)}
// strict: line 1, column 11: context: entries argument cannot be null
// lenient: {a: 1, b: null} with one warning

Unknown names, calling something that is not a function, and exceeding the evaluation limits are errors in both modes. A filter such as orders[amount > 100] drops an element it cannot evaluate in either mode, without a warning.

Built-in Functions​

FEEL includes a standard library of functions. See the built-in functions reference for the full list.

  • count([1, 2, 3]) -> 3
  • sum([10, 20]) -> 30
  • string length("foo") -> 3
  • upper case("hello") -> "HELLO"
  • contains("foobar", "bar") -> true

Comments​

Code can be annotated with comments.

// This is a single line comment
10 + 10

/*
This is a
block comment
*/