@shd101wyy/yo 0.1.26 → 0.1.27

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 (167) hide show
  1. package/.github/skills/yo-async-effects/SKILL.md +4 -4
  2. package/.github/skills/yo-async-effects/async-effects-recipes.md +34 -34
  3. package/.github/skills/yo-core-patterns/SKILL.md +1 -1
  4. package/.github/skills/yo-core-patterns/core-patterns-cheatsheet.md +26 -26
  5. package/.github/skills/yo-project-workflow/SKILL.md +6 -3
  6. package/.github/skills/yo-project-workflow/workflow-cheatsheet.md +34 -11
  7. package/.github/skills/yo-syntax/SKILL.md +7 -6
  8. package/.github/skills/yo-syntax/syntax-cheatsheet.md +73 -60
  9. package/.github/skills/yo-wasm-integration/wasm-integration-cheatsheet.md +3 -3
  10. package/README.md +10 -8
  11. package/out/cjs/index.cjs +456 -438
  12. package/out/cjs/yo-cli.cjs +576 -543
  13. package/out/cjs/yo-lsp.cjs +559 -532
  14. package/out/esm/index.mjs +281 -263
  15. package/out/types/src/formatter.d.ts +11 -0
  16. package/out/types/src/lsp/formatting.d.ts +2 -0
  17. package/out/types/src/tests/formatter.test.d.ts +1 -0
  18. package/out/types/tsconfig.tsbuildinfo +1 -1
  19. package/package.json +1 -1
  20. package/std/alg/hash.yo +13 -21
  21. package/std/allocator.yo +25 -40
  22. package/std/async.yo +3 -7
  23. package/std/build.yo +105 -151
  24. package/std/cli/arg_parser.yo +184 -169
  25. package/std/collections/array_list.yo +350 -314
  26. package/std/collections/btree_map.yo +142 -131
  27. package/std/collections/deque.yo +132 -128
  28. package/std/collections/hash_map.yo +542 -566
  29. package/std/collections/hash_set.yo +623 -687
  30. package/std/collections/linked_list.yo +275 -293
  31. package/std/collections/ordered_map.yo +113 -85
  32. package/std/collections/priority_queue.yo +73 -73
  33. package/std/crypto/md5.yo +191 -95
  34. package/std/crypto/random.yo +56 -64
  35. package/std/crypto/sha256.yo +151 -107
  36. package/std/encoding/base64.yo +87 -81
  37. package/std/encoding/hex.yo +43 -50
  38. package/std/encoding/html.yo +56 -81
  39. package/std/encoding/html_char_utils.yo +7 -13
  40. package/std/encoding/html_entities.yo +2248 -2253
  41. package/std/encoding/json.yo +316 -224
  42. package/std/encoding/punycode.yo +86 -116
  43. package/std/encoding/toml.yo +67 -66
  44. package/std/encoding/utf16.yo +37 -44
  45. package/std/env.yo +62 -91
  46. package/std/error.yo +7 -15
  47. package/std/fmt/display.yo +5 -9
  48. package/std/fmt/index.yo +8 -14
  49. package/std/fmt/to_string.yo +330 -315
  50. package/std/fmt/writer.yo +58 -87
  51. package/std/fs/dir.yo +83 -102
  52. package/std/fs/file.yo +147 -180
  53. package/std/fs/metadata.yo +45 -78
  54. package/std/fs/temp.yo +55 -65
  55. package/std/fs/types.yo +27 -40
  56. package/std/fs/walker.yo +53 -68
  57. package/std/gc.yo +5 -8
  58. package/std/glob.yo +30 -43
  59. package/std/http/client.yo +107 -120
  60. package/std/http/http.yo +106 -96
  61. package/std/http/index.yo +4 -6
  62. package/std/imm/list.yo +88 -93
  63. package/std/imm/map.yo +528 -464
  64. package/std/imm/set.yo +52 -57
  65. package/std/imm/sorted_map.yo +340 -286
  66. package/std/imm/sorted_set.yo +57 -63
  67. package/std/imm/string.yo +404 -345
  68. package/std/imm/vec.yo +173 -181
  69. package/std/io/reader.yo +3 -6
  70. package/std/io/writer.yo +4 -8
  71. package/std/libc/assert.yo +5 -9
  72. package/std/libc/ctype.yo +32 -22
  73. package/std/libc/dirent.yo +26 -25
  74. package/std/libc/errno.yo +164 -90
  75. package/std/libc/fcntl.yo +52 -45
  76. package/std/libc/float.yo +66 -44
  77. package/std/libc/limits.yo +42 -33
  78. package/std/libc/math.yo +53 -82
  79. package/std/libc/signal.yo +72 -47
  80. package/std/libc/stdatomic.yo +217 -188
  81. package/std/libc/stdint.yo +5 -29
  82. package/std/libc/stdio.yo +5 -29
  83. package/std/libc/stdlib.yo +32 -39
  84. package/std/libc/string.yo +5 -23
  85. package/std/libc/sys/stat.yo +58 -56
  86. package/std/libc/time.yo +5 -19
  87. package/std/libc/unistd.yo +5 -20
  88. package/std/libc/wctype.yo +6 -9
  89. package/std/libc/windows.yo +26 -30
  90. package/std/log.yo +41 -55
  91. package/std/net/addr.yo +102 -97
  92. package/std/net/dns.yo +27 -28
  93. package/std/net/errors.yo +50 -49
  94. package/std/net/tcp.yo +113 -124
  95. package/std/net/udp.yo +55 -66
  96. package/std/os/env.yo +35 -33
  97. package/std/os/signal.yo +15 -25
  98. package/std/path.yo +276 -311
  99. package/std/prelude.yo +6304 -4315
  100. package/std/process/command.yo +87 -103
  101. package/std/process/index.yo +12 -31
  102. package/std/regex/compiler.yo +196 -95
  103. package/std/regex/flags.yo +58 -39
  104. package/std/regex/index.yo +157 -173
  105. package/std/regex/match.yo +20 -31
  106. package/std/regex/node.yo +134 -152
  107. package/std/regex/parser.yo +283 -259
  108. package/std/regex/unicode.yo +172 -202
  109. package/std/regex/vm.yo +155 -171
  110. package/std/string/index.yo +5 -7
  111. package/std/string/rune.yo +45 -55
  112. package/std/string/string.yo +937 -964
  113. package/std/string/string_builder.yo +94 -104
  114. package/std/string/unicode.yo +46 -64
  115. package/std/sync/channel.yo +72 -73
  116. package/std/sync/cond.yo +31 -36
  117. package/std/sync/mutex.yo +30 -32
  118. package/std/sync/once.yo +13 -16
  119. package/std/sync/rwlock.yo +26 -31
  120. package/std/sync/waitgroup.yo +20 -25
  121. package/std/sys/advise.yo +16 -24
  122. package/std/sys/bufio/buf_reader.yo +77 -93
  123. package/std/sys/bufio/buf_writer.yo +52 -65
  124. package/std/sys/clock.yo +4 -9
  125. package/std/sys/constants.yo +77 -61
  126. package/std/sys/copy.yo +4 -10
  127. package/std/sys/dir.yo +26 -43
  128. package/std/sys/dns.yo +41 -61
  129. package/std/sys/errors.yo +95 -103
  130. package/std/sys/events.yo +45 -57
  131. package/std/sys/externs.yo +319 -267
  132. package/std/sys/fallocate.yo +7 -11
  133. package/std/sys/fcntl.yo +14 -22
  134. package/std/sys/file.yo +26 -40
  135. package/std/sys/future.yo +5 -8
  136. package/std/sys/iov.yo +12 -25
  137. package/std/sys/lock.yo +12 -13
  138. package/std/sys/mmap.yo +38 -43
  139. package/std/sys/path.yo +3 -8
  140. package/std/sys/perm.yo +7 -21
  141. package/std/sys/pipe.yo +5 -12
  142. package/std/sys/process.yo +23 -29
  143. package/std/sys/seek.yo +10 -12
  144. package/std/sys/signal.yo +7 -13
  145. package/std/sys/signals.yo +52 -35
  146. package/std/sys/socket.yo +63 -58
  147. package/std/sys/socketpair.yo +3 -6
  148. package/std/sys/sockinfo.yo +11 -20
  149. package/std/sys/statfs.yo +11 -34
  150. package/std/sys/statx.yo +25 -52
  151. package/std/sys/sysinfo.yo +15 -20
  152. package/std/sys/tcp.yo +62 -92
  153. package/std/sys/temp.yo +5 -9
  154. package/std/sys/time.yo +5 -15
  155. package/std/sys/timer.yo +6 -11
  156. package/std/sys/tty.yo +10 -18
  157. package/std/sys/udp.yo +22 -39
  158. package/std/sys/umask.yo +3 -6
  159. package/std/sys/unix.yo +33 -52
  160. package/std/testing/bench.yo +49 -52
  161. package/std/thread.yo +10 -15
  162. package/std/time/datetime.yo +105 -89
  163. package/std/time/duration.yo +43 -56
  164. package/std/time/instant.yo +13 -18
  165. package/std/time/sleep.yo +5 -9
  166. package/std/url/index.yo +184 -209
  167. package/std/worker.yo +6 -10
