Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 3 Next »

Friendly enough expression language (FEEL) for the purpose of giving standard executable semantics to many kinds of expressions in decision model has the following features;

  • Side-effect free
  • Simple data model with numbers, dates, strings, lists and contexts
  • Simple syntax designed for a wide audience

  • Three-valued logic (true, false, null)

Data Types

FEEL supports the following datatypes:

  • number

  • string

  • boolean

  • days and time duration

  • years and months duration

  • time

  • date and time

  • list

  • context

Duration and date/time datatypes have no literal syntax. They must be constructed from a string representation using a built-in function (see conversion functions)

Contexts, Lists, Qualified Names

A context is a map of key-value pairs called context entries, and is written using curly braces to delimit the context, commas to separate the entries, and a colon to separate key and value. The key can be a string or a name. The value is an expression.

A list is written using square brackets to delimit the list, and commas to separate the list items. A singleton list is equal to its single item, Example "[e]=e" for all FEEL expressions.

Contexts and lists can reference other contexts and lists, giving rise to a directed acyclic graph. Naming is path based. The qualified name (QN) of a context entry is of the form "N1.N2 ... Nn" where N1 is the name of an in-scope context.

Nested lists encountered in the interpretation of N1.N2 ... Nn are preserved. For example,

    [{a: [{b: 1}, {b: [2.1, 2.2]}]}, {a: [{b: 3}, {b: 4}, {b: 5}]}].a.b =
    [[{b: 1}, {b: [2.1, 2.2]}], [{b: 3}, {b: 4}, {b: 5}]].b =
    [[1, [2.1, 2.1]],[ 3, 4, 5]]

Nested lists can be flattened using the flatten() built-in function.

Literal and Data Type Semantics

Equality

In general, the values to be compared must be of the same kind. For example; FEEL("1" = 1) = null

data typee1 = e2
listlists must be same length, and e1[n] = e2[n] must be equal
contextcontext must be same set of keys and every e1.key = e2.key must be equal
rangerange start and end points must be same
numbervalue of numbers must be equal
stringvalue of string must be equals with case sensitivity
dateall date components must be equal
date and timeall date and time components must be equal
timeall time components must be equal
days and time durationvalue of duration must be equal
years and months durationvalue of duration must be equal
booleanboth e1 and e2 must be true or false

number

Feel numbers based on decimal format, there is no integer or float data types. 

Literals consist of base 10 digits and an optional decimal point. –INF, +INF, and NaN literals are not supported. There is no distinction between -0 and 0. The number(from, grouping separator, decimal separator) built-in function supports a richer literal format. For example, FEEL(number("1.000.000,01", ".", ",")) = 1000000.01

There is no value for NaN, positiveInfinity, or negativeInfinity. Use null instead.

string

Literal strings can be double-quoted or single quoted sequence of characters. e.g. "abc" All strings compared as UTF-8 encoding.

boolean

Boolean literals are true and false.

time

Feel does not have time literals although time values can be expressed using a string literal and time built-in function.

Time values also have optional time zone offset. If no time zone offset specified, time is interpreted as local time of day.

Time data type has also provides an context of sequence of numbers for the hour, minute, second, and an optional time offset.

date

Feel does not have time literals although time values can be expressed using a string literal and date built-in function.

Date values has no time zone offset and interpreted as UTC time zone.

Date data type has also provides an context of sequence of numbers for the year, month, day of month.

date time

Feel does not have time literals although time values can be expressed using a string literal and date time built-in function.

Date time also have optional time zone offset. If no time zone offset specified, time is interpreted as UTC time zone.

Date time data type has also provides an context of sequence of numbers for the year, month, day, hour, minute, second, and optional time offset.

days and time duration

Feel does not have time literals although time values can be expressed using a string literal and days and time duration built-in function. Duration format expressed in ISO 8601 duration syntax.

Days and time duration data type has also provides an context of sequence of numbers for the days, hours, minutes, and seconds of duration and normalized such that the sum of these numbers is minimized. For example; FEEL(duration("P0DT25H")) = P1DT1H

years and months duration

Feel does not have time literals although time values can be expressed using a string literal and years and months duration built-in function. Duration format expressed in ISO 8601 duration syntax.

Days and time duration data type has also provides an context of sequence of numbers for the years and months of duration and normalized such that the sum of these numbers is minimized. For example; FEEL(duration("P0Y13M")) = P1Y1M

Lists and filters

Lists are immutable and may be nested. First element of list can be accessed using L[1] and last element accessed using L[-1]. If no element exists in list then L[n] = null.

