Lexical elements


Comment serve as documentation. Comments begin with the character sequence // and stop at the end of the line.

Comments cannot start inside string or regexp literals. Comments act like newlines.


Flux is built up from tokens. There are four classes of tokens:

  • identifiers
  • keywords
  • operators
  • literals

White space formed from spaces, horizontal tabs, carriage returns, and newlines is ignored except as it separates tokens that would otherwise combine into a single token. While breaking the input into tokens, the next token is the longest sequence of characters that form a valid token.


Identifiers name entities within a program. An identifier is a sequence of one or more letters and digits. An identifier must start with a letter.

    identifier = letter { letter | unicode_digit } .
Examples of identifiers


The following keywords are reserved and may not be used as identifiers:

and import  option   if
or  package builtin  then
not return  testcase else exists


The following character sequences represent operators:

+   ==   !=   (   )   =>
-   <    !~   [   ]   ^
*   >    =~   {   }   ?
/   <=   =    ,   :   "
%   >=   <-   .   |>  @

Integer literals

An integer literal is a sequence of digits representing an integer value. Only decimal integers are supported.

    int_lit     = "0" | decimal_lit .
    decimal_lit = ( "1"  "9" ) { decimal_digit } .
Examples of integer literals

Floating-point literals

A floating-point literal is a decimal representation of a floating-point value. It has an integer part, a decimal point, and a fractional part. The integer and fractional part comprise decimal digits. One of the integer part or the fractional part may be elided.

float_lit = decimals "." [ decimals ]
    | "." decimals .
decimals  = decimal_digit { decimal_digit } .
Examples of floating-point literals
072.40  // == 72.40

Duration literals

A duration literal is a representation of a length of time. It has an integer part and a duration unit part. The integer part must be a valid Flux integer and should not contain leading zeros. Multiple durations may be specified together and the resulting duration is the sum of each smaller part. When several durations are specified together, larger units must appear before smaller ones, and there can be no repeated units.

duration_lit  = { int_lit duration_unit } .
duration_unit = "y" | "mo" | "w" | "d" | "h" | "m" | "s" | "ms" | "us" | "µs" | "ns" .
yyear (12 months)
wweek (7 days)
hhour (60 minutes)
mminute (60 seconds)
msmilliseconds (1 thousandth of a second)
us or µsmicroseconds (1 millionth of a second)
nsnanoseconds (1 billionth of a second)

Durations represent a length of time. Lengths of time are dependent on specific instants in time they occur and as such, durations do not represent a fixed amount of time. There are no amount of days equal to a month, as months vary in their number of days. Durations are a tuple of positive integers that represent a duration and the sign of the duration (positive or negative). Durations are implemented this way so it is possible to determine whether a duration is positive or negative. Since duration values depend on their context, the only way to know if a duration is a positive or negative number is if all magnitudes have the same sign. In the canonical implementation, this is implemented as a tuple of the months and nanoseconds and a boolean that indicates whether it is positive or negative. The spec does not prescribe a specific implementation and other implementations may use a different internal representation.

Durations cannot be combined by addition and subtraction. All magnitudes in the tuple must be a positive integer which cannot be guaranteed when using addition and subtraction. Durations can be multiplied by any integer value. The unary negative operator is the equivalent of multiplying the duration by -1. These operations are performed on each time unit independently.

Examples of duration literals
1h15m  // 1 hour and 15 minutes
1mo5d  // 1 month and 5 days
-1mo5d // negative 1 month and 5 days

Durations can be added to date times to produce a new date time. Addition and subtraction of durations to date times applies months and nanoseconds in that order. When months are added to a date times and the resulting date is past the end of the month, the day is rolled back to the last day of the month. Of note is that addition and subtraction of durations to date times does not commute.

Examples of duration literals
import "date"

date.add(d: 1d,  to: 2018-01-01T00:00:00Z) // 2018-01-02T00:00:00Z
date.add(d: 1mo, to: 2018-01-01T00:00:00Z) // 2018-02-01T00:00:00Z
date.add(d: 2mo, to: 2018-01-01T00:00:00Z) // 2018-03-01T00:00:00Z
date.add(d: 2mo, to: 2018-01-31T00:00:00Z) // 2018-03-31T00:00:00Z
date.add(d: 2mo, to: 2018-02-28T00:00:00Z) // 2018-04-28T00:00:00Z
date.add(d: 1mo, to: 2018-01-31T00:00:00Z) // 2018-02-28T00:00:00Z, February 31th is rolled back to the last day of the month, February 28th in 2018.

date.add(d: 1d, to: date.add(d: 1mo, to: 2018-02-28T00:00:00Z))   // 2018-03-29T00:00:00Z
date.add(d: 1mo, to: date.add(d: 1d, to: 2018-02-28T00:00:00Z))   // 2018-04-01T00:00:00Z
date.sub(d: 1d, from: date.add(d: 2mo, to: 2018-01-01T00:00:00Z)) // 2018-02-28T00:00:00Z
date.add(d: 3mo, to: date.sub(d: 1d, from: 2018-01-01T00:00:00Z)) // 2018-03-31T00:00:00Z
date.add(d: 1mo, to: date.add(d: 1mo, to: 2018-01-31T00:00:00Z))  // 2018-03-28T00:00:00Z
date.add(d: 2mo, to: 2018-01-31T00:00:00Z)                        // 2018-03-31T00:00:00Z

