firefly-compiler 0.4.78 → 0.4.80

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 (67) hide show
  1. package/compiler/Builder.ff +2 -2
  2. package/compiler/Compiler.ff +1 -1
  3. package/compiler/Inference.ff +2 -1
  4. package/compiler/JsEmitter.ff +11 -17
  5. package/compiler/Main.ff +3 -3
  6. package/compiler/ModuleCache.ff +1 -1
  7. package/compiler/Tokenizer.ff +1 -1
  8. package/compiler/Unification.ff +1 -1
  9. package/core/.firefly/include/package-lock.json +267 -97
  10. package/core/.firefly/include/package.json +1 -1
  11. package/core/Float.ff +25 -0
  12. package/core/Lock.ff +1 -1
  13. package/core/NodeSystem.ff +1 -1
  14. package/core/Stream.ff +9 -9
  15. package/core/Task.ff +3 -3
  16. package/core/Try.ff +25 -4
  17. package/experimental/s3/S3TestAuthorizationHeader.ff +2 -1
  18. package/experimental/s3/S3TestPut.ff +2 -1
  19. package/fireflysite/CommunityOverview.ff +2 -2
  20. package/fireflysite/CountingButtonDemo.ff +1 -1
  21. package/fireflysite/DocumentParser.ff +332 -0
  22. package/fireflysite/ExamplesOverview.ff +11 -2
  23. package/fireflysite/FrontPage.ff +344 -0
  24. package/fireflysite/{GuideIntroduction.ff → GettingStarted.ff} +1 -25
  25. package/fireflysite/Guide.ff +239 -104
  26. package/fireflysite/Main.ff +100 -51
  27. package/fireflysite/MatchingPasswordsDemo.ff +13 -17
  28. package/fireflysite/PackagesOverview.ff +1 -1
  29. package/fireflysite/PostgresqlDemo.ff +34 -0
  30. package/fireflysite/ReferenceAll.ff +19 -0
  31. package/fireflysite/ReferenceIntroduction.ff +11 -0
  32. package/fireflysite/Styles.ff +358 -97
  33. package/fireflysite/Test.ff +38 -0
  34. package/fireflysite/assets/font/NotoSansMono-Regular.ttf +0 -0
  35. package/fireflysite/assets/font/NunitoSans-VariableFont_YTLC,opsz,wdth,wght.ttf +0 -0
  36. package/fireflysite/assets/image/autocomplete-small.png +0 -0
  37. package/fireflysite/assets/image/autocomplete.png +0 -0
  38. package/fireflysite/assets/image/edit-time-error.png +0 -0
  39. package/fireflysite/assets/image/firefly-logo-yellow.png +0 -0
  40. package/fireflysite/assets/markdown/reference/BaseTypes.md +209 -0
  41. package/fireflysite/assets/markdown/reference/FunctionsAndMethods.md +208 -0
  42. package/fireflysite/assets/markdown/reference/ModulesAndPackages.md +168 -0
  43. package/fireflysite/assets/markdown/reference/PatternMatching.md +224 -0
  44. package/fireflysite/assets/markdown/reference/StatementsAndExpressions.md +86 -0
  45. package/fireflysite/assets/markdown/reference/TraitsAndInstances.md +100 -0
  46. package/fireflysite/assets/markdown/reference/UserDefinedTypes.md +184 -0
  47. package/fireflysite/assets/markdown/scratch/ControlFlow.md +136 -0
  48. package/fireflysite/assets/markdown/scratch/Toc.md +41 -0
  49. package/lsp/Handler.ff +4 -4
  50. package/lsp/LanguageServer.ff +5 -5
  51. package/lux/Lux.ff +9 -9
  52. package/lux/Main2.ff +1 -1
  53. package/output/js/ff/compiler/Builder.mjs +4 -4
  54. package/output/js/ff/compiler/Inference.mjs +2 -2
  55. package/output/js/ff/compiler/JsEmitter.mjs +18 -72
  56. package/output/js/ff/compiler/Main.mjs +4 -4
  57. package/output/js/ff/compiler/ModuleCache.mjs +4 -4
  58. package/output/js/ff/core/Float.mjs +50 -0
  59. package/output/js/ff/core/NodeSystem.mjs +4 -4
  60. package/output/js/ff/core/Task.mjs +8 -8
  61. package/output/js/ff/core/Try.mjs +98 -4
  62. package/package.json +1 -1
  63. package/postgresql/Pg.ff +1 -1
  64. package/vscode/package.json +15 -1
  65. package/vscode/syntaxes/firefly-markdown-injection.json +45 -0
  66. package/webserver/.firefly/include/package-lock.json +7 -1
  67. /package/fireflysite/{firefly-logo-notext.png → assets/image/firefly-logo-notext.png} +0 -0