Lists can be filtered with a boolean expression in square brackets. The expression in square brackets can reference a list element using name "item". If list entries is a context, item entries may be referenced within filter expression without item prefix. For example;

    [1, 2, 3, 4][item > 2] = [3, 4]
    [{x:1, y:2}, {x:2, y:3}][x=1] = {x:1, y:2}

For convenience a selection using "." operator with a list of contexts on its left hand side returns a list of selections. For example;

    [{x:1, y:2}, {x:2, y:3}].y = [2,3]

Context

Context is a collection of key and expression pairs called context entries. Keys are mapped to string values. The syntax for selecting value of context entry named key1 from context1 is "context1.key1"

To retrieve a list of key,value pairs from a context m, the following built-in function may be used: get entries(m).

Range

Feel supports the compact syntax for range of values. 

Negation

Negation is performed with builtin not function. Semantics of negation is;

anot(a)
truefalse
falsetrue
otherwisenull

Binary logic

Binary logic can be expressed with "and" and "or" keywords. Binary logic semantics;

aba and ba or b
truetruetruetrue
truefalsefalsetrue
trueotherwisenulltrue
falsetruefalse

true

falsefalsefalsefalse
falseotherwisefalsenull
otherwiseotherwisenullnull

Xml Data Mapping

FEEL supports the xml data context in contexts. Xml namespaces are not supported but elements can be accessed with prefix. All xml values are interpreted as string values.

XMLcontext entryRemarks
<e />e : nullempty element mapped to null value.
<n:e />n$e : nullnamespaces are ignored and prefix can be used to access entry.
<e>v</e>e : "v"single element with value
<e>v1</e><e>v2</e>e : ["v1","v2"]repeating element with value

<e a="v">v1</e>

e$a : "v"

e : "v1"

attributes are prefixed with @

element value accessed with name

<e a="v">v1

<c>v1</c>

</e>

e$a : "v",

e.c : "v1"

attributes are prefixed with @

childs accessed with name

Builtin Functions

To promote interoperability, FEEL includes a library of built-in functions. The syntax and semantics of the built-ins are required for a conformant FEEL implementation.

Conversion Functions

FEEL supports many conversions between values of different types. Of particular importance is the conversion from strings to dates, times, and durations. There is no literal representation for date, time, or duration. Also, formatted numbers such as 1,000.00 must be converted from a string by specifying the grouping separator and the decimal separator.

Name and ParametersParameterDescriptionExample

date(from)

date string

convert from to a date

date("2012-12-25") – date("2012-12-24") = duration("P1D")

date(from)

date and time

convert from to a date (set time components to null)

date(date and time("2012-12-25T11:00:00Z")) = date("2012-12-25")

date(year, month, day)

year, month, day are numbers

creates a date from year, month, day component values

date(2012, 12, 25) = date("2012-12-25")

date and time(date, time)

date is a date or date time; time is a time

creates a date time from the given date (ignoring any time component) and the given time

date and time ("2012-12-24T23:59:00") = date and time (date("2012-12-24”), time(“T23:59:00"))

date and time(from)

date time string

convert from to a date and time

date and time("2012-12-24T23:59:00") + duration("PT1M") = date and time("2012-12- 25T00:00:00")

time(from)

time string

convert from to time

time("23:59:00z") + duration("PT2M") = time("00:01:00@Etc/UTC")

time(from)

time, date and time

convert from to time (ignoring date components)

time(date and time("2012-12-25T11:00:00Z")) = time("11:00:00Z")

time(hour, minute, second, offset)

hour, minute, second, are numbers, offset is a days and time duration, or null

creates a time from the given component values

