firefly-compiler 0.5.35 → 0.5.36

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.
Files changed (225) hide show
  1. package/.hintrc +4 -4
  2. package/.vscode/settings.json +4 -4
  3. package/bin/Release.ff +157 -154
  4. package/bin/firefly.mjs +1 -1
  5. package/compiler/Builder.ff +275 -277
  6. package/compiler/Compiler.ff +234 -233
  7. package/compiler/Dependencies.ff +186 -187
  8. package/compiler/DependencyLock.ff +17 -17
  9. package/compiler/Deriver.ff +23 -31
  10. package/compiler/Dictionaries.ff +1 -1
  11. package/compiler/Inference.ff +43 -20
  12. package/compiler/JsEmitter.ff +1437 -1282
  13. package/compiler/LspHook.ff +202 -202
  14. package/compiler/Main.ff +25 -24
  15. package/compiler/ModuleCache.ff +178 -178
  16. package/compiler/Parser.ff +36 -109
  17. package/compiler/Resolver.ff +5 -8
  18. package/compiler/Substitution.ff +1 -1
  19. package/compiler/Syntax.ff +1 -16
  20. package/compiler/Token.ff +9 -0
  21. package/compiler/Tokenizer.ff +4 -0
  22. package/compiler/Workspace.ff +88 -88
  23. package/core/.firefly/include/package.json +5 -5
  24. package/core/.firefly/package.ff +2 -2
  25. package/core/Any.ff +26 -30
  26. package/core/Array.ff +298 -265
  27. package/core/Atomic.ff +63 -64
  28. package/core/Box.ff +7 -7
  29. package/core/BrowserSystem.ff +40 -40
  30. package/core/Buffer.ff +185 -152
  31. package/core/BuildSystem.ff +156 -148
  32. package/core/Channel.ff +95 -92
  33. package/core/Char.ff +3 -2
  34. package/core/Core.ff +16 -23
  35. package/core/Crypto.ff +94 -96
  36. package/core/Equal.ff +41 -36
  37. package/core/Error.ff +15 -10
  38. package/core/FileHandle.ff +45 -37
  39. package/core/Float.ff +176 -200
  40. package/core/HttpClient.ff +142 -148
  41. package/core/Instant.ff +6 -8
  42. package/core/Int.ff +40 -24
  43. package/core/IntMap.ff +61 -39
  44. package/core/Js.ff +305 -0
  45. package/core/JsSystem.ff +135 -114
  46. package/core/JsValue.ff +303 -159
  47. package/core/Json.ff +423 -443
  48. package/core/List.ff +482 -486
  49. package/core/Lock.ff +108 -144
  50. package/core/Log.ff +25 -14
  51. package/core/NodeSystem.ff +198 -191
  52. package/core/Ordering.ff +160 -161
  53. package/core/Path.ff +377 -409
  54. package/core/Queue.ff +90 -0
  55. package/core/Random.ff +140 -134
  56. package/core/RbMap.ff +216 -216
  57. package/core/Serializable.ff +16 -13
  58. package/core/Show.ff +44 -43
  59. package/core/SourceLocation.ff +68 -68
  60. package/core/Stream.ff +1 -1
  61. package/core/String.ff +224 -202
  62. package/core/StringMap.ff +58 -36
  63. package/core/Task.ff +165 -149
  64. package/experimental/benchmarks/ListGrab.ff +23 -23
  65. package/experimental/benchmarks/ListGrab.java +55 -55
  66. package/experimental/benchmarks/Pyrotek45.ff +30 -30
  67. package/experimental/benchmarks/Pyrotek45.java +64 -64
  68. package/experimental/bidirectional/Bidi.ff +88 -88
  69. package/experimental/lines/Main.ff +40 -0
  70. package/experimental/random/Index.ff +53 -53
  71. package/experimental/random/Process.ff +120 -120
  72. package/experimental/random/RunLength.ff +65 -65
  73. package/experimental/random/Scrape.ff +51 -51
  74. package/experimental/random/Symbols.ff +73 -73
  75. package/experimental/random/Tensor.ff +52 -52
  76. package/experimental/random/Units.ff +36 -36
  77. package/experimental/s3/S3TestAuthorizationHeader.ff +39 -39
  78. package/experimental/s3/S3TestPut.ff +16 -16
  79. package/experimental/tests/TestJson.ff +26 -26
  80. package/firefly.sh +0 -0
  81. package/fireflysite/.firefly/package.ff +4 -4
  82. package/fireflysite/CommunityOverview.ff +20 -20
  83. package/fireflysite/CountingButtonDemo.ff +58 -58
  84. package/fireflysite/DocumentParser.ff +325 -331
  85. package/fireflysite/ExamplesOverview.ff +40 -40
  86. package/fireflysite/FrontPage.ff +344 -344
  87. package/fireflysite/GettingStarted.ff +45 -45
  88. package/fireflysite/Guide.ff +456 -456
  89. package/fireflysite/Main.ff +163 -152
  90. package/fireflysite/MatchingPasswordsDemo.ff +82 -82
  91. package/fireflysite/PackagesOverview.ff +49 -49
  92. package/fireflysite/PostgresqlDemo.ff +34 -34
  93. package/fireflysite/ReferenceAll.ff +18 -18
  94. package/fireflysite/ReferenceIntroduction.ff +11 -11
  95. package/fireflysite/Styles.ff +567 -567
  96. package/fireflysite/Test.ff +121 -62
  97. package/fireflysite/assets/markdown/reference/BaseTypes.md +209 -209
  98. package/fireflysite/assets/markdown/reference/EmittedJavascript.md +65 -65
  99. package/fireflysite/assets/markdown/reference/Exceptions.md +101 -101
  100. package/fireflysite/assets/markdown/reference/FunctionsAndMethods.md +364 -364
  101. package/fireflysite/assets/markdown/reference/JavascriptInterop.md +235 -172
  102. package/fireflysite/assets/markdown/reference/ModulesAndPackages.md +162 -162
  103. package/fireflysite/assets/markdown/reference/OldStructuredConcurrency.md +48 -48
  104. package/fireflysite/assets/markdown/reference/PatternMatching.md +224 -224
  105. package/fireflysite/assets/markdown/reference/StatementsAndExpressions.md +86 -86
  106. package/fireflysite/assets/markdown/reference/StructuredConcurrency.md +99 -99
  107. package/fireflysite/assets/markdown/reference/TraitsAndInstances.md +100 -100
  108. package/fireflysite/assets/markdown/reference/UserDefinedTypes.md +184 -184
  109. package/fireflysite/assets/markdown/scratch/ControlFlow.md +136 -136
  110. package/fireflysite/assets/markdown/scratch/Toc.md +40 -40
  111. package/lsp/.firefly/package.ff +1 -1
  112. package/lsp/CompletionHandler.ff +827 -827
  113. package/lsp/Handler.ff +714 -714
  114. package/lsp/HoverHandler.ff +79 -79
  115. package/lsp/LanguageServer.ff +272 -272
  116. package/lsp/SignatureHelpHandler.ff +55 -55
  117. package/lsp/SymbolHandler.ff +181 -181
  118. package/lsp/TestReferences.ff +17 -17
  119. package/lsp/TestReferencesCase.ff +7 -7
  120. package/lsp/stderr.txt +1 -1
  121. package/lsp/stdout.txt +34 -34
  122. package/lux/.firefly/package.ff +1 -1
  123. package/lux/Css.ff +648 -648
  124. package/lux/CssTest.ff +48 -48
  125. package/lux/Lux.ff +608 -617
  126. package/lux/LuxEvent.ff +79 -116
  127. package/lux/Main.ff +123 -123
  128. package/lux/Main2.ff +143 -143
  129. package/lux/TestDry.ff +28 -28
  130. package/output/js/ff/compiler/Builder.mjs +72 -71
  131. package/output/js/ff/compiler/Compiler.mjs +19 -13
  132. package/output/js/ff/compiler/Dependencies.mjs +8 -7
  133. package/output/js/ff/compiler/DependencyLock.mjs +6 -4
  134. package/output/js/ff/compiler/Deriver.mjs +26 -24
  135. package/output/js/ff/compiler/Dictionaries.mjs +14 -18
  136. package/output/js/ff/compiler/Environment.mjs +6 -4
  137. package/output/js/ff/compiler/Inference.mjs +238 -164
  138. package/output/js/ff/compiler/JsEmitter.mjs +1160 -350
  139. package/output/js/ff/compiler/JsImporter.mjs +20 -18
  140. package/output/js/ff/compiler/LspHook.mjs +12 -10
  141. package/output/js/ff/compiler/Main.mjs +61 -41
  142. package/output/js/ff/compiler/ModuleCache.mjs +10 -8
  143. package/output/js/ff/compiler/Parser.mjs +153 -669
  144. package/output/js/ff/compiler/Patterns.mjs +12 -10
  145. package/output/js/ff/compiler/Resolver.mjs +52 -78
  146. package/output/js/ff/compiler/Substitution.mjs +12 -16
  147. package/output/js/ff/compiler/Syntax.mjs +50 -341
  148. package/output/js/ff/compiler/Token.mjs +126 -4
  149. package/output/js/ff/compiler/Tokenizer.mjs +62 -52
  150. package/output/js/ff/compiler/Unification.mjs +74 -90
  151. package/output/js/ff/compiler/Wildcards.mjs +4 -2
  152. package/output/js/ff/compiler/Workspace.mjs +26 -20
  153. package/output/js/ff/core/Any.mjs +20 -20
  154. package/output/js/ff/core/Array.mjs +268 -175
  155. package/output/js/ff/core/AssetSystem.mjs +8 -6
  156. package/output/js/ff/core/Atomic.mjs +84 -52
  157. package/output/js/ff/core/Bool.mjs +6 -4
  158. package/output/js/ff/core/BrowserSystem.mjs +38 -29
  159. package/output/js/ff/core/Buffer.mjs +285 -133
  160. package/output/js/ff/core/BuildSystem.mjs +36 -56
  161. package/output/js/ff/core/Channel.mjs +250 -97
  162. package/output/js/ff/core/Char.mjs +5 -3
  163. package/output/js/ff/core/Core.mjs +28 -34
  164. package/output/js/ff/core/Crypto.mjs +30 -52
  165. package/output/js/ff/core/Duration.mjs +4 -2
  166. package/output/js/ff/core/Equal.mjs +14 -12
  167. package/output/js/ff/core/Error.mjs +17 -11
  168. package/output/js/ff/core/FileHandle.mjs +76 -38
  169. package/output/js/ff/core/Float.mjs +92 -160
  170. package/output/js/ff/core/HttpClient.mjs +208 -76
  171. package/output/js/ff/core/Instant.mjs +8 -10
  172. package/output/js/ff/core/Int.mjs +36 -26
  173. package/output/js/ff/core/IntMap.mjs +79 -33
  174. package/output/js/ff/core/Js.mjs +751 -0
  175. package/output/js/ff/core/JsSystem.mjs +54 -60
  176. package/output/js/ff/core/JsValue.mjs +294 -143
  177. package/output/js/ff/core/Json.mjs +443 -253
  178. package/output/js/ff/core/List.mjs +262 -214
  179. package/output/js/ff/core/Lock.mjs +156 -125
  180. package/output/js/ff/core/Log.mjs +20 -10
  181. package/output/js/ff/core/Map.mjs +10 -8
  182. package/output/js/ff/core/NodeSystem.mjs +189 -123
  183. package/output/js/ff/core/Nothing.mjs +4 -2
  184. package/output/js/ff/core/Option.mjs +40 -38
  185. package/output/js/ff/core/Ordering.mjs +26 -20
  186. package/output/js/ff/core/Pair.mjs +4 -2
  187. package/output/js/ff/core/Path.mjs +517 -315
  188. package/output/js/ff/core/Queue.mjs +306 -0
  189. package/output/js/ff/core/Random.mjs +141 -77
  190. package/output/js/ff/core/RbMap.mjs +36 -34
  191. package/output/js/ff/core/Serializable.mjs +44 -28
  192. package/output/js/ff/core/Set.mjs +6 -4
  193. package/output/js/ff/core/Show.mjs +8 -6
  194. package/output/js/ff/core/SourceLocation.mjs +4 -2
  195. package/output/js/ff/core/Stream.mjs +30 -50
  196. package/output/js/ff/core/String.mjs +263 -172
  197. package/output/js/ff/core/StringMap.mjs +77 -31
  198. package/output/js/ff/core/Task.mjs +91 -76
  199. package/output/js/ff/core/Try.mjs +20 -18
  200. package/output/js/ff/core/Unit.mjs +4 -2
  201. package/package.json +1 -1
  202. package/postgresql/Pg.ff +53 -59
  203. package/rpc/.firefly/package.ff +1 -1
  204. package/rpc/Rpc.ff +70 -70
  205. package/s3/.firefly/package.ff +1 -1
  206. package/s3/S3.ff +92 -94
  207. package/vscode/LICENSE.txt +21 -21
  208. package/vscode/Prepublish.ff +15 -15
  209. package/vscode/README.md +16 -16
  210. package/vscode/client/package-lock.json +544 -544
  211. package/vscode/client/package.json +22 -22
  212. package/vscode/client/src/extension.ts +104 -104
  213. package/vscode/icons/firefly-icon.svg +10 -10
  214. package/vscode/language-configuration.json +61 -61
  215. package/vscode/package-lock.json +3623 -3623
  216. package/vscode/package.json +1 -1
  217. package/vscode/snippets.json +241 -241
  218. package/vscode/syntaxes/firefly-markdown-injection.json +45 -45
  219. package/webserver/.firefly/include/package.json +5 -5
  220. package/webserver/.firefly/package.ff +2 -2
  221. package/webserver/WebServer.ff +647 -685
  222. package/websocket/.firefly/package.ff +1 -1
  223. package/websocket/WebSocket.ff +100 -131
  224. package/core/UnsafeJs.ff +0 -42
  225. package/output/js/ff/core/UnsafeJs.mjs +0 -191
