Expression DSL Reference¶
Constants¶
Keyword | Description | Syntax |
---|---|---|
Noop | No operation
Returns true without input validation. Used in place of matchers for uninteresting signals. Aliases: _ |
Const |
Null | Null value | Const |
True | Logical true | Const |
False | Logical false | Const |
Pi | Pi constant | Const |
E | Euler's number | Const |
Inf | Infinity | Const |
Eps | Machine epsilon | Const |
NaN | Not a number | Const |
Thread | Thread id
Not really a constant, but useful for branching the test input conditions. |
Const |
Math Functions¶
Keyword | Description | Syntax |
---|---|---|
Sin | Sinus | Unary |
Cos | Cosinus | Unary |
Tan | Tangens | Unary |
Asin | Arcsin | Unary |
Acos | Arccos | Unary |
Atan | Arctan | Unary |
Sinh | Hyperbolic sin | Unary |
Cosh | Hyperbolic cos | Unary |
Tanh | Hyperbolic tan | Unary |
Asinh | Hyperbolic arcsin | Unary |
Acosh | Hyperbolic arccos | Unary |
Atanh | Hyperbolic arctan | Unary |
Exp | Exponential (e^x) | Unary |
Erf | Error function | Unary |
Erfc | Error function complement | Unary |
Gamma | Gamma function | Unary |
Abs | Absolute value | Unary |
Ceil | Ceil | Unary |
Floor | Floor | Unary |
Round | Round to nearest integer
Hint: To round to ndigits precision after the decimal point, use Mul(ndigits)|Round|Div(ndigits) combo. |
Unary |
Sqrt | Square root | Unary |
Sign | Sign | Unary |
Arithmetic Operators¶
Keyword | Symbol | Description | Syntax | Examples |
---|---|---|---|---|
Neg | Negate | Unary | Neg >> 42 == -42 |
|
Add | + | Addition | Binary | Add >> [2, -1] == 1 Add(-1) >> 2 == 1 |
Sub | - | Subtraction | Binary | Sub >> [2, 1] == -1 Sub(1) >> 2 == 1 |
Mul | * | Multiplication | Binary | Mul >> [2, 3] == 6 Mul(3) >> 2 == 6 |
Div | / | Division
1. [ ] |-> [x, y] |-> x / y 2. [y] |-> [x] |-> x / y |
Binary | Div >> [6, 3] == 2 Div(3) >> 6 == 2 |
Pow | To power
X to power p 1. [ ] |-> [x, p] |-> x^p 2. [p] |-> [x] |-> x^p |
Binary | Pow >> [2, 3] == 8 Pow(3) >> 2 == 8 |
|
Log | Logarithm
Logarithm with base b: 1. [ ] |-> [x, b] |-> log_b(x) 2. [b] |-> [x] |-> log_b(x) |
Binary | Log >> [8, 2] == 3 Log(2) >> 8 == 3 |
|
Mod | % | Modulo
Modulo of x: 1. [ ] |-> [x, m] |-> x % m 2. [m] |-> [x] |-> x % m |
Binary | Mod >> [7, 4] == 3 Mod(4) >> 7 == 3 |
Quot | // | Quotient
Quotient of x: 1. [ ] |-> [x, d] |-> x // d 2. [d] |-> [x] |-> x // d |
Binary | Quot >> [7, 4] == 1 Quot(4) >> 7 == 1 |
BitNot | ~ | Bitwise not | Unary | BitNot >> 0b1010 == 0b0101 |
BitAnd | & | Bitwise and | Binary | BitAnd >> [0b1010, 0b1100] == 0b1000 |
BitOr | | | Bitwise or | Binary | BitOr >> [0b1010, 0b1100] == 0b1110 |
BitXor | ^ | Bitwise xor | Binary | BitXor >> [0b1010, 0b1100] == 0b0110 |
BitLshift | << | Bitwise left shift
1. [ ] |-> [x, s] |-> x << s 2. [s] |-> [x] |-> x << s |
Binary | BitLshift >> [0b1010, 2] == 0b101000 |
BitRshift | >> | Bitwise right shift
1. [ ] |-> [x, s] |-> x >> s 2. [s] |-> [x] |-> x >> s |
Binary | BitRshift >> [0b1010, 2] == 0b0010 |
Relation Operators¶
Keyword | Symbol | Description | Syntax | Examples |
---|---|---|---|---|
Eq | = | Is equal | Binary | Eq >> [1, 1] == true Eq(42) >> 41 == false |
Ne | ≠ | Not equal | Binary | Ne >> [1, 2] == true Ne(42) >> 42 == false |
Lt | < | Lesser than | Binary | Lt >> [1, 2] == true Lt(42) >> 41 == false |
Le | ≤ | Lesser or equal | Binary | Le >> [1, 2] == true Le(42) >> 42 == true |
Gt | > | Greater than | Binary | Gt >> [2, 1] == true Gt(42) >> 43 == false |
Ge | ≥ | Greater or equal | Binary | Ge >> [2, 1] == true Ge(42) >> 42 == true |
Approx | Floating point approximately equal
Based on numpy.isclose: abs(x - ref) <= (atol + rtol * abs(ref)) Rhs parameters: ref: reference value rtol: relative tolerance, default = 1e-05 atol: absolute tolerance, default = 1e-08 Rhs dynamic evaluation: 1. ref -> [ref, default, default] 2. [ref] -> [ref, default, default] 3. [ref, rtol] -> [ref, rtol , default] 4. [ref, rtol, atol] -> [ref, rtol , atol ] Aliases: near |
Binary | Approx >> [42, 42] == true Approx(42.0 + 1e-09) >> 42 == true Approx(42.001) >> 42 == false Relative tolerance 1e-03 Approx([3.14, 0.001]) >> pi == true Absolute tolerance 0.01 Approx([3.14, 0, 0.01]) >> pi == true |
Set Operators¶
Keyword | Symbol | Description | Syntax | Examples |
---|---|---|---|---|
Union | ∪ | Set union | Binary | Union >> [[1, 2], [2, 3]] == [1, 2, 3] Union([2, 3]) >> [1, 2] == [1, 2, 3] |
Intersect | ∩ | Set intersection | Binary | Intersect >> [[1, 2], [2, 3]] == [2] Intersect([2, 3]) >> [1, 2] == [2] |
Diff | Set difference | Binary | Diff >> [[1, 2], [2, 3]] == [1] Diff([2, 3]) >> [1, 2] == [1] |
Set Relation Operators¶
Keyword | Symbol | Description | Syntax | Examples |
---|---|---|---|---|
SetEq | ≡ | Equal as set | Binary | SetEq >> [[1, 2], [2, 1]] == true SetEq([2, 1]) >> [1, 2] == true |
Subset | ⊆ | Is subset | Binary | Subset >> [[1, 2], [1, 2, 3]] == true Subset([1, 2, 3]) >> [1, 2] == true Subset >> [[1, 2, 3], [2, 3]] == false Subset([2, 3]) >> [1, 2, 3] == false Subset >> [[1, 2], []] == true Subset >> [[], []] == true |
Superset | ⊇ | Is superset | Binary | Superset >> [[1, 2, 3], [1, 2]] == true Superset([1, 2]) >> [1, 2, 3] == true Superset >> [[2, 3], [1, 2, 3]] == false Superset([1, 2, 3]) >> [2, 3] == false Superset >> [[], [1, 2]] == true Superset >> [[], []] == true |
ProperSubset | ⊂ | Is proper subset | Binary | ProperSubset >> [[1, 2], [1, 2, 3]] == true ProperSubset([1, 2, 3]) >> [1, 2] == true ProperSubset >> [[1, 2, 3], [2, 3]] == false ProperSubset([2, 3]) >> [1, 2, 3] == false ProperSubset >> [[1, 2], []] == true ProperSubset >> [[], []] == false |
ProperSuperset | ⊃ | Is proper superset | Binary | ProperSuperset >> [[1, 2, 3], [1, 2]] == true ProperSuperset([1, 2]) >> [1, 2, 3] == true ProperSuperset >> [[2, 3], [1, 2, 3]] == false ProperSuperset([1, 2, 3]) >> [2, 3] == false ProperSuperset >> [[], [1, 2]] == true ProperSuperset >> [[], []] == false |
In | ∈ | Element is in | Binary | In >> [1, [1, 2]] == true In([1, 2]) >> 3 == false |
NotIn | ∉ | Element is not in | Binary | NotIn >> [3, [1, 2]] == true NotIn([1, 2]) >> 1 == false |
Ni | ∋ | Contains element
Aliases: contains |
Binary | Ni >> [[1, 2], 1] == true Ni([1, 2]) >> 3 == false |
NotNi | ∌ | Not contains element | Binary | NotNi >> [[1, 2], 3] == true NotNi([1, 2]) >> 1 == false |
Branching Operators¶
Keyword | Symbol | Description | Syntax | Examples |
---|---|---|---|---|
Bool | ? | Predicate on boolean transform (aka truthy) | Unary | Bool >> 42 == true Bool >> 0 == false Bool >> "false" == true Bool >> "" == false Bool >> [1] == true Bool >> [] == false Bool >> {} == false Bool >> null == false |
Nil | Predicate on boolean transform (aka falsy) | Unary | Nil >> 42 == false Nil >> 0 == true |
|
Not | ¬ | Logical complement | Unary | Not >> true == false Not >> false == true |
And | ∧ | Logical and
Generic behavior: if first operand is truthy, returns second operand, otherwise first |
Binary | And >> [true, false] == false And >> [true, true] == true Generic behavior: And >> ["foo", [42, 43]] == [42, 43] And >> ["" , [42, 43]] == "" And(42) >> 13 == 42 And(42) >> [] == [] If-Else using composition: And(42)|Or(13) >> true == 42 And(42)|Or(13) >> false == 13 |
Or | ∨ | Logical or
Generic behavior: if first operand is truthy, returns first operand, second otherwise |
Binary | Or >> [true, false] == true Or >> [false, false] == false Generic behavior: Or >> ["foo", [42, 43]] == "foo" Or >> ["" , [42, 43]] == [42, 43] Or(42) >> 13 == 13 Or(42) >> [] == 42 If-Else using composition: And(42)|Or(13) >> true == 42 And(42)|Or(13) >> false == 13 |
Unary Structural transforms¶
Keyword | Description | Syntax | Examples |
---|---|---|---|
Id | Identity function | Unary | Id >> 42 == 42 |
Transp | Transpose multidimensional list, turning rows into columns
May be used to zip sequences of equal length. |
Unary | Transp >> [[1, 2, 3], [4, 5, 6]] == [[1, 4], [2, 5], [3, 6]] |
Cartesian | Cartesian product | Unary | Cartesian >> [[1, 2], [3, 4]] == [[1, 3], [1, 4], [2, 3], [2, 4]] |
Reverse | Reverse sequence | Unary | Reverse >> [1, 2, 3] == [3, 2, 1] |
Uniques | Filter unique elements | Unary | Uniques >> [1, 2, 1, 3, 2] == [1, 2, 3] |
Items | Extract key-value pairs from object | Unary | Items >> {"a": 1, "b": 2} == [["a", 1], ["b", 2]] |
Keys | Extract keys from object | Unary | Keys >> {"a": 1, "b": 2} == ["a", "b"] |
Values | Extract values from object | Unary | Values >> {"a": 1, "b": 2} == [1, 2] |
Enumerate | Enumerate sequence
Enumerate sequence with index. |
Unary | Enumerate >> [1, 2, 3] == [[0, 1], [1, 2], [2, 3]] |
Flatten | Flatten nested list | Unary | Flatten >> [[1, 2], [3, 4]] == [1, 2, 3, 4] |
ToList | Put argument into a list
Equivalent to At([""]) |
Unary | List >> 42 == [42] |
Unary Generators¶
Keyword | Description | Syntax | Examples |
---|---|---|---|
Arange | Generate range of numbers
Return evenly spaced values within a given interval. Parameters: 1. start: start value 2. stop: stop value 3. step: step value Parameters dynamic evaluation: 1. stop: int -> [0, stop, 1] 2. [start, stop] -> [start, stop, 1] 3. [start, stop, step] -> [start, stop, step] |
Unary | Arange >> 6 == [0,1,2,3,4,5] Arange >> [2,6] == [2,3,4,5] Arange >> [1,9,2] == [1,3,5,7] Arange >> [5,1,-1] == [5,4,3,2] Arange >> "2:6" == [2,3,4,5] Arange >> "1:9:2" == [1,3,5,7] Arange >> "5:1:-1" == [5,4,3,2] |
String Transforms¶
Keyword | Description | Syntax | Examples |
---|---|---|---|
Parse | Parse string as json | Unary | Parse >> '{"a": 42}' == {"a": 42} |
Serialize | Serialize json as string
Aliases: str |
Unary | Serialize >> {"a": 42} == '{"a":42}' |
Re | Regular expression match
If input is not a string, match it's serialized form. Aliases: regex |
Binary | Re >> ["[0-9]+", "42"] == true Re("[0-9]+") >> "42" == true |
Format | Format string with the given parameter list.
Constant expressions are supported for the token list, s.t. Fmt(Pi) << "%s" produces "3.141592653589793E0" Aliases: fmt |
Variadic | Format >> ["Hello, %s!", ["world"]] == "Hello, world!" Format(2,2,4) >> "%d + %d = %d" == "2 + 2 = 4" |
Structural properties¶
Keyword | Description | Syntax | Examples |
---|---|---|---|
Card | Set cardinality (uniques count) | Unary | Card >> [1, 2, 1, 3, 2] == 3 Card >> {"a": 1, "b": 2} == 2 |
Size | Sequence size | Unary | Size >> [1, 1, 1] == 3 Size >> {"a": 1, "b": 2} == 2 |
Sum | Summation reduction
Equivalent to Reduce(Add) |
Unary | Sum >> [1, 2, 3] == 6 |
Prod | Multiplication reduction
Equivalent to Reduce(Mul) |
Unary | Prod >> [1, 2, 3] == 6 |
Avg | Arythmetic average | Unary | Avg >> [1, 2, 3] == 2 |
Binary Structural transforms¶
Keyword | Description | Syntax | Examples |
---|---|---|---|
Slide | Sliding-window iteration
Sliding window iteration by specified window width. |
Binary | Slide(3) >> [1,2,3,4,5] == [[1,2,3],[2,3,4],[3,4,5]] Slide(42) >> [1,2,3,4,5] == [] |
Stride | Striding iteration
Striding iteration by specified step width. Reminder subsequence smaller then step width is discarded. |
Binary | Stride(2) >> [1,2,3,4,5,6] == [[1,2],[3,4],[5,6]] Stride(3) >> [1,2,3,4,5] == [[1,2,3]] |
Chunks | Split into chunks of specified max width
Similar to Stride, but includes the last subsequence smaller then step width. |
Binary | Chunks(2) >> [1,2,3,4,5,6] == [[1,2],[3,4],[5,6]] Chunks(3) >> [1,2,3,4,5] == [[1,2,3],[4,5]] |
Repeat | Repeat value in list | Binary | Repeat(3) >> 42 == [42, 42, 42] Repeat(3)|Repeat(2) >> 1 == [[1,1,1],[1,1,1]] |
Concat | Concatenate sequences | Binary | Concat >> [1, 2], [3, 4] == [1, 2, 3, 4] Concat("World!") >> "Hello, " == "Hello, World!" |
Push | Push element into a front of sequence | Binary | Push >> [1, 2], 3 == [3, 1, 2] Push(3) >> [1, 2] == [3, 1, 2] |
At | Transform json value with given query
Query evaluation rules: 1. q: int |-> x: list |-> x at index q (negative -> reverse) 2. q: slice |-> x: list |-> x[start:stop:step] 3. q: str |-> x: any |-> x at JSON Pointer q 4. q: list |-> x: any |-> [x at q1, x at q2, ...] 5. {"key": q1, "$q2": q3, ...} |-> x: any |-> { "key1": x at q1, "$(x at q2)": x at q3, ...} |
Binary | • Index query: At(2) >> [1, 2, 3] == 3 At(3) >> [1, 2, 3] == nullptr At(0) >> 42 == nullptr • JSON Pointer query: At("") >> "foo" == "foo" At("/a") >> {"a": 42, "b": 13} == 42 • List query: At(["/a", "/b"]) >> {"a": 42, "b": 13} == [42, 13] At([""]) >> 42 == [42] • Object query: At({"f": "/a", "g": "/b"}) >> {"a": 42, "b": 13} == {"f": 42, "g": 13} At({"$/b": "/a"}) >> {"a": 42, "b": 13} == {"13": 42} • Slice query: At("::2") >> [1,2,3,4,5,6,7,8] == [1,3,5,7] At("4:") >> [1,2,3,4,5,6,7,8] == [5,6,7,8] At("-1:0:-1") >> [1,2,3,4,5,6,7,8] == [8,7,6,5,4,3,2,1] |
Lookup | Lookup table function
Parametrized at design time with fixed array or object, produces the value at corresponding At query given as eval-time argument. Equivalent to Flip(At(...)) |
Binary | Lookup([1,2,3]) >> 0 == 1 Lookup([1,2,3]) >> "/foo" == null |
C | User-defined constant
Produced expression will return the design-time parameter on evaluation, ignoring input. C(x) is a shorthand for Id << x or And(false)|Or(x) Aliases: let |
Binary | C(42) >> 13 == 42 |
High-Order¶
Keyword | Description | Syntax | Examples |
---|---|---|---|
Reduce | Reduce sequence with binary operator
To set specific initial value, use composition with Push, e.g. Push(0)|Reduce(Add) For reverse operation, see Unfold Aliases: fold |
Binary | Reduce(Add) >> [-1, 2, 3] == 4 Reduce(Mul) >> [-1, 2, 3] == -6 |
Map | Apply param expr to every element of sequence | Binary | Map(Add(1)) >> [1, 2, 3] == [2, 3, 4] |
Filter | Filter sequence by predicate param | Binary | Filter(Gt(2)) >> [1, 2, 3, 4] == [3, 4] |
Count | Count matches by predicate param | Binary | Count(Gt(2)) >> [1, 2, 3, 4] == 2 |
Each | Test predicate for each item in a sequence
Equivalent to Count(p|Not)|Eq(0) |
Binary | Each(Gt(2)) >> [1, 2, 3, 4] == false Slide(2)|Each(Lt) >> [1, 2, 3, 4] == true |
Sort | Sort list by key function | Binary | Sort >> [3, 1, 2] == [1, 2, 3] Sort(Id) >> [3, 1, 2] == [1, 2, 3] Sort(Abs) >> [-3, 1, -2] == [1, -2, -3] Sort|Reverse >> [3, 1, 2] == [3, 2, 1] |
Min | Min value by key function | Binary | Min >> [-3, 1, -2] == 1 Min(Abs) >> [-3, 1, -2] == -3 |
Max | Max value by key function | Binary | Max >> [-3, 1, -2] == 1 Max(Abs) >> [-3, 1, -2] == -3 |
Argmin | Min value index by key function | Binary | Argmin >> [-3, 1, -2] == 0 Argmin(Abs) >> [-3, 1, -2] == 1 |
Argmax | Max value index by key function | Binary | Argmax >> [-3, 1, -2] == 1 Argmax(Abs) >> [-3, 1, -2] == 0 |
Apply | Apply expr to literal param | Ternary | Apply(Add(1), 42) >> null == 43 • Infix operator form (left shift): (Add(1) << 42) ≡ Apply(Add(1), 42) |
Recur | Apply recursion to parameter expr and initial value
Recur(f, x) >> n = ◯ⁿ f(x) |
Ternary | Recur(Add(1), 0) >> 0 == 3 Recur(Mul(-1), 1) >> 3 == -1 |
Unfold | Put results of recursive fn call on initial value into an array
Unfold(f, x) >> n = [x, ◯¹f(x), ◯²f(x), ..., ◯ⁿ f(x)] |
Ternary | Unfold(Add(1), 0) >> 3 == [0, 1, 2, 3] Unfold(Mul(-1), 1) >> 3 == [1,-1, 1,-1] |
Bind | !not implemented! bind design-time parameters | Variadic | |
Any | Match any predicate | Variadic | Any(Gt(2), Lt(0)) >> 3 == true Any(Gt(2), Lt(0)) >> 0 == false |
All | Match all predicates | Variadic | All(Gt(2), Lt(0)) >> 3 == false All(Gt(2), Lt(3)) >> 2.5 == true |
Saturate | Saturate matches in order | Variadic | Saturate(Gt(2), Lt(0)) >> 3 == true Saturate(Gt(2), Lt(0)) >> 0 == false Saturate(42, Mod(2)|0) >> [2,4,8,42,1,2] == true Saturate(42, Mod(2)|0) >> [2,4,8,41,2] == false Saturate(42, Mod(2)|0) >> [2,4,8,42] == false |
Compose | Compose functions | Variadic | Compose(Add(1), Mul(2)) >> 3 == 7 Compose(Add(1), Mul(2)) >> 4 == 9 • Infix operator form (pipe): Add(1)|Mul(2) ≡ Compose(Add(1), Mul(2)) Add(1)|Mul(2) >> 3 == 7 |
Pack | Pack results from enveloped functions into an array
Allows to combine different properties in a single expression |
Variadic | Pack(Reduce(Add), Size) >> [1,2,3] == [6,3] • Infix operator form (ampersand): Reduce(Add) & Size >> [1,2,3] == [6,3] Reduce(Add) & Size | Div >> [1,2,3] == 2 |
Flip | Flips design-time and eval-time parameters for enveloped expression.
Useful for binding lhs operands to non-commutative operators. Unlike Haskell's flip, won't change the order or eval-time parameters - for that case use the Reverse keyword instead. |
Binary | Div(1) >> 2 == 2 Flip(Div(1)) >> 2 == 0.5 |
Evaluation handlers¶
Keyword | Description | Syntax | Examples |
---|---|---|---|
Default | Return x if not null, else return default value
Aliases: d |
Binary | Default(42) >> null == 42 Default(42) >> 13 == 13 |
Try | Evaluate enveloped function and return result or null if it throws | Binary | Try(Add(1)) >> 42 == 43 Try(Add(1)) >> "foo" == null |
TryCatch | Evaluate enveloped function and return result or error info if it throws | Binary | TryCatch(Div(0)) >> 42 == { "err": "zero division", "fn": ":div", "x": 42, "op": "zmbt::GenericSignalOperator" } |