time(“T23:59:00z") = time(23, 59, 0, duration(“PT0H”))

number(from, grouping separator, decimal separator)

string, string, string

convert from to a number

number("1 000,0", " ", ",") = number("1,000.0", ",", ".")

string(from)

non-null

convert from to a string

string(1.1) = "1.1" string(null) = null

duration(from)

duration string

convert from to a days and time or years and months duration

date and time("2012-12-24T23:59:00") - date and time("2012-12-22T03:45:00") = duration("P2DT20H14M")

duration("P2Y2M") = duration("P26M")

years and months duration(from, to)

both are date and time

return years and months duration between from and to

years and months duration( date("2011-12-22"), date("2013-08-24") ) =

duration("P1Y8M")

Boolean Functions

Name and ParametersParameterDescriptionExample
boolean(from)stringboolean conversion

boolean("true") = true

boolean("false") = false

boolean(true) = true

not(negand)

boolean

logical negation

not(true) = false

not(null) = null

String Functions

Name and ParametersParameterDescriptionExample

substring(string, start position, length?)

string, number

return length (or all) characters in string, starting at start position. 1st position is 1, last position is -1

substring("foobar",3) = "obar"
substring("foobar",3,3) = "oba"
substring("foobar", -2, 1) = "a"

string length(string)

string

return length of string

string length("foo") = 3

upper case(string)

string

return uppercased string

upper case("aBc4") = "ABC4"

lower case(string)

string

return lowercased string

lower case("aBc4") = "abc4"

substring before (string, match)

string, string

return substring of string before the match in string

substring before("foobar", "bar") = "foo"
substring before("foobar", "xyz") = ""

substring after (string, match)

string, string

return substring of string after the match in string

substring after("foobar", "ob") = "ar"
substring after("", "a") = ""

replace(input, pattern, replacement, flags?)

string

regular expression pattern matching and replacement

replace("abcd", "(ab)|(a)", "[1=$1][2=$2]") = "[1=ab][2=]cd"

contains(string, match)

string

does the string contain the match ?

contains("foobar", "of") = false

starts with(string, match)

string

does the string start with the match ?

starts with("foobar", "fo") = true

ends with(string, match)

string

does the string end with the match ?

ends with("foobar", "r") = true

matches(input, pattern, flags?)

string

does the input match the regexp pattern ?

matches("foobar", "^fo*b") = true

List Functions

Name and ParametersParameterDescriptionExample

list contains(list, element)

list, any element of the semantic domain including null

does the list contain the element ?

list contains([1,2,3], 2) = true

count(list)

list

return size of list

count([1,2,3]) = 3

min(list)
min(c1,..., cN), N >1 max(list)
max(c1,..., cN), N >1

(list of) comparable items

return minimum item
return maximum item

min([1,2,3]) = 1
min(1,2,3) = 1
max([1,2,3]) = 3
max(1,2,3) = 3

sum(list)
sum(
n1,..., nN), N >1

(list of) numbers

return sum of numbers

sum([1,2,3]) = 6
sum(1,2,3) = 6

mean(list)
mean(
n1,..., nN), N >1

(list of) numbers

return arithmetic mean (average) of numbers

mean([1,2,3]) = 2
mean(1,2,3) = 2

and(list)
and(
b1,..., bN), N >1

(list of) Boolean items

return false if any item is false, else true if all items are true, else null

and([false,null,true]) = false and(false,null,true) = false
and([]) = true
and(0) = null

or(list)
or(
b1,..., bN), N >1

(list of) Boolean items

return true if any item is true, else false if all items are false, else null

or([false,null,true]) = true
or(false,null,true) = true
or([]) = false
or(0) = null

sublist(list, start position, length?)

list, number1, number2

return list of length (or all) elements of list, starting with list[start position]. 1st position is 1, last position is -1

sublist([1,2,3], 1, 2) = [2]

append(list, item...)

list, any element including null

return new list with items appended

append([1], 2, 3) = [1,2,3]

concatenate(list...)

list

return new list that is a concatenation of the arguments

concatenate([1,2],[3]) = [1,2,3]

insert before(list, position, newItem)

list, number1, any element including null

return new list with newItem inserted at position

insert before([1,3],1,2) = [1,2,3]

remove(list, position)

list, number1

list with item at position removed

remove([1,2,3], 2) = [1,3]

reverse(list)

list

reverse the list

reverse([1,2,3]) = [3,2,1]

index of(list, match)

list, any element including null

return ascending list of list positions containing match

index of([1,2,3,2],2) = [2,4]

union(list...)

list

concatenate with duplicate removal

union([1,2],[2,3]) = [1,2,3]

distinct values(list)

list

duplicate removal

distinct values([1,2,3,2,1] = [1,2,3]

flatten(list)

list

flatten nested lists

flatten([[1,2],[[3]], 4]) = [1,2,3,4]

Numeric functions

Name and ParametersParameterDescriptionExample

decimal(n, scale)

number, number1

return n with given scale

decimal(1/3, 2) = .33
decimal(1.5, 0) = 2
decimal(2.5, 0) = 2

floor(n)

number

return greatest integer <= n

floor(1.5) = 1
floor(-1.5) = -2

ceiling(n)

number

return smallest integer >= n

ceiling(1.5) = 2
ceiling(-1.5) = -1

  • No labels