325 lines
11 KiB
Markdown
325 lines
11 KiB
Markdown
---
|
|
title: Expressions
|
|
description: An expression specifies the computation of a value by applying the operators and functions to operands.
|
|
menu:
|
|
flux_v0_ref:
|
|
parent: Flux specification
|
|
name: Expressions
|
|
weight: 109
|
|
aliases:
|
|
- /influxdb/v2/reference/flux/language/expressions/
|
|
- /influxdb/cloud/reference/flux/language/expressions/
|
|
---
|
|
|
|
An _expression_ specifies the computation of a value by applying the operators and functions to operands.
|
|
|
|
## Operands and primary expressions
|
|
|
|
Operands denote the elementary values in an expression.
|
|
|
|
Primary expressions are the operands for unary and binary expressions.
|
|
A primary expressions may be a literal, an identifier denoting a variable, or a parenthesized expression.
|
|
|
|
```js
|
|
PrimaryExpression = identifier | Literal | "(" Expression ")" .
|
|
```
|
|
|
|
## Literals
|
|
|
|
Literals construct a value.
|
|
|
|
```js
|
|
Literal = int_lit
|
|
| float_lit
|
|
| string_lit
|
|
| regex_lit
|
|
| duration_lit
|
|
| date_time_lit
|
|
| pipe_receive_lit
|
|
| RecordLiteral
|
|
| ArrayLiteral
|
|
| DictLiteral
|
|
| FunctionLiteral .
|
|
```
|
|
|
|
### Record literals
|
|
|
|
Record literals construct a value with the record type.
|
|
|
|
```js
|
|
RecordLiteral = "{" RecordBody "}" .
|
|
RecordBody = WithProperties | PropertyList .
|
|
WithProperties = identifier "with" PropertyList .
|
|
PropertyList = [ Property { "," Property } ] .
|
|
Property = identifier [ ":" Expression ]
|
|
| string_lit ":" Expression .
|
|
```
|
|
|
|
**Examples**
|
|
```js
|
|
{a: 1, b: 2, c: 3}
|
|
{a, b, c}
|
|
{o with x: 5, y: 5}
|
|
{o with a, b}
|
|
```
|
|
|
|
### Array literals
|
|
|
|
Array literals construct a value with the array type.
|
|
|
|
```js
|
|
ArrayLiteral = "[" ExpressionList "]" .
|
|
ExpressionList = [ Expression { "," Expression } ] .
|
|
```
|
|
|
|
### Dictionary literals
|
|
|
|
Dictionary literals construct a value with the dict type.
|
|
|
|
```js
|
|
DictLiteral = EmptyDict | "[" AssociativeList "]" .
|
|
EmptyDict = "[" ":" "]" .
|
|
AssociativeList = Association { "," AssociativeList } .
|
|
Association = Expression ":" Expression .
|
|
```
|
|
|
|
Keys can be arbitrary expressions.
|
|
The type system enforces that all keys are of the same type.
|
|
|
|
**Examples**
|
|
```js
|
|
a = "a"
|
|
b = [:] // empty dictionary
|
|
c = [a: 1, "b": 2] // dictionary mapping string values to integers
|
|
d = [a: 1, 2: 3] // type error: cannot mix string and integer keys
|
|
```
|
|
|
|
### Function literals
|
|
|
|
A _function literal_ defines a new function with a body and parameters.
|
|
The function body may be a block or a single expression.
|
|
The function body must have a return statement if it is an explicit block, otherwise the expression is the return value.
|
|
|
|
```js
|
|
FunctionLiteral = FunctionParameters "=>" FunctionBody .
|
|
FunctionParameters = "(" [ ParameterList [ "," ] ] ")" .
|
|
ParameterList = Parameter { "," Parameter } .
|
|
Parameter = identifier [ "=" Expression ] .
|
|
FunctionBody = Expression | Block .
|
|
```
|
|
|
|
##### Examples of function literals
|
|
|
|
```js
|
|
() => 1 // function returns the value 1
|
|
(a, b) => a + b // function returns the sum of a and b
|
|
(x=1, y=1) => x * y // function with default values
|
|
(a, b, c) => { // function with a block body
|
|
d = a + b
|
|
return d / c
|
|
}
|
|
|
|
```
|
|
All function literals are anonymous.
|
|
A function may be given a name using a variable assignment.
|
|
|
|
```
|
|
add = (a,b) => a + b
|
|
mul = (a,b) => a * b
|
|
```
|
|
|
|
Function literals are _closures_ and may refer to variables defined in a surrounding block.
|
|
Those variables are shared between the function literal and the surrounding block.
|
|
|
|
Function arguments are named. There are no positional arguments.
|
|
Values implementing a function type must use the same argument names.
|
|
|
|
```js
|
|
apply = (f, x) => f(x: x)
|
|
|
|
apply(f: (x) => x + 1, x: 2) // 3
|
|
apply(f: (a) => a + 1, x: 2) // error, function must use the same argument name `x`.
|
|
apply(f: (x, a=3) => a + x, x: 2) // 5, extra default arguments are allowed
|
|
```
|
|
|
|
## Call expressions
|
|
|
|
A _call expression_ invokes a function with the provided arguments.
|
|
Arguments must be specified using the argument name.
|
|
Positional arguments are not supported.
|
|
Argument order does not matter.
|
|
When an argument has a default value, it is not required to be specified.
|
|
|
|
```js
|
|
CallExpression = "(" PropertyList ")" .
|
|
```
|
|
|
|
##### Examples of call expressions
|
|
|
|
```js
|
|
f(a:1, b:9.6)
|
|
float(v:1)
|
|
```
|
|
|
|
Use short notation in a call expression when the name of every argument matches the name of every parameter.
|
|
|
|
##### Examples of short notation in call expressions
|
|
|
|
```js
|
|
add(a: a, b: b) //long notation
|
|
add(a, b) // short notation equivalent
|
|
|
|
add = (a,b) => a + b
|
|
a = 1
|
|
b = 2
|
|
|
|
// Don't mix short and long notation.
|
|
add(a: a, b)
|
|
add(a, b: b)
|
|
```
|
|
|
|
## Pipe expressions
|
|
|
|
A _pipe expression_ is a call expression with an implicit piped argument.
|
|
Pipe expressions simplify creating long nested call chains.
|
|
|
|
Pipe expressions pass the result of the left hand expression as the _pipe argument_ to the right hand call expression.
|
|
Function literals specify which if any argument is the pipe argument using the _pipe literal_ as the argument's default value.
|
|
It is an error to use a pipe expression if the function does not declare a pipe argument.
|
|
|
|
```js
|
|
pipe_receive_lit = "<-" .
|
|
```
|
|
|
|
##### Examples of pipe expressions
|
|
|
|
```js
|
|
foo = () => // function body elided
|
|
bar = (x=<-) => // function body elided
|
|
baz = (y=<-) => // function body elided
|
|
foo() |> bar() |> baz() // equivalent to baz(x:bar(y:foo()))
|
|
```
|
|
|
|
## Index expressions
|
|
Index expressions access a value from an array based on a numeric index.
|
|
|
|
```js
|
|
IndexExpression = "[" Expression "]" .
|
|
```
|
|
|
|
## Member expressions
|
|
Member expressions access a property of a record.
|
|
They are specified using an expression in one of the following forms:
|
|
|
|
```js
|
|
rec.k
|
|
// or
|
|
rec["k"]
|
|
```
|
|
|
|
The property being accessed must be either an identifier or a string literal.
|
|
In either case the literal value is the name of the property being accessed, the identifier is not evaluated.
|
|
It is not possible to access a record's property using an arbitrary expression.
|
|
|
|
If `rec` contains an entry with property `k`, both `rec.k` and `rec["k"]` return the value associated with `k`.
|
|
If `rec` does **not** contain an entry with property `k`, both `rec.k` and `rec["k"]` return _null_.
|
|
|
|
```js
|
|
MemberExpression = DotExpression | MemberBracketExpression .
|
|
DotExpression = "." identifier .
|
|
MemberBracketExpression = "[" string_lit "]" .
|
|
```
|
|
|
|
## Conditional expressions
|
|
Conditional expressions evaluate a boolean-valued condition.
|
|
If the result is _true_, the expression that follows the `then` keyword is evaluated and returned.
|
|
If the result is _false_, the expression that follows the `else` keyword is evaluated and returned.
|
|
In either case, only the branch taken is evaluated and only side effects associated this branch will occur.
|
|
|
|
```js
|
|
ConditionalExpression = "if" Expression "then" Expression "else" Expression .
|
|
```
|
|
|
|
##### Conditional expression example
|
|
```js
|
|
color = if code == 0 then "green" else if code == 1 then "yellow" else "red"
|
|
```
|
|
|
|
{{% note %}}
|
|
According to the definition above, if a condition evaluates to a _null_ or unknown value,
|
|
the _else_ branch is evaluated.
|
|
{{% /note %}}
|
|
|
|
## Operators
|
|
Operators combine operands into expressions.
|
|
The precedence of the operators is given in the table below.
|
|
Operators with a lower number have higher precedence.
|
|
|
|
| Precedence | Operator | Description |
|
|
| :--------: | :----------------: | :----------------------------------- |
|
|
| 1 | `a()` | Function call |
|
|
| | `a[]` | Member or index access |
|
|
| | `.` | Member access |
|
|
| 2 | <code>\|></code> | Pipe forward |
|
|
| 3 | `() => 1` | FunctionLiteral |
|
|
| 4 | `^` | Exponentiation |
|
|
| 5 | `*` `/` `%` | Multiplication, division, and modulo |
|
|
| 6 | `+` `-` | Addition and subtraction |
|
|
| 7 | `==` `!=` | Comparison operators |
|
|
| | `<` `<=` | |
|
|
| | `>` `>=` | |
|
|
| | `=~` `!~` | |
|
|
| 8 | `not` | Unary logical operator |
|
|
| | `exists` | Null check operator |
|
|
| 9 | `and` | Logical AND |
|
|
| 10 | `or` | Logical OR |
|
|
| 11 | `if` `then` `else` | Conditional |
|
|
|
|
The operator precedence is encoded directly into the grammar as the following.
|
|
|
|
```js
|
|
Expression = ConditionalExpression .
|
|
ConditionalExpression = LogicalExpression
|
|
| "if" Expression "then" Expression "else" Expression .
|
|
LogicalExpression = UnaryLogicalExpression
|
|
| LogicalExpression LogicalOperator UnaryLogicalExpression .
|
|
LogicalOperator = "and" | "or" .
|
|
UnaryLogicalExpression = ComparisonExpression
|
|
| UnaryLogicalOperator UnaryLogicalExpression .
|
|
UnaryLogicalOperator = "not" | "exists" .
|
|
ComparisonExpression = MultiplicativeExpression
|
|
| ComparisonExpression ComparisonOperator MultiplicativeExpression .
|
|
ComparisonOperator = "==" | "!=" | "<" | "<=" | ">" | ">=" | "=~" | "!~" .
|
|
AdditiveExpression = MultiplicativeExpression
|
|
| AdditiveExpression AdditiveOperator MultiplicativeExpression .
|
|
AdditiveOperator = "+" | "-" .
|
|
MultiplicativeExpression = ExponentExpression
|
|
| ExponentExpression ExponentOperator MultiplicativeExpression .
|
|
| ExponentExpression MultiplicativeOperator MultiplicativeExpression .
|
|
MultiplicativeOperator = "*" | "/" | "%" .
|
|
ExponentExpression = PipeExpression
|
|
| ExponentExpression ExponentOperator PipeExpression .
|
|
ExponentOperator = "^" .
|
|
PipeExpression = PostfixExpression
|
|
| PipeExpression PipeOperator UnaryExpression .
|
|
PipeOperator = "|>" .
|
|
UnaryExpression = PostfixExpression
|
|
| PrefixOperator UnaryExpression .
|
|
PrefixOperator = "+" | "-" .
|
|
PostfixExpression = PrimaryExpression
|
|
| PostfixExpression PostfixOperator .
|
|
PostfixOperator = MemberExpression
|
|
| CallExpression
|
|
| IndexExpression .
|
|
```
|
|
|
|
{{% warn %}}
|
|
Dividing by 0 or using the mod operator with a divisor of 0 will result in an error.
|
|
Floating point divide by zero produces positive or negative infinity according
|
|
to the [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754) floating point specification.
|
|
{{% /warn %}}
|
|
|
|
_Also see [Flux Operators](/flux/v0/spec/operators)._
|
|
|
|
{{< page-nav prev="/flux/v0/spec/assignment-scope/" next="/flux/v0/spec/operators/" >}}
|