firefly-compiler 0.5.39 → 0.5.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.hintrc +4 -4
- package/.vscode/settings.json +4 -4
- package/bin/Release.ff +157 -157
- package/bin/firefly.mjs +1 -1
- package/compiler/Builder.ff +275 -275
- package/compiler/Compiler.ff +234 -234
- package/compiler/Dependencies.ff +186 -186
- package/compiler/DependencyLock.ff +17 -17
- package/compiler/JsEmitter.ff +1437 -1437
- package/compiler/LspHook.ff +202 -202
- package/compiler/ModuleCache.ff +178 -178
- package/compiler/Workspace.ff +88 -88
- package/core/.firefly/include/package.json +5 -5
- package/core/.firefly/package.ff +2 -2
- package/core/Any.ff +25 -25
- package/core/Array.ff +298 -298
- package/core/Atomic.ff +63 -63
- package/core/Box.ff +7 -7
- package/core/BrowserSystem.ff +40 -40
- package/core/BuildSystem.ff +156 -156
- package/core/Crypto.ff +94 -94
- package/core/Equal.ff +41 -41
- package/core/Error.ff +25 -25
- package/core/HttpClient.ff +142 -142
- package/core/Instant.ff +24 -24
- package/core/Js.ff +305 -305
- package/core/JsSystem.ff +135 -135
- package/core/Json.ff +423 -423
- package/core/List.ff +482 -482
- package/core/Lock.ff +108 -108
- package/core/NodeSystem.ff +198 -198
- package/core/Ordering.ff +160 -160
- package/core/Path.ff +377 -378
- package/core/Queue.ff +90 -90
- package/core/Random.ff +140 -140
- package/core/RbMap.ff +216 -216
- package/core/Show.ff +44 -44
- package/core/SourceLocation.ff +68 -68
- package/core/Task.ff +165 -165
- package/experimental/benchmarks/ListGrab.ff +23 -23
- package/experimental/benchmarks/ListGrab.java +55 -55
- package/experimental/benchmarks/Pyrotek45.ff +30 -30
- package/experimental/benchmarks/Pyrotek45.java +64 -64
- package/experimental/bidirectional/Bidi.ff +88 -88
- package/experimental/lines/Main.ff +40 -40
- package/experimental/random/Index.ff +53 -53
- package/experimental/random/Process.ff +120 -120
- package/experimental/random/RunLength.ff +65 -65
- package/experimental/random/Scrape.ff +51 -51
- package/experimental/random/Symbols.ff +73 -73
- package/experimental/random/Tensor.ff +52 -52
- package/experimental/random/Units.ff +36 -36
- package/experimental/s3/S3TestAuthorizationHeader.ff +39 -39
- package/experimental/s3/S3TestPut.ff +16 -16
- package/experimental/tests/TestJson.ff +26 -26
- package/firefly.sh +0 -0
- package/fireflysite/.firefly/package.ff +4 -4
- package/fireflysite/CommunityOverview.ff +20 -20
- package/fireflysite/CountingButtonDemo.ff +58 -58
- package/fireflysite/DocumentParser.ff +325 -325
- package/fireflysite/ExamplesOverview.ff +40 -40
- package/fireflysite/FrontPage.ff +344 -344
- package/fireflysite/GettingStarted.ff +45 -45
- package/fireflysite/Guide.ff +456 -456
- package/fireflysite/Main.ff +163 -163
- package/fireflysite/MatchingPasswordsDemo.ff +82 -82
- package/fireflysite/PackagesOverview.ff +49 -49
- package/fireflysite/PostgresqlDemo.ff +34 -34
- package/fireflysite/ReferenceAll.ff +18 -18
- package/fireflysite/ReferenceIntroduction.ff +11 -11
- package/fireflysite/Styles.ff +567 -567
- package/fireflysite/Test.ff +121 -121
- package/fireflysite/assets/markdown/reference/BaseTypes.md +209 -209
- package/fireflysite/assets/markdown/reference/EmittedJavascript.md +65 -65
- package/fireflysite/assets/markdown/reference/Exceptions.md +101 -101
- package/fireflysite/assets/markdown/reference/FunctionsAndMethods.md +364 -364
- package/fireflysite/assets/markdown/reference/JavascriptInterop.md +235 -235
- package/fireflysite/assets/markdown/reference/ModulesAndPackages.md +162 -162
- package/fireflysite/assets/markdown/reference/OldStructuredConcurrency.md +48 -48
- package/fireflysite/assets/markdown/reference/PatternMatching.md +224 -224
- package/fireflysite/assets/markdown/reference/StatementsAndExpressions.md +86 -86
- package/fireflysite/assets/markdown/reference/StructuredConcurrency.md +99 -99
- package/fireflysite/assets/markdown/reference/TraitsAndInstances.md +100 -100
- package/fireflysite/assets/markdown/reference/UserDefinedTypes.md +184 -184
- package/fireflysite/assets/markdown/scratch/ControlFlow.md +136 -136
- package/fireflysite/assets/markdown/scratch/Toc.md +40 -40
- package/lsp/.firefly/package.ff +1 -1
- package/lsp/CompletionHandler.ff +827 -827
- package/lsp/Handler.ff +714 -714
- package/lsp/HoverHandler.ff +79 -79
- package/lsp/LanguageServer.ff +272 -272
- package/lsp/SignatureHelpHandler.ff +55 -55
- package/lsp/SymbolHandler.ff +181 -181
- package/lsp/TestReferences.ff +17 -17
- package/lsp/TestReferencesCase.ff +7 -7
- package/lsp/stderr.txt +1 -1
- package/lsp/stdout.txt +34 -34
- package/lux/.firefly/package.ff +1 -1
- package/lux/Css.ff +648 -648
- package/lux/CssTest.ff +48 -48
- package/lux/Lux.ff +608 -608
- package/lux/LuxEvent.ff +79 -79
- package/lux/Main.ff +123 -123
- package/lux/Main2.ff +143 -143
- package/lux/TestDry.ff +28 -28
- package/output/js/ff/compiler/Builder.mjs +36 -36
- package/output/js/ff/core/Path.mjs +0 -2
- package/package.json +1 -1
- package/rpc/.firefly/package.ff +1 -1
- package/rpc/Rpc.ff +70 -70
- package/s3/.firefly/package.ff +1 -1
- package/s3/S3.ff +92 -92
- package/vscode/LICENSE.txt +21 -21
- package/vscode/Prepublish.ff +15 -15
- package/vscode/README.md +16 -16
- package/vscode/client/package-lock.json +544 -544
- package/vscode/client/package.json +22 -22
- package/vscode/client/src/extension.ts +104 -104
- package/vscode/icons/firefly-icon.svg +10 -10
- package/vscode/language-configuration.json +61 -61
- package/vscode/package-lock.json +3623 -3623
- package/vscode/package.json +1 -1
- package/vscode/snippets.json +241 -241
- package/vscode/syntaxes/firefly-markdown-injection.json +45 -45
- package/webserver/.firefly/include/package.json +5 -5
- package/webserver/.firefly/package.ff +2 -2
- package/webserver/WebServer.ff +647 -647
- package/websocket/.firefly/package.ff +1 -1
- package/websocket/WebSocket.ff +100 -100
|
@@ -1,162 +1,162 @@
|
|
|
1
|
-
# Modules and packages
|
|
2
|
-
|
|
3
|
-
In Firefly, source code is organized in packages, which can be versioned, released and depended on.
|
|
4
|
-
Inside packages, there are modules, which are individual files that can be imported from other modules.
|
|
5
|
-
|
|
6
|
-
The minimal package consists of just a single module file, and nothing else.
|
|
7
|
-
Such a module can contain the following top level constructs:
|
|
8
|
-
|
|
9
|
-
```firefly
|
|
10
|
-
// Package information
|
|
11
|
-
package mygroup:mypackage:1.2.3
|
|
12
|
-
dependency ff:webserver:0.0.0
|
|
13
|
-
include "node_modules"
|
|
14
|
-
|
|
15
|
-
// Module imports
|
|
16
|
-
import WebServer from ff:webserver
|
|
17
|
-
|
|
18
|
-
// Named constants
|
|
19
|
-
answer: Int = 42
|
|
20
|
-
|
|
21
|
-
// Function definitions
|
|
22
|
-
f(x: Int): Int {
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// Type definitions
|
|
27
|
-
data Point(x: Int, y: Int)
|
|
28
|
-
|
|
29
|
-
// Method definitions
|
|
30
|
-
extend self: Point {
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// Traits and trait instances
|
|
35
|
-
trait T: HasCenter {
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
instance Point: HasCenter {
|
|
39
|
-
|
|
40
|
-
}
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
In a multi-file package, the package information is instead specified in a separate `package.ff` file which must live in the `.firefly/` subdirectory. A typical multi-file package looks like this:
|
|
44
|
-
|
|
45
|
-
```
|
|
46
|
-
mypackage/
|
|
47
|
-
.firefly/
|
|
48
|
-
package.ff
|
|
49
|
-
MyModule.ff
|
|
50
|
-
MyOtherModule.ff
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
The two module files here `MyModule.ff` and `MyOtherModule.ff` defines the modules `MyModule` and `MyOtherModule` respectively. Module files must start with a capital letter.
|
|
54
|
-
|
|
55
|
-
In general, identifiers of any kind in Firefly must start with an ASCII letter, and can only contain ASCII letters and numbers. This also applies to module and package names.
|
|
56
|
-
|
|
57
|
-
Apart from containing the `package.ff` file, the `.firefly/` subdirectory is used for various compiler output and can contain an `include/` directory with JavaScript that you want to include verbatim into the build via the `include` directive.
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
# Package information
|
|
61
|
-
|
|
62
|
-
The `package` keyword specifies the group name, package name and major.minor.patch package version:
|
|
63
|
-
|
|
64
|
-
```firefly
|
|
65
|
-
package mygroup:mypackage:1.2.3
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
A group is a person, organization or similar entity that's allowed to publish packages under that group name.
|
|
69
|
-
|
|
70
|
-
If present, the `package` keyword must be the first token in the file. In a single file package, all the package information goes before any other content.
|
|
71
|
-
|
|
72
|
-
The `dependency` keyword specifies the group name, package name and major.minor.patch package version of a package that is a dependency of this package:
|
|
73
|
-
|
|
74
|
-
```firefly
|
|
75
|
-
dependency ff:webserver:0.0.0
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
There may be zero or more dependencies. If there are conflicting versions of the same package in the dependencies or transitive dependencies, the first version that's encountered in a breadth first search from top to bottom will be used.
|
|
79
|
-
|
|
80
|
-
The `include` keyword includes files verbatim in the JavaScript that is emitted by the compiler:
|
|
81
|
-
|
|
82
|
-
```firefly
|
|
83
|
-
include "node_modules"
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
This instructs the compiler to copy the file or directory `mypackage/.firefly/include/node_modules` verbatim into the `mypackage/.firefly/ouput/node/mygroup/mypackage/node/node_modules` directory. It doesn't do anything for the browser target.
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
# Imports and exports
|
|
90
|
-
|
|
91
|
-
To access the symbols that a module exports, it is necessary to import it:
|
|
92
|
-
|
|
93
|
-
```firefly
|
|
94
|
-
import WebServer from ff:webserver
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
This imports the `WebServer` module from the `ff:webserver` package, which must have been declared as a dependency.
|
|
98
|
-
|
|
99
|
-
Symbols exported from the module can then be accessed using the `WebServer.` prefix:
|
|
100
|
-
|
|
101
|
-
```firefly
|
|
102
|
-
WebServer.new(system, "localhost", 8080)
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
Types, variants and traits are available under the prefix, but can also be accessed with no prefix at all. In the case of naming collisions between these, the last import wins.
|
|
106
|
-
|
|
107
|
-
If two imported modules have the same name, or a different prefix is desired, the symbols can be imported under a different prefix:
|
|
108
|
-
|
|
109
|
-
```firefly
|
|
110
|
-
import WebServer as W from ff:webserver
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
The symbols can then be accessed using the `W.` prefix:
|
|
114
|
-
|
|
115
|
-
```firefly
|
|
116
|
-
W.new(system, "localhost", 8080)
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
Currently, all top level definitions are automatically exported. This is likely to change in the future.
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
# Main functions
|
|
123
|
-
|
|
124
|
-
In Firefly, there are three targets, each with its own main function:
|
|
125
|
-
|
|
126
|
-
```firefly
|
|
127
|
-
nodeMain(system: NodeSystem) {
|
|
128
|
-
system.writeLine("Hello server!")
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
browserMain(system: BrowserSystem) {
|
|
132
|
-
system.writeLine("Hello browser!")
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
buildMain(system: BuildSystem) {
|
|
136
|
-
system.writeLine("Hello build!")
|
|
137
|
-
}
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
The three main functions may coexist in the same file.
|
|
141
|
-
The `nodeMain` function runs when you run your executable,
|
|
142
|
-
the `browserMain` function runs in the browser, and
|
|
143
|
-
the `buildMain` function runs when you build your program.
|
|
144
|
-
|
|
145
|
-
The `system` parameter is an object with methods that let you do I/O in the target system.
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
# Constants
|
|
149
|
-
|
|
150
|
-
Named constants may be defined at the top level, and must have an explict type:
|
|
151
|
-
|
|
152
|
-
```firefly
|
|
153
|
-
answer: Int = 42
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
Here `answer` is defined to be an `Int` with the value `42`.
|
|
157
|
-
|
|
158
|
-
There's no global state in Firefly, and to enforce this, the type of a named constant must have be declared with the `data` or `newtype` keyword.
|
|
159
|
-
|
|
160
|
-
Named constants that occur on the right hand side must not directly or indirecly refer to the named constant being defined.
|
|
161
|
-
|
|
162
|
-
Neither of the requirements are enforced currently, but this is likely to change in the future.
|
|
1
|
+
# Modules and packages
|
|
2
|
+
|
|
3
|
+
In Firefly, source code is organized in packages, which can be versioned, released and depended on.
|
|
4
|
+
Inside packages, there are modules, which are individual files that can be imported from other modules.
|
|
5
|
+
|
|
6
|
+
The minimal package consists of just a single module file, and nothing else.
|
|
7
|
+
Such a module can contain the following top level constructs:
|
|
8
|
+
|
|
9
|
+
```firefly
|
|
10
|
+
// Package information
|
|
11
|
+
package mygroup:mypackage:1.2.3
|
|
12
|
+
dependency ff:webserver:0.0.0
|
|
13
|
+
include "node_modules"
|
|
14
|
+
|
|
15
|
+
// Module imports
|
|
16
|
+
import WebServer from ff:webserver
|
|
17
|
+
|
|
18
|
+
// Named constants
|
|
19
|
+
answer: Int = 42
|
|
20
|
+
|
|
21
|
+
// Function definitions
|
|
22
|
+
f(x: Int): Int {
|
|
23
|
+
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Type definitions
|
|
27
|
+
data Point(x: Int, y: Int)
|
|
28
|
+
|
|
29
|
+
// Method definitions
|
|
30
|
+
extend self: Point {
|
|
31
|
+
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Traits and trait instances
|
|
35
|
+
trait T: HasCenter {
|
|
36
|
+
|
|
37
|
+
}
|
|
38
|
+
instance Point: HasCenter {
|
|
39
|
+
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
In a multi-file package, the package information is instead specified in a separate `package.ff` file which must live in the `.firefly/` subdirectory. A typical multi-file package looks like this:
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
mypackage/
|
|
47
|
+
.firefly/
|
|
48
|
+
package.ff
|
|
49
|
+
MyModule.ff
|
|
50
|
+
MyOtherModule.ff
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
The two module files here `MyModule.ff` and `MyOtherModule.ff` defines the modules `MyModule` and `MyOtherModule` respectively. Module files must start with a capital letter.
|
|
54
|
+
|
|
55
|
+
In general, identifiers of any kind in Firefly must start with an ASCII letter, and can only contain ASCII letters and numbers. This also applies to module and package names.
|
|
56
|
+
|
|
57
|
+
Apart from containing the `package.ff` file, the `.firefly/` subdirectory is used for various compiler output and can contain an `include/` directory with JavaScript that you want to include verbatim into the build via the `include` directive.
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
# Package information
|
|
61
|
+
|
|
62
|
+
The `package` keyword specifies the group name, package name and major.minor.patch package version:
|
|
63
|
+
|
|
64
|
+
```firefly
|
|
65
|
+
package mygroup:mypackage:1.2.3
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
A group is a person, organization or similar entity that's allowed to publish packages under that group name.
|
|
69
|
+
|
|
70
|
+
If present, the `package` keyword must be the first token in the file. In a single file package, all the package information goes before any other content.
|
|
71
|
+
|
|
72
|
+
The `dependency` keyword specifies the group name, package name and major.minor.patch package version of a package that is a dependency of this package:
|
|
73
|
+
|
|
74
|
+
```firefly
|
|
75
|
+
dependency ff:webserver:0.0.0
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
There may be zero or more dependencies. If there are conflicting versions of the same package in the dependencies or transitive dependencies, the first version that's encountered in a breadth first search from top to bottom will be used.
|
|
79
|
+
|
|
80
|
+
The `include` keyword includes files verbatim in the JavaScript that is emitted by the compiler:
|
|
81
|
+
|
|
82
|
+
```firefly
|
|
83
|
+
include "node_modules"
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
This instructs the compiler to copy the file or directory `mypackage/.firefly/include/node_modules` verbatim into the `mypackage/.firefly/ouput/node/mygroup/mypackage/node/node_modules` directory. It doesn't do anything for the browser target.
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
# Imports and exports
|
|
90
|
+
|
|
91
|
+
To access the symbols that a module exports, it is necessary to import it:
|
|
92
|
+
|
|
93
|
+
```firefly
|
|
94
|
+
import WebServer from ff:webserver
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
This imports the `WebServer` module from the `ff:webserver` package, which must have been declared as a dependency.
|
|
98
|
+
|
|
99
|
+
Symbols exported from the module can then be accessed using the `WebServer.` prefix:
|
|
100
|
+
|
|
101
|
+
```firefly
|
|
102
|
+
WebServer.new(system, "localhost", 8080)
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Types, variants and traits are available under the prefix, but can also be accessed with no prefix at all. In the case of naming collisions between these, the last import wins.
|
|
106
|
+
|
|
107
|
+
If two imported modules have the same name, or a different prefix is desired, the symbols can be imported under a different prefix:
|
|
108
|
+
|
|
109
|
+
```firefly
|
|
110
|
+
import WebServer as W from ff:webserver
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
The symbols can then be accessed using the `W.` prefix:
|
|
114
|
+
|
|
115
|
+
```firefly
|
|
116
|
+
W.new(system, "localhost", 8080)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Currently, all top level definitions are automatically exported. This is likely to change in the future.
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
# Main functions
|
|
123
|
+
|
|
124
|
+
In Firefly, there are three targets, each with its own main function:
|
|
125
|
+
|
|
126
|
+
```firefly
|
|
127
|
+
nodeMain(system: NodeSystem) {
|
|
128
|
+
system.writeLine("Hello server!")
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
browserMain(system: BrowserSystem) {
|
|
132
|
+
system.writeLine("Hello browser!")
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
buildMain(system: BuildSystem) {
|
|
136
|
+
system.writeLine("Hello build!")
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
The three main functions may coexist in the same file.
|
|
141
|
+
The `nodeMain` function runs when you run your executable,
|
|
142
|
+
the `browserMain` function runs in the browser, and
|
|
143
|
+
the `buildMain` function runs when you build your program.
|
|
144
|
+
|
|
145
|
+
The `system` parameter is an object with methods that let you do I/O in the target system.
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
# Constants
|
|
149
|
+
|
|
150
|
+
Named constants may be defined at the top level, and must have an explict type:
|
|
151
|
+
|
|
152
|
+
```firefly
|
|
153
|
+
answer: Int = 42
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Here `answer` is defined to be an `Int` with the value `42`.
|
|
157
|
+
|
|
158
|
+
There's no global state in Firefly, and to enforce this, the type of a named constant must have be declared with the `data` or `newtype` keyword.
|
|
159
|
+
|
|
160
|
+
Named constants that occur on the right hand side must not directly or indirecly refer to the named constant being defined.
|
|
161
|
+
|
|
162
|
+
Neither of the requirements are enforced currently, but this is likely to change in the future.
|
|
@@ -1,48 +1,48 @@
|
|
|
1
|
-
# Structured concurrency
|
|
2
|
-
|
|
3
|
-
Firefly has a lightweight task system that supports structured concurrency and cancellation.
|
|
4
|
-
|
|
5
|
-
Tasks are structured in a parent-child relationship, where the parent scope waits for all its child tasks to complete before proceeding.
|
|
6
|
-
|
|
7
|
-
If the parent task or a sibling subtask fails with an uncaught exception, the other subtasks are cancelled.
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
# Spawning a subtask
|
|
11
|
-
|
|
12
|
-
The `system` parameter for the main function has a `mainTask()` method that returns a `Task`.
|
|
13
|
-
This is the main task whose lifecycle corresponds to that of the application.
|
|
14
|
-
A task can `spawn` subtasks:
|
|
15
|
-
|
|
16
|
-
```firefly
|
|
17
|
-
nodeMain(system: NodeSystem) {
|
|
18
|
-
system.mainTask().spawn {subtask =>
|
|
19
|
-
while {True} {
|
|
20
|
-
Log.trace("Hello from subtask!")
|
|
21
|
-
subtask.sleep(Duration(1.0))
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
while {True} {
|
|
25
|
-
Log.trace("Hello from main task!")
|
|
26
|
-
system.mainTask().sleep(Duration(1.0))
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
In the above example, there's one while loop running in the subtask, and another running in the main task.
|
|
32
|
-
They run concurrently, and the `"Hello..."` messages are thus logged in an interleaved fashion.
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
# Waiting for subtasks
|
|
36
|
-
|
|
37
|
-
```firefly
|
|
38
|
-
nodeMain(system: NodeSystem) {
|
|
39
|
-
system.mainTask().spawn {task =>
|
|
40
|
-
task.spawn {subtask =>
|
|
41
|
-
while {True} {
|
|
42
|
-
Log.trace("Hello from subtask!")
|
|
43
|
-
subtask.sleep(Duration(1.0))
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
```
|
|
1
|
+
# Structured concurrency
|
|
2
|
+
|
|
3
|
+
Firefly has a lightweight task system that supports structured concurrency and cancellation.
|
|
4
|
+
|
|
5
|
+
Tasks are structured in a parent-child relationship, where the parent scope waits for all its child tasks to complete before proceeding.
|
|
6
|
+
|
|
7
|
+
If the parent task or a sibling subtask fails with an uncaught exception, the other subtasks are cancelled.
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# Spawning a subtask
|
|
11
|
+
|
|
12
|
+
The `system` parameter for the main function has a `mainTask()` method that returns a `Task`.
|
|
13
|
+
This is the main task whose lifecycle corresponds to that of the application.
|
|
14
|
+
A task can `spawn` subtasks:
|
|
15
|
+
|
|
16
|
+
```firefly
|
|
17
|
+
nodeMain(system: NodeSystem) {
|
|
18
|
+
system.mainTask().spawn {subtask =>
|
|
19
|
+
while {True} {
|
|
20
|
+
Log.trace("Hello from subtask!")
|
|
21
|
+
subtask.sleep(Duration(1.0))
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
while {True} {
|
|
25
|
+
Log.trace("Hello from main task!")
|
|
26
|
+
system.mainTask().sleep(Duration(1.0))
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
In the above example, there's one while loop running in the subtask, and another running in the main task.
|
|
32
|
+
They run concurrently, and the `"Hello..."` messages are thus logged in an interleaved fashion.
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
# Waiting for subtasks
|
|
36
|
+
|
|
37
|
+
```firefly
|
|
38
|
+
nodeMain(system: NodeSystem) {
|
|
39
|
+
system.mainTask().spawn {task =>
|
|
40
|
+
task.spawn {subtask =>
|
|
41
|
+
while {True} {
|
|
42
|
+
Log.trace("Hello from subtask!")
|
|
43
|
+
subtask.sleep(Duration(1.0))
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|