firefly-compiler 0.5.35 → 0.5.37

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,224 +1,224 @@
1
- # Pattern matching
2
-
3
- Every function lets you pattern match on its arguments. Pattern matching lets you branch on the structure of arguments and extract nested values.
4
-
5
-
6
- # In anonymous functions
7
-
8
- In the following example, `map` is passed an anonymous function, which pattern matches on its argument:
9
-
10
- ```firefly
11
- blockElements.map {
12
- | Paragraph(text) =>
13
- renderParagraph(text)
14
- | Code(code, Some(type)) =>
15
- renderHighlighted(code, type)
16
- | Code(code, None) =>
17
- renderCode(code)
18
- | Video(url) {vimeoId(url) | Some(id)} =>
19
- renderVimeo(id)
20
- | Video(url) =>
21
- renderVideo(url)
22
- }
23
- ```
24
-
25
- In this example there are five cases, and `blockElements: List[BlockElement]` with the following type definition:
26
-
27
- ```firefly
28
- data BlockElement {
29
- Paragraph(text: String)
30
- Code(code: String, type: Option[String])
31
- Video(url: String)
32
- }
33
- ```
34
-
35
- If you have multiple arguments, you need to provide a pattern for each argument, separated by commas.
36
-
37
-
38
- # Cases
39
-
40
- Each case must have one or more patterns, zero or more guards, and zero or more statements.
41
-
42
- The first case starts with a pattern that matches when the argument is `Paragraph`, and extracts its `text` field into a variable named `text`:
43
-
44
- ```firefly
45
- | Paragraph(text) =>
46
- ```
47
-
48
- The variable is in scope in the statements of the case following the `=>`.
49
- The field name and the variable name do not have to be the same.
50
- The variable could be named `t` or `foo`, even though the type defines a field named `text`.
51
-
52
- The second case starts with a pattern that matches when the argument is `Code`, and the second field of that is `Some`:
53
-
54
- ```firefly
55
- | Code(code, Some(type)) =>
56
- ```
57
-
58
- The third case starts with a pattern that matches when the argument is `Code`, and the second field of that is `None`:
59
-
60
- ```firefly
61
- | Code(code, None) =>
62
- ```
63
-
64
- Together with the case above, it covers all the values that can be constructed using the `Code` variant.
65
-
66
- The fourth case starts with a pattern that matches when the argument is `Video`, and then uses a guard:
67
-
68
- ```firefly
69
- | Video(url) {vimeoId(url) | Some(id)} =>
70
- ```
71
-
72
- The guard calls a function on the extracted field, and matches the result against the pattern `Some(id)`.
73
-
74
- The fifth and final case starts with a pattern that matches when the argument is `Video`, and has no guard:
75
-
76
- ```firefly
77
- | Video(url) =>
78
- ```
79
-
80
- Together with the case above, it convers all the values that can be constructed using the `Video` variant.
81
-
82
-
83
- # Exhaustiveness
84
-
85
- Since all the ways to construct a `BlockElement` has been covered by the cases, the pattern match is exhaustive.
86
- Exhaustiveness is enforced in Firefly, so it's never possible to end up in a situation at runtime where no case matches the arguments.
87
-
88
- Cases are tried in order until one of them matches. When a case matches, its statements will be run.
89
- In this case a return value is expected, and thus the last statement must be an expression, whose value will be returned.
90
-
91
-
92
- # Alias patterns
93
-
94
- To extract all the fields of a variant as an anonymous record, use the a pattern like this:
95
-
96
- ```firefly
97
- | Code c =>
98
- renderCode(c.code)
99
- ```
100
-
101
- Here `c: (code: String, type: Option[String])` - that is, it's an anonymous record with the fields of the variant.
102
-
103
- To pattern match on a value while also extracting that value into a variable, use a pattern like this:
104
-
105
- ```firefly
106
- | Code(code, Some(_) @ typeOption) =>
107
- ```
108
-
109
- This ensures that the case only matches if the type field is `Some`, but binds the whole option into a variable `typeOption: Option[String]`.
110
-
111
-
112
- # In pipes
113
-
114
- Another way to write the above is to pipe the argument into an anonymous function that pattern matches on it:
115
-
116
- ```firefly
117
- blockElements.map {blockElement =>
118
- blockElement.{
119
- | Paragraph(text) =>
120
- renderParagraph(text)
121
- | Code(code, Some(type)) =>
122
- renderHighlighted(code, type)
123
- | Code(code, None) =>
124
- renderCode(code)
125
- | Video(url) {vimeoId(url) | Some(id)} =>
126
- renderVimeo(id)
127
- | Video(url) =>
128
- renderVideo(url)
129
- }
130
- }
131
- ```
132
-
133
- This is also a way to pattern match on one of many arguments, a local variable or an expression.
134
-
135
-
136
- # In named functions
137
-
138
- Pattern matching may also be used for the arguments of named functions and methods. Here's an example of pattern matching in a local function:
139
-
140
- ```firefly
141
- function render(element: BlockElement) {
142
- | Paragraph(text) =>
143
- renderParagraph(text)
144
- | Code(code, Some(type)) =>
145
- renderHighlighted(code, type)
146
- | Code(code, None) =>
147
- renderCode(code)
148
- | Video(url) {vimeoId(url) | Some(id)} =>
149
- renderVimeo(id)
150
- | Video(url) =>
151
- renderVideo(url)
152
- }
153
- ```
154
-
155
- Here's an example of pattern matching in a method:
156
-
157
- ```firefly
158
- extend self: Renderer {
159
- render(element: BlockElement) {
160
- | Paragraph(text) =>
161
- self.renderParagraph(text)
162
- | Code(code, Some(type)) =>
163
- self.renderHighlighted(code, type)
164
- | Code(code, None) =>
165
- self.renderCode(code)
166
- | Video(url) {vimeoId(url) | Some(id)} =>
167
- self.renderVimeo(id)
168
- | Video(url) =>
169
- self.renderVideo(url)
170
- }
171
- }
172
- ```
173
-
174
-
175
- # Literals and wildcards
176
-
177
- It's also possible to match on `Int`, `Char`, `String`, and `List[T]` values.
178
-
179
- Here's an example that matches on `Int`:
180
-
181
- ```firefly
182
- fib(n: Int): Int {
183
- | 0 => 0
184
- | 1 => 1
185
- | _ => fib(n - 1) + fib(n - 2)
186
- }
187
- ```
188
-
189
- The wildcard pattern `_` matches any value without binding it to a variable.
190
-
191
- Here's an example that matches on `Char`:
192
-
193
- ```firefly
194
- extend self: Player {
195
- go(key: Char) {
196
- | 'w' => self.goUp()
197
- | 'a' => self.goLeft()
198
- | 's' => self.goDown()
199
- | 'd' => self.goRight()
200
- | _ =>
201
- }
202
- }
203
- ```
204
-
205
- Here's an example that matches on `String`:
206
-
207
- ```firefly
208
- name.{
209
- | "" => "Hello, there!"
210
- | _ => "Hello, " + name + "!"
211
- }
212
- ```
213
-
214
- Here's an example that matches on `List[Int]`:
215
-
216
- ```firefly
217
- numbers.{
218
- | [] => "No numbers!"
219
- | [n] => "One number, " + n + "!"
220
- | [n, ...ns] => "A number, " + n + ", and " + ns.size() + " more numbers!"
221
- }
222
- ```
223
-
224
- In patterns, the spread syntax `...` matches the rest of a list.
1
+ # Pattern matching
2
+
3
+ Every function lets you pattern match on its arguments. Pattern matching lets you branch on the structure of arguments and extract nested values.
4
+
5
+
6
+ # In anonymous functions
7
+
8
+ In the following example, `map` is passed an anonymous function, which pattern matches on its argument:
9
+
10
+ ```firefly
11
+ blockElements.map {
12
+ | Paragraph(text) =>
13
+ renderParagraph(text)
14
+ | Code(code, Some(type)) =>
15
+ renderHighlighted(code, type)
16
+ | Code(code, None) =>
17
+ renderCode(code)
18
+ | Video(url) {vimeoId(url) | Some(id)} =>
19
+ renderVimeo(id)
20
+ | Video(url) =>
21
+ renderVideo(url)
22
+ }
23
+ ```
24
+
25
+ In this example there are five cases, and `blockElements: List[BlockElement]` with the following type definition:
26
+
27
+ ```firefly
28
+ data BlockElement {
29
+ Paragraph(text: String)
30
+ Code(code: String, type: Option[String])
31
+ Video(url: String)
32
+ }
33
+ ```
34
+
35
+ If you have multiple arguments, you need to provide a pattern for each argument, separated by commas.
36
+
37
+
38
+ # Cases
39
+
40
+ Each case must have one or more patterns, zero or more guards, and zero or more statements.
41
+
42
+ The first case starts with a pattern that matches when the argument is `Paragraph`, and extracts its `text` field into a variable named `text`:
43
+
44
+ ```firefly
45
+ | Paragraph(text) =>
46
+ ```
47
+
48
+ The variable is in scope in the statements of the case following the `=>`.
49
+ The field name and the variable name do not have to be the same.
50
+ The variable could be named `t` or `foo`, even though the type defines a field named `text`.
51
+
52
+ The second case starts with a pattern that matches when the argument is `Code`, and the second field of that is `Some`:
53
+
54
+ ```firefly
55
+ | Code(code, Some(type)) =>
56
+ ```
57
+
58
+ The third case starts with a pattern that matches when the argument is `Code`, and the second field of that is `None`:
59
+
60
+ ```firefly
61
+ | Code(code, None) =>
62
+ ```
63
+
64
+ Together with the case above, it covers all the values that can be constructed using the `Code` variant.
65
+
66
+ The fourth case starts with a pattern that matches when the argument is `Video`, and then uses a guard:
67
+
68
+ ```firefly
69
+ | Video(url) {vimeoId(url) | Some(id)} =>
70
+ ```
71
+
72
+ The guard calls a function on the extracted field, and matches the result against the pattern `Some(id)`.
73
+
74
+ The fifth and final case starts with a pattern that matches when the argument is `Video`, and has no guard:
75
+
76
+ ```firefly
77
+ | Video(url) =>
78
+ ```
79
+
80
+ Together with the case above, it convers all the values that can be constructed using the `Video` variant.
81
+
82
+
83
+ # Exhaustiveness
84
+
85
+ Since all the ways to construct a `BlockElement` has been covered by the cases, the pattern match is exhaustive.
86
+ Exhaustiveness is enforced in Firefly, so it's never possible to end up in a situation at runtime where no case matches the arguments.
87
+
88
+ Cases are tried in order until one of them matches. When a case matches, its statements will be run.
89
+ In this case a return value is expected, and thus the last statement must be an expression, whose value will be returned.
90
+
91
+
92
+ # Alias patterns
93
+
94
+ To extract all the fields of a variant as an anonymous record, use the a pattern like this:
95
+
96
+ ```firefly
97
+ | Code c =>
98
+ renderCode(c.code)
99
+ ```
100
+
101
+ Here `c: (code: String, type: Option[String])` - that is, it's an anonymous record with the fields of the variant.
102
+
103
+ To pattern match on a value while also extracting that value into a variable, use a pattern like this:
104
+
105
+ ```firefly
106
+ | Code(code, Some(_) @ typeOption) =>
107
+ ```
108
+
109
+ This ensures that the case only matches if the type field is `Some`, but binds the whole option into a variable `typeOption: Option[String]`.
110
+
111
+
112
+ # In pipes
113
+
114
+ Another way to write the above is to pipe the argument into an anonymous function that pattern matches on it:
115
+
116
+ ```firefly
117
+ blockElements.map {blockElement =>
118
+ blockElement.{
119
+ | Paragraph(text) =>
120
+ renderParagraph(text)
121
+ | Code(code, Some(type)) =>
122
+ renderHighlighted(code, type)
123
+ | Code(code, None) =>
124
+ renderCode(code)
125
+ | Video(url) {vimeoId(url) | Some(id)} =>
126
+ renderVimeo(id)
127
+ | Video(url) =>
128
+ renderVideo(url)
129
+ }
130
+ }
131
+ ```
132
+
133
+ This is also a way to pattern match on one of many arguments, a local variable or an expression.
134
+
135
+
136
+ # In named functions
137
+
138
+ Pattern matching may also be used for the arguments of named functions and methods. Here's an example of pattern matching in a local function:
139
+
140
+ ```firefly
141
+ function render(element: BlockElement) {
142
+ | Paragraph(text) =>
143
+ renderParagraph(text)
144
+ | Code(code, Some(type)) =>
145
+ renderHighlighted(code, type)
146
+ | Code(code, None) =>
147
+ renderCode(code)
148
+ | Video(url) {vimeoId(url) | Some(id)} =>
149
+ renderVimeo(id)
150
+ | Video(url) =>
151
+ renderVideo(url)
152
+ }
153
+ ```
154
+
155
+ Here's an example of pattern matching in a method:
156
+
157
+ ```firefly
158
+ extend self: Renderer {
159
+ render(element: BlockElement) {
160
+ | Paragraph(text) =>
161
+ self.renderParagraph(text)
162
+ | Code(code, Some(type)) =>
163
+ self.renderHighlighted(code, type)
164
+ | Code(code, None) =>
165
+ self.renderCode(code)
166
+ | Video(url) {vimeoId(url) | Some(id)} =>
167
+ self.renderVimeo(id)
168
+ | Video(url) =>
169
+ self.renderVideo(url)
170
+ }
171
+ }
172
+ ```
173
+
174
+
175
+ # Literals and wildcards
176
+
177
+ It's also possible to match on `Int`, `Char`, `String`, and `List[T]` values.
178
+
179
+ Here's an example that matches on `Int`:
180
+
181
+ ```firefly
182
+ fib(n: Int): Int {
183
+ | 0 => 0
184
+ | 1 => 1
185
+ | _ => fib(n - 1) + fib(n - 2)
186
+ }
187
+ ```
188
+
189
+ The wildcard pattern `_` matches any value without binding it to a variable.
190
+
191
+ Here's an example that matches on `Char`:
192
+
193
+ ```firefly
194
+ extend self: Player {
195
+ go(key: Char) {
196
+ | 'w' => self.goUp()
197
+ | 'a' => self.goLeft()
198
+ | 's' => self.goDown()
199
+ | 'd' => self.goRight()
200
+ | _ =>
201
+ }
202
+ }
203
+ ```
204
+
205
+ Here's an example that matches on `String`:
206
+
207
+ ```firefly
208
+ name.{
209
+ | "" => "Hello, there!"
210
+ | _ => "Hello, " + name + "!"
211
+ }
212
+ ```
213
+
214
+ Here's an example that matches on `List[Int]`:
215
+
216
+ ```firefly
217
+ numbers.{
218
+ | [] => "No numbers!"
219
+ | [n] => "One number, " + n + "!"
220
+ | [n, ...ns] => "A number, " + n + ", and " + ns.size() + " more numbers!"
221
+ }
222
+ ```
223
+
224
+ In patterns, the spread syntax `...` matches the rest of a list.
@@ -1,86 +1,86 @@
1
- # Statements and expressions
2
-
3
- In Firefly, the body of functions and methods consist of zero or more statements, separated by `;`.
4
-
5
- When `;` is the last token on a line, it can be omitted.
6
-
7
- A statement is either a [local function definition](functions-and-methods), a local variable definition, an assignment or an expression.
8
-
9
- Field assignments were covered in [user defined types](user-defined types).
10
-
11
-
12
- # Local variables
13
-
14
- Local variables need an initial value:
15
-
16
- ```firefly
17
- let x = 42
18
- ```
19
-
20
- This defines immutable local variable `x: Int` with the value `42`.
21
-
22
- Variables can be reffered to by name:
23
-
24
- ```firefly
25
- x + x // Returns 84
26
- ```
27
-
28
- The type of a variable can be stated explicitly:
29
-
30
- ```firefly
31
- let y: String = "Hello"
32
- ```
33
-
34
- Mutable variables are introduced using the `mutable` keyword:
35
-
36
- ```firefly
37
- mutable z = 1
38
- ```
39
-
40
- This works like `let`, except that you're allowed to update mutable variables by assigning to them:
41
-
42
- ```firefly
43
- z = 2 // z is now 2
44
- z += 2 // z is now 4
45
- z -= 1 // z is now 3
46
- ```
47
-
48
-
49
- # Expressions
50
-
51
- Expressions can be one of the following syntactic constructs:
52
-
53
- ```firefly
54
- 42 // Int literal
55
- 42.0 // Float literal
56
- 'a' // Char literal
57
- "foo" // String literal
58
- [] // List literal
59
- {} // Function literal
60
- () // Record literal
61
- True // Variant construction
62
- x // Variable
63
- _ // Anonymous parameter
64
- f() // Function call
65
- x.y // Field access
66
- x.V() // Copy construction
67
- x.{_} // Piping
68
- !x // Unary operator
69
- a + b // Binary operator
70
- (a + b) * c // Grouping parenthesis
71
- ```
72
-
73
- Binary operators are left associative and the operator precedence is as follows, lowest to highest:
74
-
75
- * `||`
76
- * `&&`
77
- * `!=` `==`
78
- * `<=` `>=` `<` `>`
79
- * `+` `-`
80
- * `*` `/` `%`
81
- * `^`
82
- * `f()`
83
- * `x.y` `x.V()` `x.{_}`
84
-
85
- Unary operators `!` and `-` have higher precedence than `^` and lower precedence than `f()`.
86
-
1
+ # Statements and expressions
2
+
3
+ In Firefly, the body of functions and methods consist of zero or more statements, separated by `;`.
4
+
5
+ When `;` is the last token on a line, it can be omitted.
6
+
7
+ A statement is either a [local function definition](functions-and-methods), a local variable definition, an assignment or an expression.
8
+
9
+ Field assignments were covered in [user defined types](user-defined types).
10
+
11
+
12
+ # Local variables
13
+
14
+ Local variables need an initial value:
15
+
16
+ ```firefly
17
+ let x = 42
18
+ ```
19
+
20
+ This defines immutable local variable `x: Int` with the value `42`.
21
+
22
+ Variables can be reffered to by name:
23
+
24
+ ```firefly
25
+ x + x // Returns 84
26
+ ```
27
+
28
+ The type of a variable can be stated explicitly:
29
+
30
+ ```firefly
31
+ let y: String = "Hello"
32
+ ```
33
+
34
+ Mutable variables are introduced using the `mutable` keyword:
35
+
36
+ ```firefly
37
+ mutable z = 1
38
+ ```
39
+
40
+ This works like `let`, except that you're allowed to update mutable variables by assigning to them:
41
+
42
+ ```firefly
43
+ z = 2 // z is now 2
44
+ z += 2 // z is now 4
45
+ z -= 1 // z is now 3
46
+ ```
47
+
48
+
49
+ # Expressions
50
+
51
+ Expressions can be one of the following syntactic constructs:
52
+
53
+ ```firefly
54
+ 42 // Int literal
55
+ 42.0 // Float literal
56
+ 'a' // Char literal
57
+ "foo" // String literal
58
+ [] // List literal
59
+ {} // Function literal
60
+ () // Record literal
61
+ True // Variant construction
62
+ x // Variable
63
+ _ // Anonymous parameter
64
+ f() // Function call
65
+ x.y // Field access
66
+ x.V() // Copy construction
67
+ x.{_} // Piping
68
+ !x // Unary operator
69
+ a + b // Binary operator
70
+ (a + b) * c // Grouping parenthesis
71
+ ```
72
+
73
+ Binary operators are left associative and the operator precedence is as follows, lowest to highest:
74
+
75
+ * `||`
76
+ * `&&`
77
+ * `!=` `==`
78
+ * `<=` `>=` `<` `>`
79
+ * `+` `-`
80
+ * `*` `/` `%`
81
+ * `^`
82
+ * `f()`
83
+ * `x.y` `x.V()` `x.{_}`
84
+
85
+ Unary operators `!` and `-` have higher precedence than `^` and lower precedence than `f()`.
86
+