Skip to content

Commit

Permalink
spec outlining packages, namespaces, and imports
Browse files Browse the repository at this point in the history
  • Loading branch information
jlapacik committed Sep 4, 2018
1 parent d98c8dd commit 3691795
Showing 1 changed file with 75 additions and 7 deletions.
82 changes: 75 additions & 7 deletions docs/SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ Examples:
The following keywords are reserved and may not be used as identifiers:

and import not return
empty in or
empty in or package

[IMPL#256](https://github.com/influxdata/platform/issues/256) Add in and empty operator support
[IMPL#334](https://github.com/influxdata/platform/issues/334) Add "import" support
Expand Down Expand Up @@ -456,7 +456,7 @@ Flux is lexically scoped using blocks:
1. The scope of an option identifier is the options block.
2. The scope of a preassigned (non-option) identifier is in the universe block.
3. The scope of an identifier denoting a variable or function at the top level (outside any function) is the package block.
4. The scope of a package name of an imported package is the file block of the file containing the import declaration.
4. The scope of the name of an imported package is the file block of the file containing the import declaration.
5. The scope of an identifier denoting a function argument is the function body.
6. The scope of a variable assigned inside a function is the innermost containing block.

Expand All @@ -465,8 +465,6 @@ While the identifier of the inner assignment is in scope, it denotes the entity

Option identifiers have default assignments that are automatically defined in the _options block_.
Because the _options block_ is the top-level block of a Flux program, options are visible/available to any and all other blocks.
However option values may only be reassigned or overridden in the explicit block denoting the main (executable) package.
Assignment of option identifiers in any non-executable package is strictly prohibited.

The package clause is not a assignment; the package name does not appear in any scope.
Its purpose is to identify the files belonging to the same package and to specify the default package name for import declarations.
Expand Down Expand Up @@ -569,12 +567,66 @@ Examples:
baz = (y=<-) => // function body elided
foo() |> bar() |> baz() // equivalent to baz(x:bar(y:foo()))

### Program

A Flux program is a sequence of statements defined by

Program = [PackageStatement] [ImportList] StatementList .
ImportList = { ImportStatement } .

### Statements

A statement controls execution.

Statement = OptionStatement | VarAssignment | ReturnStatement |
ExpressionStatement | BlockStatment .
Statement = OptionStatement | VarAssignment |
ReturnStatement | ExpressionStatement | BlockStatment .

#### Package statement

PackageStatement = "package" identifier .

A package statement defines a package block.
Package names must be valid Flux identifiers.
The package statement must be the first statement of every Flux source file.
If a file does not declare a package statement, all identifiers in that file will belong to the special _main_ package.

##### package main

The _main_ package is special for a few reasons:

1. It defines the entrypoint of a Flux program
2. It cannot be imported
3. All query specifications produced after evaluating the _main_ package are coerced into producing side effects

#### Import statement

ImportStatement = "import" [identifier] `"` unicode_char { unicode_char } `"`.

Associated with every package is a package name and an import path.
The import statement takes a package's import path and brings all of the identifiers defined in that package into the current scope.
The import statment defines a namespace through which to access the imported identifiers.
By default the identifer of this namespace is the package name unless otherwise specified.
For example, given a variable `x` declared in package `foo`, importing `foo` and referencing `x` would look like this:

```
import "import/path/to/package/foo"
foo.x
```

Or this:

```
import bar "import/path/to/package/foo"
bar.x
```

A package's import path is always absolute.
Flux does not support relative imports.
Assigment into the namespace of an imported package is not allowed.
A package cannot access nor modify the identifiers belonging to the imported packages of its imported packages.
Every statement contained in an imported package is evaluated.

#### Option statements

Expand Down Expand Up @@ -651,6 +703,15 @@ Examples:
f()
a

### Side Effects

Side effects can occur in two ways.

1. By reassigning builtin options
2. By calling a function that produces side effects

A function produces side effects when it is explicitly declared to have side effects or when it calls a function that itself produces side effects.

### Built-in functions

The following functions are preassigned in the universe block.
Expand Down Expand Up @@ -926,12 +987,13 @@ Examples:
The execution of a query is separate and distinct from the execution of Flux the language.
The input into the query engine is a query specification.

The output of an Flux program is a query specification, which then may be passed into the query execution engine.
The output of a Flux program is a query specification, which then may be passed into the query execution engine.

### Query specification

A query specification consists of a set of operations and a set of edges between those operations.
The operations and edges must form a directed acyclic graph (DAG).
A query specification produces side effects when at least one of its operations produces side effects.

#### Encoding

Expand Down Expand Up @@ -1047,6 +1109,8 @@ Most operations output one table for every table they receive from the input str

Operations that modify the group keys or values will need to regroup the tables in the output stream.

An operation produces side effects when it is constructed from a function that produces side effects.

### Built-in operations

#### From
Expand Down Expand Up @@ -1096,6 +1160,8 @@ Yield has the following properties:
Example:
`from(bucket: "telegraf/autogen") |> range(start: -5m) |> yield(name:"1")`

**Note:** The `yield` function produces side effects.

#### Aggregate operations

Aggregate operations output a table for every input table they receive.
Expand Down Expand Up @@ -2141,6 +2207,8 @@ _tag1=a hum=55.4,temp=99.3 0006
_tag1=a hum=55.5,temp=99.9 0007
```

**Note:** The `to` function produces side effects.

#### Type conversion operations

##### toBool
Expand Down

0 comments on commit 3691795

Please sign in to comment.