mirror of
https://github.com/fluencelabs/aqua-book
synced 2024-12-04 15:20:19 +00:00
GitBook: [master] 29 pages modified
This commit is contained in:
parent
d5e471c886
commit
f27d59874e
@ -8,7 +8,7 @@
|
||||
* [Tools](getting-started/tools.md)
|
||||
* [Language](language/README.md)
|
||||
* [Types](language/types.md)
|
||||
* [Variables](language/variables.md)
|
||||
* [Values](language/variables.md)
|
||||
* [Topology](language/topology.md)
|
||||
* [Execution flow](language/operators/README.md)
|
||||
* [Sequential](language/operators/sequential.md)
|
||||
@ -23,8 +23,8 @@
|
||||
* [Overrideable constants](language/expressions/overrideable-constants.md)
|
||||
* [Abilities & Services](language/abilities-and-services.md)
|
||||
* [Imports & exports](language/statements-1.md)
|
||||
* [Library \(BuiltIns\)](language/library-builtins.md)
|
||||
* [Aqua Patterns](aqua-patterns.md)
|
||||
* [Library \(BuiltIns\)](library-builtins.md)
|
||||
* [Aqua VM](aqua-vm.md)
|
||||
* [Appendix](appendix.md)
|
||||
* [Foundations: π-calculus](foundations-p-calculus.md)
|
||||
|
@ -1,2 +1,6 @@
|
||||
# Execution flow
|
||||
|
||||
Aqua's main goal is to express how the execution flows: moves from peer to peer, forks to parallel flows and then joins back, uses data from one step in another.
|
||||
|
||||
As the foundation of Aqua is based on π-calculus, finally flow is decomposed into sequential \(seq, .\), conditional \(xor, ^\), parallel \(par, \|\) computations and iterations based on data \(!P\).
|
||||
|
||||
|
@ -1,4 +1,64 @@
|
||||
# Sequential
|
||||
|
||||
Sequential
|
||||
By default, Aqua code is executed line by line, sequentially.
|
||||
|
||||
### Contract
|
||||
|
||||
Data from the first branch is available in the second branch.
|
||||
|
||||
Second branch is executed iff the first branch succeeded.
|
||||
|
||||
If any branch errored, then the whole sequence is errored.
|
||||
|
||||
If all branches executed successfully, then the whole seq is executed successfully.
|
||||
|
||||
### Sequential operations
|
||||
|
||||
#### call arrow
|
||||
|
||||
Any runnable piece of code in Aqua is an arrow from its domain to codomain.
|
||||
|
||||
```text
|
||||
-- Call a function
|
||||
foo()
|
||||
|
||||
-- Call a function that returns smth, assign results to a variable
|
||||
x <- foo()
|
||||
|
||||
-- Call an ability function
|
||||
y <- Peer.identify()
|
||||
|
||||
-- Pass an argument
|
||||
z <- Op.identity(y)
|
||||
```
|
||||
|
||||
When you write `<-`, this means not just "assign results of the function on the right to variable on the left". It means that all the effects are executed: [service](../abilities-and-services.md) may change state, [topology](../topology.md) may be shifted. But you end up in the same topological scope.
|
||||
|
||||
#### on
|
||||
|
||||
`on` denotes the peer where the code must be executed.
|
||||
|
||||
```text
|
||||
func foo():
|
||||
-- Will be executed where `foo` was executed
|
||||
bar()
|
||||
|
||||
-- Move to another peer
|
||||
on another_peer:
|
||||
-- To call bar, we need to leave the peer where we were and get to another_peer
|
||||
-- It's done automagically
|
||||
bar()
|
||||
|
||||
on third_peer via relay:
|
||||
-- This is executed on third_peer
|
||||
-- But we denote that to get to third_peer and to leave third_peer
|
||||
-- an additional hop is needed: get to relay, then to peer
|
||||
bar()
|
||||
|
||||
-- Will be executed in the `foo` call site again
|
||||
-- To get from the previous `bar`, compiler will add a hop to relay
|
||||
bar()
|
||||
```
|
||||
|
||||
See more in [Topology](../topology.md) section.
|
||||
|
||||
|
@ -1,26 +1,113 @@
|
||||
# Variables
|
||||
# Values
|
||||
|
||||
Variables are immutable, except [writeable collections](types.md#collection-types) \(streams\).
|
||||
Aqua is all about combining data and computations. Underlying runtime \([AquaVM](https://github.com/fluencelabs/aquavm)\) tracks what data comes from what origin, which constitutes the foundation for distributed systems security. That approach, driven by π-calculus and security considerations of open-by-default networks and distributed applications as custom application protocols, also puts constraints on the language that configures it.
|
||||
|
||||
Namely, values form VDS \(Verifiable Data Structures\). All operations on values must retain security invariants. Hence values are immutable, except [writeable collections](types.md#collection-types) \(streams\).
|
||||
|
||||
### Arguments
|
||||
|
||||
Function arguments are available within the whole function body.
|
||||
|
||||
```text
|
||||
func foo(arg: i32, log: string -> ()):
|
||||
-- Use data arguments
|
||||
bar(arg)
|
||||
|
||||
-- Arguments can have arrow type and be used as strings
|
||||
log("Wrote arg to responses")
|
||||
```
|
||||
|
||||
### Return values
|
||||
|
||||
That's the second way to get data with a name.
|
||||
|
||||
```text
|
||||
-- Imagine a Stringify service that's always available
|
||||
service Stringify("stringify"):
|
||||
i32ToStr(arg: i32) -> string
|
||||
|
||||
-- Define the result type of a function
|
||||
func bar(arg: i32) -> string:
|
||||
-- Make a value, name it x
|
||||
x <- Stringify.i32ToStr(arg)
|
||||
-- Starting from there, you can use x
|
||||
-- Pass x out of the function scope as the return value
|
||||
<- x
|
||||
|
||||
|
||||
func foo(arg: i32, log: *string):
|
||||
-- Use bar to convert arg to string, push that string
|
||||
-- to logs stream, return nothing
|
||||
log <- bar(arg)
|
||||
```
|
||||
|
||||
### Literals
|
||||
|
||||
Aqua supports just a few literals: numbers, quoted strings, booleans. You cannot make a structure in Aqua.
|
||||
Aqua supports just a few literals: numbers, quoted strings, booleans. You [cannot make a structure](https://github.com/fluencelabs/aqua/issues/167) in Aqua.
|
||||
|
||||
### Lenses
|
||||
```text
|
||||
-- String literals cannot contain double quotes
|
||||
foo("double quoted string literal")
|
||||
|
||||
Can get fields from objects, and elements by id from collections.
|
||||
-- Booleans are true and false
|
||||
if x == false:
|
||||
foo("false is a literal")
|
||||
|
||||
-- Numbers are different
|
||||
-- Any number:
|
||||
bar(1)
|
||||
|
||||
-- Signed number:
|
||||
bar(-1)
|
||||
|
||||
-- Float:
|
||||
bar(-0.2)
|
||||
```
|
||||
|
||||
### Getters
|
||||
|
||||
In Aqua, you can use a getter to peak into a field of a product, or indexed element in an array.
|
||||
|
||||
```text
|
||||
data Sub:
|
||||
sub: string
|
||||
|
||||
data Example:
|
||||
field: u32
|
||||
arr: []Sub
|
||||
child: Sub
|
||||
|
||||
func foo(e: Example):
|
||||
bar(e.field) -- u32
|
||||
bar(e.child) -- Sub
|
||||
bar(e.child.sub) -- string
|
||||
bar(e.arr) -- []Sub
|
||||
bar(e.arr!) -- gets the 0 element
|
||||
bar(e.arr!.sub) -- string
|
||||
bar(e.arr!2) -- gets the 2nd element
|
||||
bar(e.arr!2.sub) -- string
|
||||
```
|
||||
|
||||
Note that `!` operator may fail or halt:
|
||||
|
||||
* If it is called on an immutable collection, it will fail if collection is shorter and has no given index; you can handle it with [try](operators/conditional.md#try) or [otherwise](operators/conditional.md#otherwise).
|
||||
* If it is called on an appendable stream, it will wait for some parallel append operation to fulfill, see [Join behavior](operators/parallel.md#join-behavior).
|
||||
|
||||
`!` operator cannot be used with non-literal indices: you can use `!2`, but not `!x`. It's planned to be fixed.
|
||||
|
||||
### Assignments
|
||||
|
||||
Assignments do nothing new, just gives a name to a variable with applied lens.
|
||||
Assignments do nothing new, just gives a name to a value with applied getter, or name a literal.
|
||||
|
||||
```text
|
||||
func foo(arg: bool, e: Example):
|
||||
-- Rename the argument
|
||||
a = arg
|
||||
-- Assign the name b to value of e.child
|
||||
b = e.child
|
||||
-- Create a literal
|
||||
c = "just string value"
|
||||
```
|
||||
|
||||
### Constants
|
||||
|
||||
@ -28,7 +115,21 @@ Constants are like assignments, but in the root scope. Can be used in all functi
|
||||
|
||||
You can change the compilation results with overriding a constant. Override should be of the same type \(or a subtype\).
|
||||
|
||||
Only literals can be values of constants.
|
||||
Constant values must resolve to a literal.
|
||||
|
||||
```text
|
||||
-- This flag is always true
|
||||
const flag = true
|
||||
|
||||
-- This setting can be overwritten via CLI flag
|
||||
const setting ?= "value"
|
||||
|
||||
func foo(arg: string): ...
|
||||
|
||||
func bar():
|
||||
-- Type of setting is string
|
||||
foo(setting)
|
||||
```
|
||||
|
||||
### Visibility scopes
|
||||
|
||||
|
2
library-builtins.md
Normal file
2
library-builtins.md
Normal file
@ -0,0 +1,2 @@
|
||||
# Library \(BuiltIns\)
|
||||
|
Loading…
Reference in New Issue
Block a user