package/std/http/http.yo CHANGED
@@ -1,163 +1,177 @@
1
1
  //! HTTP core types — methods, headers, requests, and responses.
2
2
  // std/http/http.yo - HTTP types and request/response builders
3
-
4
- open import "../string";
5
- { ArrayList } :: import "../collections/array_list";
6
- { ToString } :: import "../fmt";
7
-
3
+ open(import("../string"));
4
+ { ArrayList } :: import("../collections/array_list");
5
+ { ToString } :: import("../fmt");
8
6
  /// Standard HTTP request methods.
9
7
  HttpMethod :: enum(GET, POST, PUT, DELETE, HEAD, PATCH);
10
-
11
- impl(HttpMethod, ToString(
12
- to_string : (self ->
13
- match(self,
14
- .GET => `GET`,
15
- .POST => `POST`,
16
- .PUT => `PUT`,
17
- .DELETE => `DELETE`,
18
- .HEAD => `HEAD`,
19
- .PATCH => `PATCH`
8
+ impl(
9
+ HttpMethod,
10
+ ToString(
11
+ to_string : (
12
+ self ->
13
+ match(
14
+ self,
15
+ .GET => `GET`,
16
+ .POST => `POST`,
17
+ .PUT => `PUT`,
18
+ .DELETE => `DELETE`,
19
+ .HEAD => `HEAD`,
20
+ .PATCH => `PATCH`
21
+ )
20
22
  )
21
23
  )
22
- ));
23
-
24
+ );
24
25
  /// An HTTP header as a name-value pair.
25
- HttpHeader :: object(name: String, value: String);
26
-
27
- impl(HttpHeader,
26
+ HttpHeader :: object(name : String, value : String);
27
+ impl(
28
+ HttpHeader,
28
29
  /// Create a new header with the given name and value.
29
- new : (fn(name: String, value: String) -> Self)(
30
- Self(name: name, value: value)
30
+ new : (fn(name : String, value : String) -> Self)(
31
+ Self(name : name, value : value)
31
32
  )
32
33
  );
33
-
34
34
  /// An HTTP request with method, path, headers, and optional body.
35
35
  HttpRequest :: object(
36
- method: HttpMethod,
37
- path: String,
38
- headers: ArrayList(HttpHeader),
39
- body: String
36
+ method : HttpMethod,
37
+ path : String,
38
+ headers : ArrayList(HttpHeader),
39
+ body : String
40
40
  );
41
-
42
- impl(HttpRequest,
41
+ impl(
42
+ HttpRequest,
43
43
  /// Create a new request with the given method and path.
44
- new : (fn(method: HttpMethod, path: String) -> Self)(
45
- Self(method: method, path: path, headers: ArrayList(HttpHeader).new(), body: ``)
44
+ new : (fn(method : HttpMethod, path : String) -> Self)(
45
+ Self(method : method, path : path, headers : ArrayList(HttpHeader).new(), body : ``)
46
46
  ),
47
-
48
47
  /// Add a header and return the request (builder pattern).
49
- header : (fn(self: Self, name: String, value: String) -> Self)({
48
+ header : (fn(self : Self, name : String, value : String) -> Self)({
50
49
  self.headers.push(HttpHeader.new(name, value));
51
50
  self
52
51
  }),
53
-
54
52
  /// Set the request body and return the request (builder pattern).
55
- with_body : (fn(self: Self, body: String) -> Self)({
53
+ with_body : (fn(self : Self, body : String) -> Self)({
56
54
  self.body = body;
57
55
  self
58
56
  }),
59
-
60
57
  /// Set the Host header.
61
- set_host : (fn(self: Self, host: String) -> unit)({
58
+ set_host : (fn(self : Self, host : String) -> unit)({
62
59
  self.headers.push(HttpHeader.new(`Host`, host));
63
60
  }),
64
-
65
61
  /// Append a header to the request.
66
- set_header : (fn(self: Self, name: String, value: String) -> unit)({
62
+ set_header : (fn(self : Self, name : String, value : String) -> unit)({
67
63
  self.headers.push(HttpHeader.new(name, value));
68
64
  }),
69
-
70
65
  /// Set the request body.
71
- set_body : (fn(self: Self, body: String) -> unit)({
66
+ set_body : (fn(self : Self, body : String) -> unit)({
72
67
  self.body = body;
73
68
  }),
74
-
75
69
  /// Serialize the request to an HTTP/1.1 wire-format string.
76
- to_string : (fn(self: Self) -> String)({
70
+ to_string : (fn(self : Self) -> String)({
77
71
  result := `${self.method.to_string()} ${self.path} HTTP/1.1\r\n`;
78
72
  i := usize(0);
79
- while (i < self.headers.len()), (i = (i + usize(1))), {
73
+ while(i < self.headers.len(), i = (i + usize(1)), {
80
74
  h := self.headers.get(i).unwrap();
81
75
  result = `${result}${h.name}: ${h.value}\r\n`;
82
- };
76
+ });
83
77
  result = `${result}\r\n`;
84
78
  cond(
85
- (!(self.body.is_empty())) => { result = `${result}${self.body}`; },
79
+ (!(self.body.is_empty())) => {
80
+ result = `${result}${self.body}`;
81
+ },
86
82
  true => ()
87
83
  );
88
84
  result
89
85
  })
90
86
  );
91
-
92
87
  /// An HTTP response with status code, headers, and body.
93
88
  HttpResponse :: object(
94
- status_code: i32,
95
- status_text: String,
96
- headers: ArrayList(HttpHeader),
97
- body: String
89
+ status_code : i32,
90
+ status_text : String,
91
+ headers : ArrayList(HttpHeader),
92
+ body : String
98
93
  );
99
-
100
- impl(HttpResponse,
94
+ impl(
95
+ HttpResponse,
101
96
  /// Create a new response with the given status code and text.
102
- new : (fn(status_code: i32, status_text: String) -> Self)(
103
- Self(status_code: status_code, status_text: status_text, headers: ArrayList(HttpHeader).new(), body: ``)
97
+ new : (fn(status_code : i32, status_text : String) -> Self)(
98
+ Self(status_code : status_code, status_text : status_text, headers : ArrayList(HttpHeader).new(), body : ``)
104
99
  ),
105
-
106
100
  /// Look up a header value by name (case-insensitive).
107
- get_header : (fn(self: Self, name: String) -> Option(String))({
101
+ get_header : (fn(self : Self, name : String) -> Option(String))({
108
102
  lower_name := name.to_lowercase();
109
103
  i := usize(0);
110
- while (i < self.headers.len()), (i = (i + usize(1))), {
104
+ while(i < self.headers.len(), i = (i + usize(1)), {
111
105
  h := self.headers.get(i).unwrap();
112
- cond((h.name.to_lowercase() == lower_name) => { return .Some(h.value); }, true => ());
113
- };
106
+ cond(
107
+ (h.name.to_lowercase() == lower_name) => {
108
+ return(.Some(h.value));
109
+ },
110
+ true => ()
111
+ );
112
+ });
114
113
  .None
115
114
  }),
116
-
117
115
  /// Return `true` if the status code is in the 2xx range.
118
- is_ok : (fn(self: Self) -> bool)(
119
- ((self.status_code >= i32(200)) && (self.status_code < i32(300)))
116
+ is_ok : (fn(self : Self) -> bool)(
117
+ (self.status_code >= i32(200)) && (self.status_code < i32(300))
120
118
  ),
121
-
122
119
  /// Return `true` if the status code is in the 3xx range.
123
- is_redirect : (fn(self: Self) -> bool)(
124
- ((self.status_code >= i32(300)) && (self.status_code < i32(400)))
120
+ is_redirect : (fn(self : Self) -> bool)(
121
+ (self.status_code >= i32(300)) && (self.status_code < i32(400))
125
122
  ),
126
-
127
123
  /// Return `true` if the status code is 4xx or higher.
128
- is_error : (fn(self: Self) -> bool)(
129
- (self.status_code >= i32(400))
124
+ is_error : (fn(self : Self) -> bool)(
125
+ self.status_code >= i32(400)
130
126
  )
131
127
  );
132
-
133
128
  /// Parse a raw HTTP response string into an `HttpResponse`.
134
- parse_response :: (fn(raw: String) -> Result(HttpResponse, String))({
129
+ parse_response :: (fn(raw : String) -> Result(HttpResponse, String))({
135
130
  lines := raw.split(`\r\n`);
136
- cond((lines.len() == usize(0)) => { return .Err(`Empty response`); }, true => ());
137
-
131
+ cond(
132
+ (lines.len() == usize(0)) => {
133
+ return(.Err(`Empty response`));
134
+ },
135
+ true => ()
136
+ );
138
137
  status_line := lines.get(usize(0)).unwrap();
139
- cond((!(status_line.starts_with(`HTTP/`))) => { return .Err(`Invalid status line`); }, true => ());
140
-
138
+ cond(
139
+ (!(status_line.starts_with(`HTTP/`))) => {
140
+ return(.Err(`Invalid status line`));
141
+ },
142
+ true => ()
143
+ );
141
144
  sp1_opt := status_line.index_of(` `);
142
- cond(sp1_opt.is_none() => { return .Err(`Invalid status line format`); }, true => ());
145
+ cond(
146
+ sp1_opt.is_none() => {
147
+ return(.Err(`Invalid status line format`));
148
+ },
149
+ true => ()
150
+ );
143
151
  sp1 := sp1_opt.unwrap();
144
- rest := status_line.substring((sp1 + usize(1)), status_line.len());
145
-
152
+ rest := status_line.substring(sp1 + usize(1), status_line.len());
146
153
  sp2_opt := rest.index_of(` `);
147
- cond(sp2_opt.is_none() => { return .Err(`Invalid status line format`); }, true => ());
154
+ cond(
155
+ sp2_opt.is_none() => {
156
+ return(.Err(`Invalid status line format`));
157
+ },
158
+ true => ()
159
+ );
148
160
  sp2 := sp2_opt.unwrap();
149
161
  code_str := rest.substring(usize(0), sp2);
150
- status_text := rest.substring((sp2 + usize(1)), rest.len());
151
-
162
+ status_text := rest.substring(sp2 + usize(1), rest.len());
152
163
  code_opt := code_str.parse_i32();
153
- cond(code_opt.is_none() => { return .Err(`Invalid status code`); }, true => ());
164
+ cond(
165
+ code_opt.is_none() => {
166
+ return(.Err(`Invalid status code`));
167
+ },
168
+ true => ()
169
+ );
154
170
  code := code_opt.unwrap();
155
-
156
171
  resp := HttpResponse.new(code, status_text);
157
-
158
172
  j := usize(1);
159
173
  body_start := lines.len();
160
- while (j < lines.len()), (j = (j + usize(1))), {
174
+ while(j < lines.len(), j = (j + usize(1)), {
161
175
  hline := lines.get(j).unwrap();
162
176
  cond(
163
177
  hline.is_empty() => {
@@ -170,31 +184,28 @@ parse_response :: (fn(raw: String) -> Result(HttpResponse, String))({
170
184
  colon_opt.is_some() => {
171
185
  colon := colon_opt.unwrap();
172
186
  hname := hline.substring(usize(0), colon).trim();
173
- hval := hline.substring((colon + usize(1)), hline.len()).trim();
187
+ hval := hline.substring(colon + usize(1), hline.len()).trim();
174
188
  resp.headers.push(HttpHeader.new(hname, hval));
175
189
  },
176
190
  true => ()
177
191
  );
178
192
  }
179
193
  );
180
- };
181
-
194
+ });
182
195
  cond(
183
196
  (body_start < lines.len()) => {
184
197
  resp.body = lines.get(body_start).unwrap();
185
198
  m := (body_start + usize(1));
186
- while (m < lines.len()), (m = (m + usize(1))), {
199
+ while(m < lines.len(), m = (m + usize(1)), {
187
200
  resp.body = `${resp.body}\r\n${lines.get(m).unwrap()}`;
188
- };
201
+ });
189
202
  },
190
203
  true => ()
191
204
  );
192
-
193
205
  .Ok(resp)
194
206
  });
195
-
196
207
  /// Return the standard status text for an HTTP status code.
197
- http_status_text :: (fn(code: i32) -> String)(
208
+ http_status_text :: (fn(code : i32) -> String)(
198
209
  cond(
199
210
  (code == i32(200)) => `OK`,
200
211
  (code == i32(201)) => `Created`,
@@ -211,6 +222,5 @@ http_status_text :: (fn(code: i32) -> String)(
211
222
  true => `Unknown`
212
223
  )
213
224
  );
214
-
215
- export HttpMethod, HttpHeader, HttpRequest, HttpResponse;
216
- export parse_response, http_status_text;
225
+ export(HttpMethod, HttpHeader, HttpRequest, HttpResponse);
226
+ export(parse_response, http_status_text);
package/std/http/index.yo CHANGED
@@ -13,11 +13,9 @@
13
13
  // resp := io.await(fetch(`http://example.com`, using(io)));
14
14
  // println(resp.body);
15
15
  // });
16
-
17
- _http :: import "./http.yo";
18
- _client :: import "./client.yo";
19
-
20
- export
16
+ _http :: import("./http.yo");
17
+ _client :: import("./client.yo");
18
+ export(
21
19
  ...(_http),
22
20
  ...(_client)
23
- ;
21
+ );
package/std/imm/list.yo CHANGED
@@ -15,24 +15,22 @@
15
15
  //! assert((xs.head().unwrap() == i32(1)), "head is 1");
16
16
  //! assert((xs.len() == usize(3)), "length is 3");
17
17
  //! ```
18
-
19
- { GlobalAllocator } :: import "../allocator.yo";
18
+ { GlobalAllocator } :: import("../allocator.yo");
20
19
  { malloc, free } :: GlobalAllocator;
21
- { memcpy } :: import "../libc/string.yo";
22
-
20
+ { memcpy } :: import("../libc/string.yo");
23
21
  /// Internal cons cell — atomic object for thread-safe structural sharing.
24
22
  ListNode :: (fn(comptime(T) : Type, where(T <: Send)) -> comptime(Type))(
25
- atomic object(
26
- _value : T,
27
- _next : Option(Self)
23
+ atomic(
24
+ object(
25
+ _value : T,
26
+ _next : Option(Self)
27
+ )
28
28
  )
29
29
  );
30
-
31
30
  // Manual Acyclic impl — ListNode is self-referential, so auto-derivation skips it.
32
31
  // This is safe because ListNode is immutable: all operations create new nodes and never
33
32
  // mutate existing ones, making it impossible to form cycles at runtime.
34
33
  impl(forall(T : Type), where(T <: Send), ListNode(T), Acyclic());
35
-
36
34
  /// Persistent immutable singly-linked list.
37
35
  ///
38
36
  /// A value-type wrapper around an optional chain of `ListNode` atomic objects.
@@ -44,211 +42,208 @@ List :: (fn(comptime(T) : Type, where(T <: Send)) -> comptime(Type))(
44
42
  _len : usize
45
43
  )
46
44
  );
47
-
48
- impl(forall(T : Type), where(T <: Send), List(T),
45
+ impl(
46
+ forall(T : Type),
47
+ where(T <: Send),
48
+ List(T),
49
49
  /// Create an empty list.
50
50
  new : (fn() -> Self)(
51
- Self(_head: .None, _len: usize(0))
51
+ Self(_head :.None, _len : usize(0))
52
52
  ),
53
-
54
53
  /// Return the number of elements.
55
54
  len : (fn(self : Self) -> usize)(
56
55
  self._len
57
56
  ),
58
-
59
57
  /// Return `true` if the list is empty.
60
58
  is_empty : (fn(self : Self) -> bool)(
61
- (self._len == usize(0))
59
+ self._len == usize(0)
62
60
  ),
63
-
64
61
  /// Return a new list with `value` at the front. O(1).
65
62
  prepend : (fn(self : Self, value : T) -> Self)(
66
63
  Self(
67
- _head: .Some(ListNode(T)(_value: value, _next: self._head)),
68
- _len: (self._len + usize(1))
64
+ _head :.Some(ListNode(T)(_value : value, _next : self._head)),
65
+ _len : (self._len + usize(1))
69
66
  )
70
67
  ),
71
-
72
68
  /// Return the first element, or `.None` if empty. O(1).
73
69
  head : (fn(self : Self) -> Option(T))(
74
- match(self._head,
75
- .Some(node) => .Some(node._value),
76
- .None => .None
70
+ match(
71
+ self._head,
72
+ .Some(node) =>.Some(node._value),
73
+ .None =>.None
77
74
  )
78
75
  ),
79
-
80
76
  /// Return a new list without the first element. O(1).
81
77
  /// Returns an empty list if already empty.
82
78
  tail : (fn(self : Self) -> Self)(
83
- match(self._head,
84
- .Some(node) => Self(_head: node._next, _len: (self._len - usize(1))),
79
+ match(
80
+ self._head,
81
+ .Some(node) => Self(_head : node._next, _len : (self._len - usize(1))),
85
82
  .None => self
86
83
  )
87
84
  ),
88
-
89
85
  /// Access element at `index`. O(n).
90
86
  /// Returns `.None` if index is out of bounds.
91
87
  get : (fn(self : Self, index : usize) -> Option(T))({
92
- if((index >= self._len), {
93
- return .None;
88
+ if(index >= self._len, {
89
+ return(.None);
94
90
  });
95
91
  (current : Option(ListNode(T))) = self._head;
96
92
  (i : usize) = usize(0);
97
- while runtime(true), {
98
- match(current,
93
+ while(runtime(true), {
94
+ match(
95
+ current,
99
96
  .Some(node) => {
100
- if((i == index), {
101
- return .Some(node._value);
97
+ if(i == index, {
98
+ return(.Some(node._value));
102
99
  });
103
100
  current = node._next;
104
101
  i = (i + usize(1));
105
102
  },
106
103
  .None => {
107
- return .None;
104
+ return(.None);
108
105
  }
109
106
  );
110
- };
107
+ });
111
108
  .None
112
109
  }),
113
-
114
110
  /// Return a new list with elements in reverse order. O(n).
115
111
  reverse : (fn(self : Self) -> Self)({
116
112
  (result : Self) = Self.new();
117
113
  (current : Option(ListNode(T))) = self._head;
118
- while runtime(current.is_some()), {
114
+ while(runtime(current.is_some()), {
119
115
  (node : ListNode(T)) = current.unwrap();
120
116
  result = result.prepend(node._value);
121
117
  current = node._next;
122
- };
118
+ });
123
119
  result
124
120
  }),
125
-
126
121
  /// Concatenate two lists. O(n) where n = self.len().
127
122
  /// The resulting list contains all elements of `self` followed by `other`.
128
123
  concat : (fn(self : Self, other : Self) -> Self)({
129
124
  reversed := self.reverse();
130
125
  (result : Self) = other;
131
126
  (current : Option(ListNode(T))) = reversed._head;
132
- while runtime(current.is_some()), {
127
+ while(runtime(current.is_some()), {
133
128
  (node : ListNode(T)) = current.unwrap();
134
129
  result = result.prepend(node._value);
135
130
  current = node._next;
136
- };
131
+ });
137
132
  result
138
133
  }),
139
-
140
134
  /// Apply a function to each element, producing a new list. O(n).
141
135
  map : (fn(forall(U : Type), self : Self, f : Impl(Fn(a : T) -> U), where(U <: Send)) -> List(U))({
142
136
  (result : List(U)) = List(U).new();
143
137
  (current : Option(ListNode(T))) = self._head;
144
- while runtime(current.is_some()), {
138
+ while(runtime(current.is_some()), {
145
139
  (node : ListNode(T)) = current.unwrap();
146
140
  result = result.prepend(f(node._value));
147
141
  current = node._next;
148
- };
142
+ });
149
143
  result.reverse()
150
144
  }),
151
-
152
145
  /// Keep only elements satisfying the predicate. O(n).
153
146
  filter : (fn(self : Self, f : Impl(Fn(a : T) -> bool)) -> Self)({
154
147
  (result : Self) = Self.new();
155
148
  (current : Option(ListNode(T))) = self._head;
156
- while runtime(current.is_some()), {
149
+ while(runtime(current.is_some()), {
157
150
  (node : ListNode(T)) = current.unwrap();
158
151
  if(f(node._value), {
159
152
  result = result.prepend(node._value);
160
153
  });
161
154
  current = node._next;
162
- };
155
+ });
163
156
  result.reverse()
164
157
  }),
165
-
166
158
  /// Left fold over the list. O(n).
167
159
  fold : (fn(forall(U : Type), self : Self, init : U, f : Impl(Fn(acc : U, item : T) -> U)) -> U)({
168
160
  (acc : U) = init;
169
161
  (current : Option(ListNode(T))) = self._head;
170
- while runtime(current.is_some()), {
162
+ while(runtime(current.is_some()), {
171
163
  (node : ListNode(T)) = current.unwrap();
172
164
  acc = f(acc, node._value);
173
165
  current = node._next;
174
- };
166
+ });
175
167
  acc
176
168
  }),
177
-
178
169
  /// Execute a function for each element. O(n).
179
170
  for_each : (fn(self : Self, f : Impl(Fn(a : T) -> unit)) -> unit)({
180
171
  (current : Option(ListNode(T))) = self._head;
181
- while runtime(current.is_some()), {
172
+ while(runtime(current.is_some()), {
182
173
  (node : ListNode(T)) = current.unwrap();
183
174
  f(node._value);
184
175
  current = node._next;
185
- };
176
+ });
186
177
  }),
187
-
188
178
  /// Check if the list contains a value. O(n).
189
179
  /// Requires T to implement Eq.
190
180
  contains : (fn(self : Self, value : T, where(T <: Eq(T))) -> bool)({
191
181
  (current : Option(ListNode(T))) = self._head;
192
- while runtime(true), {
193
- match(current,
182
+ while(runtime(true), {
183
+ match(
184
+ current,
194
185
  .Some(node) => {
195
- if((node._value == value), {
196
- return true;
186
+ if(node._value == value, {
187
+ return(true);
197
188
  });
198
189
  current = node._next;
199
190
  },
200
191
  .None => {
201
- return false;
192
+ return(false);
202
193
  }
203
194
  );
204
- };
195
+ });
205
196
  false
206
197
  }),
207
-
208
198
  /// Build a list from a slice. O(n).
209
199
  from_slice : (fn(s : Slice(T)) -> Self)({
210
200
  (result : Self) = Self.new();
211
201
  (i : usize) = s.len();
212
- while ((i > usize(0))), {
202
+ while(i > usize(0), {
213
203
  i = (i - usize(1));
214
204
  result = result.prepend(s(i));
215
- };
205
+ });
216
206
  result
217
207
  })
218
208
  );
219
-
220
209
  /// Equality: two lists are equal if they have the same length and elements.
221
- impl(forall(T : Type), where(T <: (Send, Eq(T))), List(T), Eq(List(T))(
222
- (==) : (fn(lhs : Self, rhs : Self) -> bool)({
223
- if((lhs._len != rhs._len), {
224
- return false;
225
- });
226
- (l : Option(ListNode(T))) = lhs._head;
227
- (r : Option(ListNode(T))) = rhs._head;
228
- while runtime(true), {
229
- match(l,
230
- .Some(ln) => match(r,
231
- .Some(rn) => {
232
- if((ln._value != rn._value), {
233
- return false;
234
- });
235
- l = ln._next;
236
- r = rn._next;
237
- },
210
+ impl(
211
+ forall(T : Type),
212
+ where(T <: (Send, Eq(T))),
213
+ List(T),
214
+ Eq(List(T))(
215
+ (==) : (fn(lhs : Self, rhs : Self) -> bool)({
216
+ if(lhs._len != rhs._len, {
217
+ return(false);
218
+ });
219
+ (l : Option(ListNode(T))) = lhs._head;
220
+ (r : Option(ListNode(T))) = rhs._head;
221
+ while(runtime(true), {
222
+ match(
223
+ l,
224
+ .Some(ln) => match(
225
+ r,
226
+ .Some(rn) => {
227
+ if(ln._value != rn._value, {
228
+ return(false);
229
+ });
230
+ l = ln._next;
231
+ r = rn._next;
232
+ },
233
+ .None => {
234
+ return(false);
235
+ }
236
+ ),
238
237
  .None => {
239
- return false;
238
+ return(true);
240
239
  }
241
- ),
242
- .None => {
243
- return true;
244
- }
245
- );
246
- };
247
- true
248
- })
249
- ));
250
-
251
- export
240
+ );
241
+ });
242
+ true
243
+ })
244
+ )
245
+ );
246
+ export(
252
247
  List,
253
248
  ListNode
254
- ;
249
+ );