@@ -1,184 +1,184 @@
1
- # User defined types
2
-
3
- Named types can be defined at the top level, using one of four keywords: `data`, `class`, `capability` or `newtype`.
4
-
5
-
6
- # data
7
-
8
- To define an immutable type, you can use the `data` keyword.
9
-
10
- ```firefly
11
- data Shape {
12
- Circle(x: Float, y: Float, radius: Float)
13
- Rectangle(x: Float, y: Float, width: Float, height: Float)
14
- }
15
- ```
16
-
17
- This defines a type called `Shape` with two variants `Circle` and `Rectangle`.
18
- The `Circle` variant has three named fields of type `Float`, while the `Rectangle` variant has four.
19
-
20
- Type and variant names must start with a capital letter.
21
-
22
- No `class` or `capability` types can occur in the definition of a `data` type.
23
-
24
- A value of type `Shape` is either a `Circle` or a `Rectangle`, and they can be constructed as follows:
25
-
26
- ```firefly
27
- Circle(0.0, 0.0, 1.0) // Variant, : Shape
28
- Rectangle(5.0, 7.0, 3.0, 2.0) // Variant, : Shape
29
- ```
30
-
31
- Above the variants are constructed using positional arguments, whose order must coincide with the order of the parameters in the type definition.
32
-
33
- Named arguments are supported as well:
34
-
35
- ```firefly
36
- Circle(x = 0.0, y = 0.0, radius = 1.0)
37
- ```
38
-
39
- Named parameters don't have to be in order, and can be mixed with positional arguments:
40
-
41
- ```firefly
42
- Circle(radius = 1.0, 0.0, 0.0)
43
- ```
44
-
45
- To branch on the specific variant of a type, use [pattern matching](pattern-matching).
46
-
47
-
48
- # Common fields
49
-
50
- When all the variants share a set of fields, they can be moved to the common fields section of the declaration:
51
-
52
- ```firefly
53
- data Shape(x: Float, y: Float) {
54
- Circle(radius: Float)
55
- Rectangle(width: Float, height: Float)
56
- }
57
- ```
58
-
59
- This is similar to the `Shape` definition above, but the `x` and `y` fields have been pulled out as common fields.
60
- Given a value of a type, e.g. `shape: Shape`, common fields can be accessed without knowing which specific variant it is:
61
-
62
- ```firefly
63
- shape.x // Returns a Float
64
- shape.y // Returns a Float
65
- ```
66
-
67
- When there is only one variant of a type, and its name coincides with the name of the type, we can use a shorthand definition:
68
-
69
- ```firefly
70
- data Point(x: Float, y: Float)
71
- ```
72
-
73
- This defines a type called `Point` with a single variant, also named `Point`, and two common fields of type `Float`.
74
-
75
-
76
- # Copying
77
-
78
- If you have a value and want to construct a variant, you can copy each field explicitly:
79
-
80
- ```firefly
81
- Rectangle(x = point.x, y = point.y, width = 2.0, height = 1.5)
82
- ```
83
-
84
- There's a shorthand for doing this, however:
85
-
86
- ```firefly
87
- point.Rectangle(width = 2.0, height = 1.5)
88
- ```
89
-
90
- Using this shorthand, the fields of `Rectangle` that aren't specified will be copied from `point`.
91
-
92
-
93
-
94
- # class
95
-
96
- Types defined with the `class` keyword work like `data` types, except for the differences noted here.
97
-
98
- Fields of `class` types may be declared `mutable`:
99
-
100
- ```firefly
101
- class FruitBasket(
102
- mutable apples: Int
103
- mutable oranges: Int
104
- mutable bananas: Int
105
- )
106
- ```
107
-
108
- Mutable fields can be updated. Given a value `basket: FruitBasket`, its fields can be assigned to:
109
-
110
- ```firefly
111
- basket.apples = 42 // The apples field now holds the value 42
112
- basket.oranges += 1 // The oranges field is now one greater
113
- basket.bananas -= 1 // The bananas field is now one less
114
- ```
115
-
116
- Except for `capability` types, all types can occur in the definition of a `class` type.
117
-
118
-
119
- # capability
120
-
121
- Types defined with the `capability` keyword work like `class` types, except for the differences noted here.
122
-
123
- ```firefly
124
- capability EventHandler(
125
- onEvent: () => Unit
126
- )
127
- ```
128
-
129
- The `onEvent` field here contains a first class function, which may have captured other capabilities or classes in its closure.
130
- Therefore, calling the function contained in this field may cause side effects.
131
-
132
- In particular, it may have captured the `system` argument that's passed to the main function, or other capabilities that allow it to do I/O.
133
-
134
- There are no restrictions on the types of fields that `capability` types can have.
135
-
136
- Function types `=>` are considered `capability` types.
137
-
138
-
139
- # newtype
140
-
141
- Types defined with the `newtype` keyword work like `data` types, except that they must have exactly one common field and no explicitly listed variants.
142
-
143
- ```firefly
144
- newtype UserId(id: Int)
145
- ```
146
-
147
- At runtime, they are represented as values of the field type.
148
- In this case, it means that `UserId(42)` is represented as the `Int` value `42` at runtime, with zero overhead.
149
-
150
-
151
- # Generic types
152
-
153
- Whether you use `data`, `class`, `capability` or `newtype` to define a type, it may have type parameters.
154
-
155
- ```firefly
156
- data Basket[T](
157
- items: List[T]
158
- )
159
- ```
160
-
161
- Here the `T` in `Basket[T]` is a type parameter, and it's used as a type argument in `List[T]`.
162
-
163
- An unbounded type parameter can be instantiated to any type.
164
- We can have a `Basket[Shape]`, which has a field `items: List[Shape]`, and a different type `Basket[EventHandler]`, which has a field `items: List[EventHandler]`.
165
-
166
- Note that type parameters are not concrete types, and are thus not subject to the field type restrictions stated earlier.
167
-
168
-
169
- # Anonymous records
170
-
171
- An anonymous record is not defined anywhere, but consists of zero or more fields. The fields may have any type, but can't be reassigned after creation.
172
-
173
- ```firefly
174
- (red = 255, green = 255, blue = 0)
175
- ```
176
-
177
- This constructs an anonymous record.
178
- If you have an anonymous record value, e.g. `color: (red: Int, green: Int, blue: Int)`, you can access its fields:
179
-
180
- ```firefly
181
- color.red // Returns an Int
182
- color.green // Returns an Int
183
- color.blue // Returns an Int
184
- ```
1
+ # User defined types
2
+
3
+ Named types can be defined at the top level, using one of four keywords: `data`, `class`, `capability` or `newtype`.
4
+
5
+
6
+ # data
7
+
8
+ To define an immutable type, you can use the `data` keyword.
9
+
10
+ ```firefly
11
+ data Shape {
12
+ Circle(x: Float, y: Float, radius: Float)
13
+ Rectangle(x: Float, y: Float, width: Float, height: Float)
14
+ }
15
+ ```
16
+
17
+ This defines a type called `Shape` with two variants `Circle` and `Rectangle`.
18
+ The `Circle` variant has three named fields of type `Float`, while the `Rectangle` variant has four.
19
+
20
+ Type and variant names must start with a capital letter.
21
+
22
+ No `class` or `capability` types can occur in the definition of a `data` type.
23
+
24
+ A value of type `Shape` is either a `Circle` or a `Rectangle`, and they can be constructed as follows:
25
+
26
+ ```firefly
27
+ Circle(0.0, 0.0, 1.0) // Variant, : Shape
28
+ Rectangle(5.0, 7.0, 3.0, 2.0) // Variant, : Shape
29
+ ```
30
+
31
+ Above the variants are constructed using positional arguments, whose order must coincide with the order of the parameters in the type definition.
32
+
33
+ Named arguments are supported as well:
34
+
35
+ ```firefly
36
+ Circle(x = 0.0, y = 0.0, radius = 1.0)
37
+ ```
38
+
39
+ Named parameters don't have to be in order, and can be mixed with positional arguments:
40
+
41
+ ```firefly
42
+ Circle(radius = 1.0, 0.0, 0.0)
43
+ ```
44
+
45
+ To branch on the specific variant of a type, use [pattern matching](pattern-matching).
46
+
47
+
48
+ # Common fields
49
+
50
+ When all the variants share a set of fields, they can be moved to the common fields section of the declaration:
51
+
52
+ ```firefly
53
+ data Shape(x: Float, y: Float) {
54
+ Circle(radius: Float)
55
+ Rectangle(width: Float, height: Float)
56
+ }
57
+ ```
58
+
59
+ This is similar to the `Shape` definition above, but the `x` and `y` fields have been pulled out as common fields.
60
+ Given a value of a type, e.g. `shape: Shape`, common fields can be accessed without knowing which specific variant it is:
61
+
62
+ ```firefly
63
+ shape.x // Returns a Float
64
+ shape.y // Returns a Float
65
+ ```
66
+
67
+ When there is only one variant of a type, and its name coincides with the name of the type, we can use a shorthand definition:
68
+
69
+ ```firefly
70
+ data Point(x: Float, y: Float)
71
+ ```
72
+
73
+ This defines a type called `Point` with a single variant, also named `Point`, and two common fields of type `Float`.
74
+
75
+
76
+ # Copying
77
+
78
+ If you have a value and want to construct a variant, you can copy each field explicitly:
79
+
80
+ ```firefly
81
+ Rectangle(x = point.x, y = point.y, width = 2.0, height = 1.5)
82
+ ```
83
+
84
+ There's a shorthand for doing this, however:
85
+
86
+ ```firefly
87
+ point.Rectangle(width = 2.0, height = 1.5)
88
+ ```
89
+
90
+ Using this shorthand, the fields of `Rectangle` that aren't specified will be copied from `point`.
91
+
92
+
93
+
94
+ # class
95
+
96
+ Types defined with the `class` keyword work like `data` types, except for the differences noted here.
97
+
98
+ Fields of `class` types may be declared `mutable`:
99
+
100
+ ```firefly
101
+ class FruitBasket(
102
+ mutable apples: Int
103
+ mutable oranges: Int
104
+ mutable bananas: Int
105
+ )
106
+ ```
107
+
108
+ Mutable fields can be updated. Given a value `basket: FruitBasket`, its fields can be assigned to:
109
+
110
+ ```firefly
111
+ basket.apples = 42 // The apples field now holds the value 42
112
+ basket.oranges += 1 // The oranges field is now one greater
113
+ basket.bananas -= 1 // The bananas field is now one less
114
+ ```
115
+
116
+ Except for `capability` types, all types can occur in the definition of a `class` type.
117
+
118
+
119
+ # capability
120
+
121
+ Types defined with the `capability` keyword work like `class` types, except for the differences noted here.
122
+
123
+ ```firefly
124
+ capability EventHandler(
125
+ onEvent: () => Unit
126
+ )
127
+ ```
128
+
129
+ The `onEvent` field here contains a first class function, which may have captured other capabilities or classes in its closure.
130
+ Therefore, calling the function contained in this field may cause side effects.
131
+
132
+ In particular, it may have captured the `system` argument that's passed to the main function, or other capabilities that allow it to do I/O.
133
+
134
+ There are no restrictions on the types of fields that `capability` types can have.
135
+
136
+ Function types `=>` are considered `capability` types.
137
+
138
+
139
+ # newtype
140
+
141
+ Types defined with the `newtype` keyword work like `data` types, except that they must have exactly one common field and no explicitly listed variants.
142
+
143
+ ```firefly
144
+ newtype UserId(id: Int)
145
+ ```
146
+
147
+ At runtime, they are represented as values of the field type.
148
+ In this case, it means that `UserId(42)` is represented as the `Int` value `42` at runtime, with zero overhead.
149
+
150
+
151
+ # Generic types
152
+
153
+ Whether you use `data`, `class`, `capability` or `newtype` to define a type, it may have type parameters.
154
+
155
+ ```firefly
156
+ data Basket[T](
157
+ items: List[T]
158
+ )
159
+ ```
160
+
161
+ Here the `T` in `Basket[T]` is a type parameter, and it's used as a type argument in `List[T]`.
162
+
163
+ An unbounded type parameter can be instantiated to any type.
164
+ We can have a `Basket[Shape]`, which has a field `items: List[Shape]`, and a different type `Basket[EventHandler]`, which has a field `items: List[EventHandler]`.
165
+
166
+ Note that type parameters are not concrete types, and are thus not subject to the field type restrictions stated earlier.
167
+
168
+
169
+ # Anonymous records
170
+
171
+ An anonymous record is not defined anywhere, but consists of zero or more fields. The fields may have any type, but can't be reassigned after creation.
172
+
173
+ ```firefly
174
+ (red = 255, green = 255, blue = 0)
175
+ ```
176
+
177
+ This constructs an anonymous record.
178
+ If you have an anonymous record value, e.g. `color: (red: Int, green: Int, blue: Int)`, you can access its fields:
179
+
180
+ ```firefly
181
+ color.red // Returns an Int
182
+ color.green // Returns an Int
183
+ color.blue // Returns an Int
184
+ ```
@@ -1,136 +1,136 @@
1
- # Control flow
2
-
3
- Firefly provides several ways to implement branching. Pattern matching is the most powerful, built directly into the language. `if`, `elseIf` and `else` do what you expect and are functions and methods in the standard library, implemented using the `Option` type. An then finally, there are [exceptions](#Exceptions).
4
-
5
- # Pattern matching
6
-
7
- Pattern matching allows you to check a given data structure against a pattern. For example, if we want to parse the command line arguments provided by the user, we could do it like this:
8
-
9
- ```firefly
10
- let pair = system.arguments().{
11
- | [host] => Pair(host, 80)
12
- | ["localhost", port] => Pair("localhost", port.grabInt())
13
- | _ =>
14
- system.writeErrorLine("Usage: 'localhost' | (host port)")
15
- system.exit(0)
16
- }
17
- ```
18
-
19
- In Firefly you construct a list of strings (`List[String]`) like this `["example.com", "80"]`, and using pattern matching you can de-construct in the same way.
20
-
21
- ```firefly
22
- data.{
23
- | pattern1 => // case 1
24
- | pattern2 => // case N
25
- ...
26
- }
27
- ```
28
-
29
- The patterns must be exhaustive, that is, for any possible value of the given type, there must be a matching pattern. In the example above, there are no value for the empty list `[]` , list with two values, where the first is not `"localhost"` or lists with more than 2 arguments. That's why we need the wildcard case at the end. Without this last case, the compiler would produce a compile-time error, stating that the patterns must be exhaustive.
30
-
31
- Here are more examples — all exhaustive. Let's start with records:
32
-
33
- ```firefly
34
- pair.{
35
- | Pair(first, second) =>
36
- }
37
- ```
38
-
39
- Numbers
40
-
41
- ```firefly
42
- n.{
43
- | 1 =>
44
- | 2 =>
45
- | n =>
46
- }
47
- ```
48
-
49
- Booleans
50
-
51
- ```firefly
52
- n.{
53
- | True =>
54
- | False =>
55
- }
56
- ```
57
-
58
- And you can combine pattern as needed. Imagine you have a pair of type `Pair[List[Bool], Pair(Int, String)]`
59
-
60
-
61
- ```firefly
62
- pair.{
63
- | Pair([True, False], Pair(42, "foo")) =>
64
- | other =>
65
- }
66
- ```
67
-
68
-
69
- # Option
70
-
71
- Sometimes you don't have a value. Other languages uses null for this purpose, but Firefly does not have null. Instead, we have `Option` from the core package.
72
-
73
-
74
- ```firefly
75
- data Option[T] {
76
- None
77
- Some(value: T)
78
- }
79
- ```
80
-
81
- For some type `T`, say `String`, `Option[String]` is either some string or no value `None`. This way, the type system guides you to check for no-value.
82
-
83
- Many functions and methods returns an `Option` in Firefly. For instance the `getInt` method on `String`. This method returns `Some[Int]` when the string consists only of digits and `None` otherwise. We can perform pattern matching on Option like this:
84
-
85
- ```firefly
86
- port.getInt().{
87
- | None => 80
88
- | Some(p) => p
89
- }
90
- ```
91
-
92
- Many methods like `getInt` have a non-total counterpart `grabInt`, which returns an `Int`. But it will throw an exception when the input cannot be parsed. Options let's you code in an exception-safe manner.
93
-
94
-
95
- # if - elseIf - else
96
-
97
- You write if-statements in Firefly like this:
98
-
99
- ```firefly
100
- if(path == "/") {
101
- response.writeText("<!doctype html>")
102
- } elseIf {path.startsWith("/js/")} {
103
- response.writeText("<script>")
104
- } else {
105
- response.writeStatus("404 Not found")
106
- }
107
- ```
108
-
109
- You can also use it as an expression like this
110
-
111
-
112
- ```firefly
113
- let contentType = if(path == "/") {
114
- "text/html; charset=UTF-8"
115
- } elseIf(directory2.exists) {
116
- "text/javascript; charset=UTF-8"
117
- } else {
118
- "text/plain; charset=UTF-8"
119
- }
120
- ```
121
-
122
- `if`, `elseIf` and `else` are not keywords or construct build into Firefly. `if` is just a function defined like this:
123
-
124
-
125
- ```firefly
126
- if[T](condition: Bool, body: () => T): Option[T] {
127
- condition.{
128
- | False => None
129
- | True => Some(body())
130
- }
131
- }
132
- ```
133
-
134
- # Exceptions
135
-
136
- ...
1
+ # Control flow
2
+
3
+ Firefly provides several ways to implement branching. Pattern matching is the most powerful, built directly into the language. `if`, `elseIf` and `else` do what you expect and are functions and methods in the standard library, implemented using the `Option` type. An then finally, there are [exceptions](#Exceptions).
4
+
5
+ # Pattern matching
6
+
7
+ Pattern matching allows you to check a given data structure against a pattern. For example, if we want to parse the command line arguments provided by the user, we could do it like this:
8
+
9
+ ```firefly
10
+ let pair = system.arguments().{
11
+ | [host] => Pair(host, 80)
12
+ | ["localhost", port] => Pair("localhost", port.grabInt())
13
+ | _ =>
14
+ system.writeErrorLine("Usage: 'localhost' | (host port)")
15
+ system.exit(0)
16
+ }
17
+ ```
18
+
19
+ In Firefly you construct a list of strings (`List[String]`) like this `["example.com", "80"]`, and using pattern matching you can de-construct in the same way.
20
+
21
+ ```firefly
22
+ data.{
23
+ | pattern1 => // case 1
24
+ | pattern2 => // case N
25
+ ...
26
+ }
27
+ ```
28
+
29
+ The patterns must be exhaustive, that is, for any possible value of the given type, there must be a matching pattern. In the example above, there are no value for the empty list `[]` , list with two values, where the first is not `"localhost"` or lists with more than 2 arguments. That's why we need the wildcard case at the end. Without this last case, the compiler would produce a compile-time error, stating that the patterns must be exhaustive.
30
+
31
+ Here are more examples — all exhaustive. Let's start with records:
32
+
33
+ ```firefly
34
+ pair.{
35
+ | Pair(first, second) =>
36
+ }
37
+ ```
38
+
39
+ Numbers
40
+
41
+ ```firefly
42
+ n.{
43
+ | 1 =>
44
+ | 2 =>
45
+ | n =>
46
+ }
47
+ ```
48
+
49
+ Booleans
50
+
51
+ ```firefly
52
+ n.{
53
+ | True =>
54
+ | False =>
55
+ }
56
+ ```
57
+
58
+ And you can combine pattern as needed. Imagine you have a pair of type `Pair[List[Bool], Pair(Int, String)]`
59
+
60
+
61
+ ```firefly
62
+ pair.{
63
+ | Pair([True, False], Pair(42, "foo")) =>
64
+ | other =>
65
+ }
66
+ ```
67
+
68
+
69
+ # Option
70
+
71
+ Sometimes you don't have a value. Other languages uses null for this purpose, but Firefly does not have null. Instead, we have `Option` from the core package.
72
+
73
+
74
+ ```firefly
75
+ data Option[T] {
76
+ None
77
+ Some(value: T)
78
+ }
79
+ ```
80
+
81
+ For some type `T`, say `String`, `Option[String]` is either some string or no value `None`. This way, the type system guides you to check for no-value.
82
+
83
+ Many functions and methods returns an `Option` in Firefly. For instance the `getInt` method on `String`. This method returns `Some[Int]` when the string consists only of digits and `None` otherwise. We can perform pattern matching on Option like this:
84
+
85
+ ```firefly
86
+ port.getInt().{
87
+ | None => 80
88
+ | Some(p) => p
89
+ }
90
+ ```
91
+
92
+ Many methods like `getInt` have a non-total counterpart `grabInt`, which returns an `Int`. But it will throw an exception when the input cannot be parsed. Options let's you code in an exception-safe manner.
93
+
94
+
95
+ # if - elseIf - else
96
+
97
+ You write if-statements in Firefly like this:
98
+
99
+ ```firefly
100
+ if(path == "/") {
101
+ response.writeText("<!doctype html>")
102
+ } elseIf {path.startsWith("/js/")} {
103
+ response.writeText("<script>")
104
+ } else {
105
+ response.writeStatus("404 Not found")
106
+ }
107
+ ```
108
+
109
+ You can also use it as an expression like this
110
+
111
+
112
+ ```firefly
113
+ let contentType = if(path == "/") {
114
+ "text/html; charset=UTF-8"
115
+ } elseIf(directory2.exists) {
116
+ "text/javascript; charset=UTF-8"
117
+ } else {
118
+ "text/plain; charset=UTF-8"
119
+ }
120
+ ```
121
+
122
+ `if`, `elseIf` and `else` are not keywords or construct build into Firefly. `if` is just a function defined like this:
123
+
124
+
125
+ ```firefly
126
+ if[T](condition: Bool, body: () => T): Option[T] {
127
+ condition.{
128
+ | False => None
129
+ | True => Some(body())
130
+ }
131
+ }
132
+ ```
133
+
134
+ # Exceptions
135
+
136
+ ...