// Addition and subtraction of durations to date times applies months and nanoseconds in that order.
date.add(d: 2d, to: date.add(d: 1mo, to: 2018-01-28T00:00:00Z))  // 2018-03-02T00:00:00Z
date.add(d: 1mo2d, to: 2018-01-28T00:00:00Z)                     // 2018-03-02T00:00:00Z
date.add(d: 1mo, to: date.add(d: 2d, to: 2018-01-28T00:00:00Z))  // 2018-02-28T00:00:00Z, explicit add of 2d first changes the result
date.add(d: 2mo2d, to: 2018-02-01T00:00:00Z)                     // 2018-04-03T00:00:00Z
date.add(d: 1mo30d, to: 2018-01-01T00:00:00Z)                    // 2018-03-03T00:00:00Z, Months are applied first to get February 1st, then days are added resulting in March 3 in 2018.
date.add(d: 1mo1d, to: 2018-01-31T00:00:00Z)                     // 2018-03-01T00:00:00Z, Months are applied first to get February 28th, then days are added resulting in March 1 in 2018.

// Multiplication and addition of durations to date times
date.add(d: date.scale(d:1mo, n:1), to: 2018-01-01T00:00:00Z)  // 2018-02-01T00:00:00Z
date.add(d: date.scale(d:1mo, n:2), to: 2018-01-01T00:00:00Z)  // 2018-03-01T00:00:00Z
date.add(d: date.scale(d:1mo, n:3), to: 2018-01-01T00:00:00Z)  // 2018-04-01T00:00:00Z
date.add(d: date.scale(d:1mo, n:1), to: 2018-01-31T00:00:00Z)  // 2018-02-28T00:00:00Z
date.add(d: date.scale(d:1mo, n:2), to: 2018-01-31T00:00:00Z)  // 2018-03-31T00:00:00Z
date.add(d: date.scale(d:1mo, n:3), to: 2018-01-31T00:00:00Z)  // 2018-04-30T00:00:00Z

Date and time literals

A date and time literal represents a specific moment in time. It has a date part, a time part and a time offset part. The format follows the RFC 3339 specification. The time is optional. When it is omitted the time is assumed to be midnight UTC.

date_time_lit     = date [ "T" time ] .
date              = year "-" month "-" day .
year              = decimal_digit decimal_digit decimal_digit decimal_digit .
month             = decimal_digit decimal_digit .
day               = decimal_digit decimal_digit .
time              = hour ":" minute ":" second [ fractional_second ] time_offset .
hour              = decimal_digit decimal_digit .
minute            = decimal_digit decimal_digit .
second            = decimal_digit decimal_digit .
fractional_second = "."  { decimal_digit } .
time_offset       = "Z" | ("+" | "-" ) hour ":" minute .
Examples of date and time literals
2018-01-01                // midnight on January 1st 2018 UTC

String literals

A string literal represents a sequence of characters enclosed in double quotes. Within the quotes any character may appear except an unescaped double quote. String literals support several escape sequences.

\n   U+000A line feed or newline
\r   U+000D carriage return
\t   U+0009 horizontal tab
\"   U+0022 double quote
\\   U+005C backslash
\${  U+0024 U+007B dollar sign and opening curly bracket

Additionally, any byte value may be specified via a hex encoding using \x as the prefix. The hex encoding of values must result in a valid UTF-8 sequence.

string_lit       = `"` { unicode_value | byte_value | StringExpression | newline } `"` .
byte_value       = `\` "x" hex_digit hex_digit .
hex_digit        = "0" … "9" | "A" … "F" | "a" … "f" .
unicode_value    = unicode_char | escaped_char .
escaped_char     = `\` ( "n" | "r" | "t" | `\` | `"` ) .
StringExpression = "${" Expression "}" .
Examples of string literals
"string with double \" quote"
"string with backslash \\"
"\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e" // the explicit UTF-8 encoding of the previous line

String literals are also interpolated for embedded expressions to be evaluated as strings. Embedded expressions are enclosed in a dollar sign and curly braces (${}). The expressions are evaluated in the scope containing the string literal. The result of an expression is formatted as a string and replaces the string content between the braces. All types are formatted as strings according to their literal representation. To include the literal ${ within a string, it must be escaped.

Example: Interpolation
n = 42
"the answer is ${n}" // the answer is 42
"the answer is not ${n+1}" // the answer is not 43
"dollar sign opening curly bracket \${" // dollar sign opening curly bracket ${

Regular expression literals

A regular expression literal represents a regular expression pattern, enclosed in forward slashes. Within the forward slashes, any unicode character may appear except for an unescaped forward slash. The \x hex byte value representation from string literals may also be present.

In addition to standard escape sequences, regular expression literals also support the following escape sequences:

\/   U+002f forward slash
regexp_lit         = "/" regexp_char { regexp_char } "/" .
regexp_char        = unicode_char | byte_value | regexp_escape_char .
regexp_escape_char = `\/`
Examples of regular expression literals
/^日本語(ZZ)?$/ // the above two lines are equivalent
/a\/b\s\w/ // escape sequences and character class shortcuts are supported
/(?:)/ // the empty regular expression

The regular expression syntax is defined by RE2.

Was this page helpful?

Thank you for your feedback!

The future of Flux

Flux is going into maintenance mode. You can continue using it as you currently are without any changes to your code.

Read more