@@ -0,0 +1,344 @@
1
+ import Guide
2
+ import CountingButtonDemo
3
+ import MatchingPasswordsDemo
4
+
5
+ new(): Document {
6
+ ReadyDocument([
7
+ Section("The full-stack programming language", [
8
+ Paragraph([
9
+ Text("Firefly code runs in the browser and on the server, or even at build time. ")
10
+ Text("You can implement highly interactive webapps without resorting to JavaScript. ")
11
+ Text("The basic skeleton of a webapp looks like this: ")
12
+ ])
13
+ CodeBlock("""
14
+ dependency ff:webserver:0.0.0
15
+
16
+ // Runs on the server
17
+ nodeMain(system: NodeSystem) {...}
18
+
19
+ // Runs in the browser
20
+ browserMain(system: BrowserSystem) {...}
21
+
22
+ // Runs at build time
23
+ buildMain(system: BuildSystem) {...}
24
+ """, firefly = True)
25
+ Paragraph([
26
+ Text("When starting out, you can put everything in a single ")
27
+ Code(".ff")
28
+ Text(" file, including your dependency list. ")
29
+ Text("As the code base grows, you can split it into multiple files and packages. ")
30
+ Text("Read on for a tour of the language. ")
31
+ ])
32
+ ])
33
+ SplitSection(
34
+ "Concise type definitions"
35
+ Paragraph([
36
+ Text("Model your types in a brief format that fits multiple definitions on one screen.")
37
+ Text("Be precise about whether things can be missing with")
38
+ Code("Option[T]", firefly = True)
39
+ Text("and make invalid states unrepresentable with variants and type parameters.")
40
+ ])
41
+ CodeBlock("""
42
+ data User(
43
+ id: UserId
44
+ name: String
45
+ email: Option[String]
46
+ )
47
+
48
+ data BlockElement {
49
+ Paragraph(text: String)
50
+ Code(code: String, type: Option[String])
51
+ Video(url: String)
52
+ }
53
+ """, firefly = True)
54
+ )
55
+ SplitSection(
56
+ "Deep pattern matching"
57
+ Paragraph([
58
+ Text("You can directly pattern match on function arguments, even in lambda functions.")
59
+ Text("The compiler checks for exhaustiveness, ensuring that all possible cases are covered.")
60
+ Text("Pattern guards are supported, so you can extract things with arbitrary logic.")
61
+ ])
62
+ CodeBlock("""
63
+ blockElements.map {
64
+ | Paragraph(text) =>
65
+ renderParagraph(text)
66
+ | Code(code, Some(type)) =>
67
+ renderHighlighted(code, type)
68
+ | Code(code, None) =>
69
+ renderCode(code)
70
+ | Video(url) {vimeoId(url) | Some(id)} =>
71
+ renderVimeo(id)
72
+ | Video(url) =>
73
+ renderVideo(url)
74
+ }
75
+ """, firefly = True)
76
+ )
77
+ SplitSection(
78
+ "Convenient collections"
79
+ Paragraph([
80
+ Text("Immutable and mutable collections are part of the standard library.")
81
+ Text("Maps, sets, arrays, lists and streams come with a rich set of methods that you can use to write code that's instantly clear to the reader.")
82
+ ])
83
+ CodeBlock("""
84
+ let emails = houses
85
+ .flatMap {_.owners}
86
+ .map {_.email}
87
+ .filter {!_.endsWith("example.com")}
88
+ .toSet()
89
+
90
+ emails.each {email =>
91
+ sendNeighborhoodNewsletter(email)
92
+ }
93
+ """, firefly = True)
94
+ )
95
+ SplitSection(
96
+ "Edit time error detection"
97
+ Paragraph([
98
+ Text("In Firefly, a large class of errors is detected by the IDE as you type.")
99
+ Text("You can usually fix these without even reading the error message.")
100
+ Text("And when you need to read the error messages, they're short and to the point.")
101
+ ])
102
+ Image("/assets/image/edit-time-error.png")
103
+ )
104
+ SplitSection(
105
+ "Type driven autocompletion"
106
+ Paragraph([
107
+ Text("The language server comes with type driven autocompletion.")
108
+ Text("It instantly presents a very precise list of completions, and the expected type is used to preselect a likely completion.")
109
+ ])
110
+ Image("/assets/image/autocomplete-small.png")
111
+ )
112
+ SplitSection(
113
+ "No async dilemma"
114
+ Paragraph([
115
+ Text("In Firefly, there's no")
116
+ Code("async")
117
+ Text("or")
118
+ Code("await")
119
+ Text("syntax.")
120
+ Text("Instead, the compiler infers which calls are asynchronous and automatically generates the appropriate code.")
121
+ Text("A method like")
122
+ Code(".map")
123
+ Text("on lists is called asynchronously only when the lambda function you pass is asynchronous.")
124
+ ])
125
+ CodeBlock("""
126
+ let files = ["a.txt", "b.txt"]
127
+ // async .map call
128
+ let contents = files.map {file =>
129
+ system.path(file).readText()
130
+ }
131
+ // sync .map call
132
+ let upper = contents.map {content =>
133
+ content.upper()
134
+ }
135
+ """, firefly = True)
136
+ )
137
+ SplitSection(
138
+ "No hidden I/O"
139
+ Paragraph([
140
+ Text("The main function is passed a")
141
+ Code("system")
142
+ Text("argument that represents all the I/O you can do.")
143
+ Text("It's a plain object, and you can simply wrap it to create a new")
144
+ Text("object with less capabilities. You can tell what effects a top level function")
145
+ Text("can have simply by looking at what arguments it receives.")
146
+ ])
147
+ CodeBlock("""
148
+ nodeMain(system: NodeSytem) {
149
+ let html = fetchSite(system.httpClient())
150
+ system.writeLine(html)
151
+ }
152
+
153
+ // this function can only do HTTP requests
154
+ fetchSite(httpClient: HttpClient): String {
155
+ let url = "https://www.example.com/"
156
+ httpClient.get(url, []) {_.readText()}
157
+ }
158
+ """, firefly = True)
159
+ )
160
+ SplitSection(
161
+ "Structural equality"
162
+ Paragraph([
163
+ Text("Traits are used for equality, ordering etc., and the core traits are automatically implemented for")
164
+ Code("data")
165
+ Text("types if you don't supply your own implementation.")
166
+ Text("They make")
167
+ Code("==")
168
+ Text("and")
169
+ Code("<")
170
+ Text("type safe, unlike in most languages, and")
171
+ Text("they're a lot simpler than the traits you find in Rust.")
172
+ ])
173
+ CodeBlock("""
174
+ trait T: Order {
175
+ compare(x: T, y: T): Ordering
176
+ }
177
+
178
+ instance Bool: Order {
179
+ compare(x: Bool, y: Bool): Ordering {
180
+ | False, True => OrderingBefore
181
+ | True, False => OrderingAfter
182
+ | _, _ => OrderingSame
183
+ }
184
+ }
185
+ """, firefly = True)
186
+ )
187
+ /*
188
+ SplitSection(
189
+ "Batteries included"
190
+ Paragraph([
191
+ Text("The standard library contains functionality that's required by most applications.")
192
+ Text("Apart from what you've seen above, there's also the following modules.")
193
+ ])
194
+ Bullets([
195
+ [Bold("Random:"), Text("Pseudorandom numbers")]
196
+ [Bold("Instant:"), Text("UTC timestamps")]
197
+ [Bold("Json:"), Text("JSON support")]
198
+ [Bold("Buffer:"), Text("Binary data")]
199
+ [Bold("Stream:"), Text("Streams (sync or async)")]
200
+ [Bold("Task:"), Text("Structured concurrency")]
201
+ [Bold("Log:"), Text("Simple logging")]
202
+ ])
203
+ )
204
+ */
205
+ Section("The Firefly Stack", [
206
+ Paragraph([
207
+ Bold("The Firefly Stack is a set of packages for building webapps.")
208
+ Text("The packages are maintained by the developers of Firefly.")
209
+ Text("You can use them individually or together.")
210
+ Italic("Here's what you can do with that.")
211
+ ])
212
+ ])
213
+ SplitSection(
214
+ "Interactive webapps"
215
+ Paragraph([
216
+ Text("The")
217
+ Code("ff:lux")
218
+ Text("package provides a declarative DOM framework for building highly interactive webapps.")
219
+ Text("Tasks that belong to removed nodes are automatically cancelled.")
220
+ Text("All without any virtual DOM.")
221
+ ])
222
+ CodeBlock("""
223
+ lux.useState(0): count, setCount =>
224
+ lux.button {
225
+ lux.text("Clicked " + count + " times")
226
+ lux.onClick {event =>
227
+ event.preventDefault()
228
+ setCount(count + 1)
229
+ }
230
+ }
231
+ """, firefly = True)
232
+ )
233
+ SplitSection(
234
+ "Type safe RPC"
235
+ Paragraph([
236
+ Text("All your custom")
237
+ Code("data")
238
+ Text("types are automatically serializable in Firefly.")
239
+ Text("With ")
240
+ Code("ff:rpc")
241
+ Text("you can set up type safe remote procedure calls from the browser to the webserver or between services.")
242
+ Text("You can even")
243
+ Italic("go to definition")
244
+ Text("across RPC boundaries.")
245
+ ])
246
+ CodeBlock("""
247
+ data Message(text: String)
248
+ instance Message: Rpc[Int]
249
+
250
+ // the browser sends a Message
251
+ let client = Rpc.newClient(...)
252
+ let messageId = client.call(Message("Hello"))
253
+
254
+ // the webserver replies with an Int
255
+ let server = Rpc.newServer(...)
256
+ server.add {| context, Message(text) => 42 }
257
+ """, firefly = True)
258
+ )
259
+ SplitSection(
260
+ "WebSocket server & client"
261
+ Paragraph([
262
+ Text("The ")
263
+ Code("ff:webserver")
264
+ Text("package comes with WebSocket support.")
265
+ Text("In just a few lines of code, you can start serving WebSockets.")
266
+ Text("The ")
267
+ Code("ff:websocket")
268
+ Text("package allows you to connect to any WebSocket server.")
269
+ Text("If both ends are running Firefly, you can use the built-in binary serialization.")
270
+ ])
271
+ CodeBlock("""
272
+ let server = WebServer.new(system, host, port)
273
+ server.enableWebSockets()
274
+
275
+ server.listen {request =>
276
+ let ws = request.openWebSocket()
277
+ ws.subscribe("chat")
278
+ while {True} {
279
+ let message = ws.readText().grab()
280
+ ws.publishText("chat", message)
281
+ }
282
+ }
283
+ """.replace("'''", "\"\"\""), firefly = True)
284
+ )
285
+ SplitSection(
286
+ "Database pooling"
287
+ Paragraph([
288
+ Text("The")
289
+ Code("ff:postgresql")
290
+ Text("package lets you create a connection pool for a PostgreSQL database.")
291
+ Text("You can then execute transactions and build stateful applications.")
292
+ ])
293
+ CodeBlock("""
294
+ let pool = Pg.newPool(...)
295
+
296
+ let emails = pool.transaction {connection =>
297
+ connection
298
+ .statement('''
299
+ select email from users
300
+ where id <= $maxId
301
+ ''')
302
+ .withInt("maxId", 100)
303
+ .map {_.getString("email").grab()}
304
+ }
305
+ """.replace("'''", "\"\"\""), firefly = True)
306
+ )
307
+ Section("What Firefly doesn't have", [
308
+ Bullets([
309
+ [
310
+ Bold("No function overloading.")
311
+ Text("Overloading leads to uninformative \"No matching overload\" errors.")
312
+ ]
313
+ [
314
+ Bold("No implicit casts.")
315
+ Text("Ever recieved an email addressed to \"Dear None\"? Static types fail to prevent this if you can implicitly cast an Option[T] to a String.")
316
+ ]
317
+ [
318
+ Bold("No dynamic typing.")
319
+ Text("Dynamic typing causes runtime errors and encourages hidden and underspecified contracts that makes refactoring harder than it needs to be.")
320
+ ]
321
+ [
322
+ Bold("No nulls.")
323
+ Text("Eliminating null ensures types accurately represent known values, reducing runtime errors and redundant checks.")
324
+ ]
325
+ [
326
+ Bold("No subtyping.")
327
+ Text("Subtyping introduces complexity via type bounds and variance. It also allows mixing loosely related types, promoting incomplete runtime type checks.")
328
+ ]
329
+ [
330
+ Bold("No inheritance.")
331
+ Text("Inheritance can lead to overgeneralization and scattering of business logic, making it hard to get the full picture at any level.")
332
+ ]
333
+ [
334
+ Bold("No macros.")
335
+ Text("Macros let you define whole new languages, that are typically wildly undertooled compared to the base language.")
336
+ ]
337
+ [
338
+ Bold("No type level programming.")
339
+ Text("Type level programming leads to inscrutable function signatures and hard to understand error messages.")
340
+ ]
341
+ ])
342
+ ])
343
+ ])
344
+ }
@@ -1,31 +1,7 @@
1
1
  import Guide
2
2
 
3
- mock(): List[Document] {
4
- [
5
- new()
6
- Document([Section("Control flow", [])])
7
- Document([Section("Base types", [])])
8
- Document([Section("Collections", [])])
9
- Document([Section("Custom types", [])])
10
- Document([Section("Async I/O", [])])
11
- Document([Section("Structured concurrency", [])])
12
- Document([Section("Applications", [])])
13
- Document([Section("Packages and modules", [])])
14
- Document([Section("Functions and methods", [])])
15
- Document([Section("Traits and instances", [])])
16
- Document([Section("JavaScript interop", [])])
17
- ]
18
- }
19
-
20
3
  new(): Document {
21
- Document([
22
- Section("Introduction", [
23
- Paragraph([
24
- Text("In this guide you will learn to use Firefly.")
25
- Text("Firefly is a programming language that compiles to JavaScript.")
26
- Text("It runs in the browser and on the server, and lets you develop webapps with a minimum of hassle.")
27
- ])
28
- ])
4
+ ReadyDocument([
29
5
  Section("Getting started", [
30
6
  Paragraph([
31
7
  Text("Firefly comes with a compiler, a build system and a package manager.")