Feel.Builtin.Context (feel v0.1.0)

Copy Markdown View Source

The context functions of FEEL (DMN 1.6, section 10.3.4.10, Table 82): get value, get entries, context, context put and context merge.

What is written (D-79)

CallResult
get value(m, key)the value of the entry key of the context m; null if there is none
get entries(m)a list of contexts {key: ..., value: ...}, one for each entry
context(entries)the context of a list of such contexts
context put(context, key, value)the context with the entry key set to value, added or replaced
context put(context, keys, value)the same at the end of a path of keys, through the contexts in between
context merge(contexts)the entries of all the contexts of the list; a later one wins for a key

The result of a function is a new context: the one that was given is not changed.

An entry that is not there is null for get value, as the second example of the table has it, and it is no error. A path (m.key) with a key the context does not have is an error (TCK, 0057 #009), and get value is the one that is not: its example says null, and the TCK has no case for it.

context(entries) takes a list of contexts that have a key, a string, and a value, which can be null; other entries of an item are left out. An item without a key or without a value, a key that is null or not a string, an item that is no context, and two items with one key, make the whole result null with an error: the first three are what the table says, and the last is what the TCK has (1145 #003) where the notes (A16) thought of the later item winning. A context in place of the list is the list of it (section 10.3.2.9.4), so context({key: "a", value: 1}) is {a: 1}.

context put with keys puts the value at the end of the path, context put({x: 1, y: {a: 0}}, ["y", "a"], 2) being {x: 1, y: {a: 2}}. Every key but the last has to be an entry that is a context: where it is not there, or is a value of another kind, the result is null with an error (TCK 1146, #nested009; the table is silent, A18), and it makes no contexts of its own. A path with no key, or with a key that is null or not a string, is out of the domain as well.

context merge does not look into the contexts: the entry of the later context is the entry, so context merge([{a: {b: 1}}, {a: {c: 2}}]) is {a: {c: 2}} (TCK 1147 #004).

The order of the entries (D-135)

A context keeps the order of its entries (Feel.Value.Context), and these are the functions that show it:

  • get entries has the entries in the order they have;
  • context(entries) has the order of the list;
  • context put puts a new entry last, and an entry that is put again stays where it was (context put({x: 1, y: 2}, "x", 3) is {x: 3, y: 2});
  • context merge keeps the entries of the first context where they are and adds the new ones of the next after them, in their order: context merge([{x: 1, y: 0}, {z: 3, y: 2}]) is {x: 1, y: 2, z: 3}.

The specification's examples are all in this order, and the TCK has no case that tells it from the order of the keys (D-135), so what it says is kept either way. A context that a host binds as a plain map has the order of its keys.

What a call by name cannot tell

context put(context, key, value) and context put(context, keys, value) are two signatures that differ in the type of the second parameter, and the function is given the values and not the signature that a call by name chose. So a call with a list for key: would be a call with keys:, where the TCK has null for it (1146 #nested008). It is not, since D-56: the analyzer has the signature that the names chose and the type of the argument, and a list of two for a string is a mismatch that makes the call null with its error (Feel.Analysis.Calls.mismatch/3); and a call by name carries that signature to the run, which checks the values against it (Feel.Builtin.call/4), so a list that is bound to a name when the run begins is the same.

A null argument, and one of another kind, is out of the domain: the result is null with an :argument_out_of_domain error. A list of one context is that context, for a context parameter.

Summary

Functions

The functions of this module that are written, as Feel.Builtin.Functions: all five.

Returns the canonical names of the functions of this module, sorted.

Functions

functions()

@spec functions() :: [Feel.Builtin.Function.t()]

The functions of this module that are written, as Feel.Builtin.Functions: all five.

iex> length(Feel.Builtin.Context.functions())
5

names()

@spec names() :: [Feel.Name.t()]

Returns the canonical names of the functions of this module, sorted.

iex> "get value" in Feel.Builtin.Context.names()
true