@rcrsr/rill 0.5.0 → 0.6.0

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 (240) hide show
  1. package/dist/generated/introspection-data.d.ts +1 -1
  2. package/dist/generated/introspection-data.d.ts.map +1 -1
  3. package/dist/generated/introspection-data.js +107 -186
  4. package/dist/generated/introspection-data.js.map +1 -1
  5. package/dist/generated/version-data.d.ts +1 -1
  6. package/dist/generated/version-data.js +3 -3
  7. package/dist/generated/version-data.js.map +1 -1
  8. package/dist/highlight-map.d.ts +4 -0
  9. package/dist/highlight-map.d.ts.map +1 -0
  10. package/dist/highlight-map.js +71 -0
  11. package/dist/highlight-map.js.map +1 -0
  12. package/dist/index.d.ts +2 -1
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +5 -1
  15. package/dist/index.js.map +1 -1
  16. package/dist/lexer/errors.d.ts.map +1 -1
  17. package/dist/lexer/errors.js +9 -3
  18. package/dist/lexer/errors.js.map +1 -1
  19. package/dist/lexer/operators.js +1 -1
  20. package/dist/lexer/tokenizer.d.ts.map +1 -1
  21. package/dist/lexer/tokenizer.js +0 -14
  22. package/dist/lexer/tokenizer.js.map +1 -1
  23. package/dist/parser/helpers.d.ts +8 -0
  24. package/dist/parser/helpers.d.ts.map +1 -1
  25. package/dist/parser/helpers.js +4 -4
  26. package/dist/parser/helpers.js.map +1 -1
  27. package/dist/parser/index.d.ts.map +1 -1
  28. package/dist/parser/index.js +1 -1
  29. package/dist/parser/index.js.map +1 -1
  30. package/dist/parser/parser-collect.js +1 -1
  31. package/dist/parser/parser-collect.js.map +1 -1
  32. package/dist/parser/parser-control.js +4 -4
  33. package/dist/parser/parser-control.js.map +1 -1
  34. package/dist/parser/parser-expr.js +32 -10
  35. package/dist/parser/parser-expr.js.map +1 -1
  36. package/dist/parser/parser-extract.js +7 -3
  37. package/dist/parser/parser-extract.js.map +1 -1
  38. package/dist/parser/parser-functions.d.ts.map +1 -1
  39. package/dist/parser/parser-functions.js +7 -18
  40. package/dist/parser/parser-functions.js.map +1 -1
  41. package/dist/parser/parser-literals.js +15 -15
  42. package/dist/parser/parser-literals.js.map +1 -1
  43. package/dist/parser/parser-script.js +3 -3
  44. package/dist/parser/parser-script.js.map +1 -1
  45. package/dist/parser/parser-variables.js +4 -4
  46. package/dist/parser/parser-variables.js.map +1 -1
  47. package/dist/parser/state.d.ts +1 -1
  48. package/dist/parser/state.d.ts.map +1 -1
  49. package/dist/parser/state.js +2 -2
  50. package/dist/parser/state.js.map +1 -1
  51. package/dist/runtime/core/callable.d.ts +20 -0
  52. package/dist/runtime/core/callable.d.ts.map +1 -1
  53. package/dist/runtime/core/callable.js +30 -7
  54. package/dist/runtime/core/callable.js.map +1 -1
  55. package/dist/runtime/core/context.d.ts +21 -0
  56. package/dist/runtime/core/context.d.ts.map +1 -1
  57. package/dist/runtime/core/context.js +75 -4
  58. package/dist/runtime/core/context.js.map +1 -1
  59. package/dist/runtime/core/eval/base.d.ts.map +1 -1
  60. package/dist/runtime/core/eval/base.js +3 -3
  61. package/dist/runtime/core/eval/base.js.map +1 -1
  62. package/dist/runtime/core/eval/index.d.ts.map +1 -1
  63. package/dist/runtime/core/eval/index.js +2 -0
  64. package/dist/runtime/core/eval/index.js.map +1 -1
  65. package/dist/runtime/core/eval/mixins/annotations.js +3 -3
  66. package/dist/runtime/core/eval/mixins/annotations.js.map +1 -1
  67. package/dist/runtime/core/eval/mixins/closures.d.ts.map +1 -1
  68. package/dist/runtime/core/eval/mixins/closures.js +69 -40
  69. package/dist/runtime/core/eval/mixins/closures.js.map +1 -1
  70. package/dist/runtime/core/eval/mixins/collections.js +15 -15
  71. package/dist/runtime/core/eval/mixins/collections.js.map +1 -1
  72. package/dist/runtime/core/eval/mixins/control-flow.d.ts.map +1 -1
  73. package/dist/runtime/core/eval/mixins/control-flow.js +12 -12
  74. package/dist/runtime/core/eval/mixins/control-flow.js.map +1 -1
  75. package/dist/runtime/core/eval/mixins/core.d.ts.map +1 -1
  76. package/dist/runtime/core/eval/mixins/core.js +12 -13
  77. package/dist/runtime/core/eval/mixins/core.js.map +1 -1
  78. package/dist/runtime/core/eval/mixins/expressions.js +9 -9
  79. package/dist/runtime/core/eval/mixins/expressions.js.map +1 -1
  80. package/dist/runtime/core/eval/mixins/extraction.d.ts.map +1 -1
  81. package/dist/runtime/core/eval/mixins/extraction.js +15 -15
  82. package/dist/runtime/core/eval/mixins/extraction.js.map +1 -1
  83. package/dist/runtime/core/eval/mixins/literals.js +22 -22
  84. package/dist/runtime/core/eval/mixins/literals.js.map +1 -1
  85. package/dist/runtime/core/eval/mixins/types.js +4 -4
  86. package/dist/runtime/core/eval/mixins/types.js.map +1 -1
  87. package/dist/runtime/core/eval/mixins/variables.js +34 -34
  88. package/dist/runtime/core/eval/mixins/variables.js.map +1 -1
  89. package/dist/runtime/core/execute.js +3 -3
  90. package/dist/runtime/core/execute.js.map +1 -1
  91. package/dist/runtime/core/introspection.d.ts +30 -1
  92. package/dist/runtime/core/introspection.d.ts.map +1 -1
  93. package/dist/runtime/core/introspection.js +47 -1
  94. package/dist/runtime/core/introspection.js.map +1 -1
  95. package/dist/runtime/core/types.d.ts +11 -0
  96. package/dist/runtime/core/types.d.ts.map +1 -1
  97. package/dist/runtime/core/types.js.map +1 -1
  98. package/dist/runtime/ext/builtins.js +22 -22
  99. package/dist/runtime/ext/builtins.js.map +1 -1
  100. package/dist/runtime/ext/extensions.d.ts +1 -1
  101. package/dist/runtime/ext/extensions.d.ts.map +1 -1
  102. package/dist/runtime/ext/extensions.js +4 -5
  103. package/dist/runtime/ext/extensions.js.map +1 -1
  104. package/dist/runtime/index.d.ts +6 -4
  105. package/dist/runtime/index.d.ts.map +1 -1
  106. package/dist/runtime/index.js +3 -2
  107. package/dist/runtime/index.js.map +1 -1
  108. package/dist/types.d.ts +36 -37
  109. package/dist/types.d.ts.map +1 -1
  110. package/dist/types.js +440 -120
  111. package/dist/types.js.map +1 -1
  112. package/package.json +7 -66
  113. package/README.md +0 -223
  114. package/dist/check/config.d.ts +0 -20
  115. package/dist/check/config.d.ts.map +0 -1
  116. package/dist/check/config.js +0 -151
  117. package/dist/check/config.js.map +0 -1
  118. package/dist/check/fixer.d.ts +0 -39
  119. package/dist/check/fixer.d.ts.map +0 -1
  120. package/dist/check/fixer.js +0 -119
  121. package/dist/check/fixer.js.map +0 -1
  122. package/dist/check/index.d.ts +0 -10
  123. package/dist/check/index.d.ts.map +0 -1
  124. package/dist/check/index.js +0 -21
  125. package/dist/check/index.js.map +0 -1
  126. package/dist/check/rules/anti-patterns.d.ts +0 -65
  127. package/dist/check/rules/anti-patterns.d.ts.map +0 -1
  128. package/dist/check/rules/anti-patterns.js +0 -481
  129. package/dist/check/rules/anti-patterns.js.map +0 -1
  130. package/dist/check/rules/closures.d.ts +0 -66
  131. package/dist/check/rules/closures.d.ts.map +0 -1
  132. package/dist/check/rules/closures.js +0 -370
  133. package/dist/check/rules/closures.js.map +0 -1
  134. package/dist/check/rules/collections.d.ts +0 -90
  135. package/dist/check/rules/collections.d.ts.map +0 -1
  136. package/dist/check/rules/collections.js +0 -373
  137. package/dist/check/rules/collections.js.map +0 -1
  138. package/dist/check/rules/conditionals.d.ts +0 -41
  139. package/dist/check/rules/conditionals.d.ts.map +0 -1
  140. package/dist/check/rules/conditionals.js +0 -134
  141. package/dist/check/rules/conditionals.js.map +0 -1
  142. package/dist/check/rules/flow.d.ts +0 -46
  143. package/dist/check/rules/flow.d.ts.map +0 -1
  144. package/dist/check/rules/flow.js +0 -206
  145. package/dist/check/rules/flow.js.map +0 -1
  146. package/dist/check/rules/formatting.d.ts +0 -133
  147. package/dist/check/rules/formatting.d.ts.map +0 -1
  148. package/dist/check/rules/formatting.js +0 -648
  149. package/dist/check/rules/formatting.js.map +0 -1
  150. package/dist/check/rules/helpers.d.ts +0 -26
  151. package/dist/check/rules/helpers.d.ts.map +0 -1
  152. package/dist/check/rules/helpers.js +0 -66
  153. package/dist/check/rules/helpers.js.map +0 -1
  154. package/dist/check/rules/index.d.ts +0 -21
  155. package/dist/check/rules/index.d.ts.map +0 -1
  156. package/dist/check/rules/index.js +0 -78
  157. package/dist/check/rules/index.js.map +0 -1
  158. package/dist/check/rules/loops.d.ts +0 -77
  159. package/dist/check/rules/loops.d.ts.map +0 -1
  160. package/dist/check/rules/loops.js +0 -310
  161. package/dist/check/rules/loops.js.map +0 -1
  162. package/dist/check/rules/naming.d.ts +0 -21
  163. package/dist/check/rules/naming.d.ts.map +0 -1
  164. package/dist/check/rules/naming.js +0 -174
  165. package/dist/check/rules/naming.js.map +0 -1
  166. package/dist/check/rules/strings.d.ts +0 -28
  167. package/dist/check/rules/strings.d.ts.map +0 -1
  168. package/dist/check/rules/strings.js +0 -79
  169. package/dist/check/rules/strings.js.map +0 -1
  170. package/dist/check/rules/types.d.ts +0 -41
  171. package/dist/check/rules/types.d.ts.map +0 -1
  172. package/dist/check/rules/types.js +0 -167
  173. package/dist/check/rules/types.js.map +0 -1
  174. package/dist/check/types.d.ts +0 -112
  175. package/dist/check/types.d.ts.map +0 -1
  176. package/dist/check/types.js +0 -6
  177. package/dist/check/types.js.map +0 -1
  178. package/dist/check/validator.d.ts +0 -18
  179. package/dist/check/validator.d.ts.map +0 -1
  180. package/dist/check/validator.js +0 -110
  181. package/dist/check/validator.js.map +0 -1
  182. package/dist/check/visitor.d.ts +0 -33
  183. package/dist/check/visitor.d.ts.map +0 -1
  184. package/dist/check/visitor.js +0 -259
  185. package/dist/check/visitor.js.map +0 -1
  186. package/dist/cli-check.d.ts +0 -43
  187. package/dist/cli-check.d.ts.map +0 -1
  188. package/dist/cli-check.js +0 -368
  189. package/dist/cli-check.js.map +0 -1
  190. package/dist/cli-eval.d.ts +0 -15
  191. package/dist/cli-eval.d.ts.map +0 -1
  192. package/dist/cli-eval.js +0 -116
  193. package/dist/cli-eval.js.map +0 -1
  194. package/dist/cli-exec.d.ts +0 -49
  195. package/dist/cli-exec.d.ts.map +0 -1
  196. package/dist/cli-exec.js +0 -183
  197. package/dist/cli-exec.js.map +0 -1
  198. package/dist/cli-module-loader.d.ts +0 -19
  199. package/dist/cli-module-loader.d.ts.map +0 -1
  200. package/dist/cli-module-loader.js +0 -83
  201. package/dist/cli-module-loader.js.map +0 -1
  202. package/dist/cli-shared.d.ts +0 -44
  203. package/dist/cli-shared.d.ts.map +0 -1
  204. package/dist/cli-shared.js +0 -108
  205. package/dist/cli-shared.js.map +0 -1
  206. package/dist/cli.d.ts +0 -13
  207. package/dist/cli.d.ts.map +0 -1
  208. package/dist/cli.js +0 -62
  209. package/dist/cli.js.map +0 -1
  210. package/dist/runtime/core/introspection-data.d.ts +0 -2
  211. package/dist/runtime/core/introspection-data.d.ts.map +0 -1
  212. package/dist/runtime/core/introspection-data.js +0 -618
  213. package/dist/runtime/core/introspection-data.js.map +0 -1
  214. package/dist/runtime/core/version-data.d.ts +0 -18
  215. package/dist/runtime/core/version-data.d.ts.map +0 -1
  216. package/dist/runtime/core/version-data.js +0 -16
  217. package/dist/runtime/core/version-data.js.map +0 -1
  218. package/docs/00_INDEX.md +0 -67
  219. package/docs/01_guide.md +0 -390
  220. package/docs/02_types.md +0 -504
  221. package/docs/03_variables.md +0 -324
  222. package/docs/04_operators.md +0 -629
  223. package/docs/05_control-flow.md +0 -692
  224. package/docs/06_closures.md +0 -787
  225. package/docs/07_collections.md +0 -688
  226. package/docs/08_iterators.md +0 -330
  227. package/docs/09_strings.md +0 -205
  228. package/docs/10_parsing.md +0 -366
  229. package/docs/11_reference.md +0 -600
  230. package/docs/12_examples.md +0 -748
  231. package/docs/13_modules.md +0 -519
  232. package/docs/14_host-integration.md +0 -985
  233. package/docs/15_grammar.ebnf +0 -773
  234. package/docs/16_conventions.md +0 -695
  235. package/docs/17_cli-tools.md +0 -184
  236. package/docs/18_design-principles.md +0 -247
  237. package/docs/19_cookbook.md +0 -628
  238. package/docs/88_errors.md +0 -902
  239. package/docs/99_llm-reference.txt +0 -614
  240. package/docs/assets/logo.png +0 -0
@@ -1,688 +0,0 @@
1
- # rill Collection Operators
2
-
3
- *Sequential and parallel iteration with each, map, filter, and fold*
4
-
5
- ## Overview
6
-
7
- rill provides four collection operators for transforming, filtering, and reducing data:
8
-
9
- | Operator | Execution | Accumulator | Returns |
10
- |----------|-----------|-------------|---------|
11
- | `each` | Sequential | Optional | List of all results |
12
- | `map` | Parallel | No | List of all results |
13
- | `filter` | Parallel | No | Elements where predicate is true |
14
- | `fold` | Sequential | Required | Final result only |
15
-
16
- All three operators share similar syntax but differ in execution model and output.
17
-
18
- > **Important:** Loop bodies cannot modify outer-scope variables (see [Variables](03_variables.md)). Use `fold` or `each(init)` with accumulators instead.
19
-
20
- ```rill
21
- # Sequential: results in order, one at a time
22
- [1, 2, 3] -> each { $ * 2 } # [2, 4, 6]
23
-
24
- # Parallel: results in order, concurrent execution
25
- [1, 2, 3] -> map { $ * 2 } # [2, 4, 6]
26
-
27
- # Parallel filter: keep matching elements
28
- [1, 2, 3, 4, 5] -> filter { $ > 2 } # [3, 4, 5]
29
-
30
- # Reduction: accumulates to single value
31
- [1, 2, 3] -> fold(0) { $@ + $ } # 6
32
- ```
33
-
34
- ## Body Forms
35
-
36
- Each operator accepts multiple body syntaxes. Choose based on readability and complexity.
37
-
38
- | Form | Syntax | When to Use |
39
- |------|--------|-------------|
40
- | Block | `{ body }` | Multi-statement logic; `$` is current element |
41
- | Grouped | `( expr )` | Single expression; `$` is current element |
42
- | Inline closure | `\|x\| body` | Named parameters; reusable logic |
43
- | Variable | `$fn` | Pre-defined closure; maximum reuse |
44
- | Identity | `$` | Return elements unchanged |
45
- | Method | `.method` | Apply method to each element |
46
-
47
- ### Block Form
48
-
49
- Use braces for multi-statement bodies. `$` refers to the current element.
50
-
51
- ```rill
52
- [1, 2, 3] -> each {
53
- $ :> $x
54
- $x * 2
55
- }
56
- # Result: [2, 4, 6]
57
- ```
58
-
59
- ### Grouped Expression
60
-
61
- Use parentheses for single expressions. `$` refers to the current element.
62
-
63
- ```rill
64
- [1, 2, 3] -> each ($ + 10)
65
- # Result: [11, 12, 13]
66
- ```
67
-
68
- ### Inline Closure
69
-
70
- Define parameters explicitly. The first parameter receives each element.
71
-
72
- ```rill
73
- [1, 2, 3] -> each |x| ($x * 2)
74
- # Result: [2, 4, 6]
75
- ```
76
-
77
- ### Variable Closure
78
-
79
- Reference a pre-defined closure by variable.
80
-
81
- ```rill
82
- |x| ($x * 2) :> $double
83
- [1, 2, 3] -> each $double
84
- # Result: [2, 4, 6]
85
- ```
86
-
87
- ### Identity
88
-
89
- Use bare `$` to return elements unchanged.
90
-
91
- ```rill
92
- [1, 2, 3] -> each $
93
- # Result: [1, 2, 3]
94
- ```
95
-
96
- ### Method Shorthand
97
-
98
- Use `.method` to apply a method to each element. Equivalent to `{ $.method() }`.
99
-
100
- ```rill
101
- ["hello", "world"] -> each .upper
102
- # Result: ["HELLO", "WORLD"]
103
-
104
- [" hi ", " there "] -> map .trim
105
- # Result: ["hi", "there"]
106
-
107
- ["hello", "", "world"] -> filter .empty
108
- # Result: [""]
109
- ```
110
-
111
- Methods can take arguments:
112
-
113
- ```rill
114
- ["a", "b"] -> map .pad_start(3, "0")
115
- # Result: ["00a", "00b"]
116
- ```
117
-
118
- Chain multiple methods:
119
-
120
- ```rill
121
- [" HELLO ", " WORLD "] -> map .trim.lower
122
- # Result: ["hello", "world"]
123
- ```
124
-
125
- For negation, use grouped expression:
126
-
127
- ```rill
128
- ["hello", "", "world"] -> filter (!.empty)
129
- # Result: ["hello", "world"]
130
- ```
131
-
132
- ---
133
-
134
- ## each — Sequential Iteration
135
-
136
- `each` iterates over a collection in order. Each iteration completes before the next begins.
137
-
138
- ```rill
139
- collection -> each body
140
- collection -> each (init) body # with accumulator
141
- ```
142
-
143
- ### Basic Usage
144
-
145
- ```rill
146
- # Double each number
147
- [1, 2, 3] -> each { $ * 2 }
148
- # Result: [2, 4, 6]
149
-
150
- # Transform strings
151
- ["a", "b", "c"] -> each { "{$}!" }
152
- # Result: ["a!", "b!", "c!"]
153
-
154
- # Iterate string characters
155
- "hello" -> each $
156
- # Result: ["h", "e", "l", "l", "o"]
157
- ```
158
-
159
- ### Dict Iteration
160
-
161
- When iterating over a dict, `$` contains `key` and `value` fields.
162
-
163
- ```rill
164
- [name: "alice", age: 30] -> each { "{$.key}: {$.value}" }
165
- # Result: ["name: alice", "age: 30"]
166
-
167
- [a: 1, b: 2, c: 3] -> each { $.value * 2 }
168
- # Result: [2, 4, 6]
169
- ```
170
-
171
- ### With Accumulator
172
-
173
- `each` supports an optional accumulator for stateful iteration. Two syntaxes exist.
174
-
175
- #### Block Form with `$@`
176
-
177
- Place initial value in parentheses before the block. Access accumulator via `$@`.
178
-
179
- ```rill
180
- # Running sum (scan pattern)
181
- [1, 2, 3] -> each(0) { $@ + $ }
182
- # Result: [1, 3, 6]
183
-
184
- # String concatenation
185
- ["a", "b", "c"] -> each("") { "{$@}{$}" }
186
- # Result: ["a", "ab", "abc"]
187
- ```
188
-
189
- #### Inline Closure Form
190
-
191
- Define accumulator as the last parameter with a default value.
192
-
193
- ```rill
194
- # Running sum
195
- [1, 2, 3] -> each |x, acc = 0| ($acc + $x)
196
- # Result: [1, 3, 6]
197
- ```
198
-
199
- ### Early Termination
200
-
201
- Use `break` to exit `each` early. Returns partial results collected before the break.
202
-
203
- ```rill
204
- [1, 2, 3, 4, 5] -> each {
205
- ($ == 3) ? break
206
- $ * 2
207
- }
208
- # Result: [2, 4] (partial results before break)
209
- ```
210
-
211
- ### Empty Collections
212
-
213
- `each` returns `[]` for empty collections. The body never executes.
214
-
215
- ```rill
216
- [] -> each { $ * 2 }
217
- # Result: []
218
-
219
- # With accumulator, still returns [] (not the initial value)
220
- [] -> each(0) { $@ + $ }
221
- # Result: []
222
- ```
223
-
224
- ---
225
-
226
- ## map — Parallel Iteration
227
-
228
- `map` iterates concurrently using `Promise.all`. Order is preserved despite parallel execution.
229
-
230
- ```rill
231
- collection -> map body
232
- ```
233
-
234
- ### Basic Usage
235
-
236
- ```rill
237
- # Map with closure parameter
238
- ["a", "b", "c"] -> map |x| { "{$x}!" }
239
- # Result: ["a!", "b!", "c!"]
240
-
241
- # Block expression (implicit $)
242
- [1, 2, 3] -> map { $ * 2 }
243
- # Result: [2, 4, 6]
244
-
245
- # Grouped expression
246
- [1, 2, 3] -> map ($ * 2)
247
- # Result: [2, 4, 6]
248
- ```
249
-
250
- ### Key Differences from each
251
-
252
- 1. **No accumulator**: Parallel execution has no "previous" value
253
- 2. **No break**: Cannot exit early from concurrent operations
254
- 3. **Concurrent execution**: All iterations start immediately
255
-
256
- ### When to Use map
257
-
258
- Use `map` when:
259
- - Operations are independent (no shared state)
260
- - Order of execution doesn't matter (results still ordered)
261
- - I/O-bound operations benefit from concurrency
262
-
263
- ```rill
264
- # Fetch pages concurrently (faster than sequential)
265
- ["page1", "page2", "page3"] -> map |id| fetch_page($id)
266
-
267
- # CPU-bound: same result as each, but runs in parallel
268
- [1, 2, 3, 4, 5] -> map { $ * $ }
269
- # Result: [1, 4, 9, 16, 25]
270
- ```
271
-
272
- ### Empty Collections
273
-
274
- `map` returns `[]` for empty collections. The body never executes.
275
-
276
- ```rill
277
- [] -> map { $ * 2 }
278
- # Result: []
279
- ```
280
-
281
- ---
282
-
283
- ## filter — Parallel Filtering
284
-
285
- `filter` keeps elements where the predicate returns `true`. Predicates must return boolean values. Executes concurrently using `Promise.all`.
286
-
287
- ```rill
288
- collection -> filter body
289
- ```
290
-
291
- ### Basic Usage
292
-
293
- ```rill
294
- # Keep numbers greater than 2
295
- [1, 2, 3, 4, 5] -> filter { $ > 2 }
296
- # Result: [3, 4, 5]
297
-
298
- # Keep non-empty strings
299
- ["hello", "", "world", ""] -> filter { !.empty }
300
- # Result: ["hello", "world"]
301
-
302
- # Keep even numbers
303
- [1, 2, 3, 4, 5, 6] -> filter { ($ % 2) == 0 }
304
- # Result: [2, 4, 6]
305
- ```
306
-
307
- ### All Body Forms
308
-
309
- `filter` accepts the same body forms as `map`:
310
-
311
- ```rill
312
- # Block form
313
- [1, 2, 3, 4, 5] -> filter { $ > 2 }
314
-
315
- # Grouped expression
316
- [1, 2, 3, 4, 5] -> filter ($ > 2)
317
-
318
- # Inline closure
319
- [1, 2, 3, 4, 5] -> filter |x| ($x > 2)
320
-
321
- # Variable closure
322
- |x| ($x > 2) :> $gtTwo
323
- [1, 2, 3, 4, 5] -> filter $gtTwo
324
- ```
325
-
326
- ### Dict Filtering
327
-
328
- When filtering a dict, `$` contains `key` and `value` fields. Returns list of matching entries.
329
-
330
- ```rill
331
- [a: 1, b: 5, c: 3] -> filter { $.value > 2 }
332
- # Result: [{ key: "b", value: 5 }, { key: "c", value: 3 }]
333
- ```
334
-
335
- ### String Filtering
336
-
337
- Filters characters in a string.
338
-
339
- ```rill
340
- "hello" -> filter { $ != "l" }
341
- # Result: ["h", "e", "o"]
342
- ```
343
-
344
- ### Chaining with Other Operators
345
-
346
- ```rill
347
- # Filter then transform
348
- [1, 2, 3, 4, 5] -> filter { $ > 2 } -> map { $ * 2 }
349
- # Result: [6, 8, 10]
350
-
351
- # Transform then filter
352
- [1, 2, 3, 4, 5] -> map { $ * 2 } -> filter { $ > 5 }
353
- # Result: [6, 8, 10]
354
-
355
- # Filter, transform, reduce
356
- [1, 2, 3, 4, 5] -> filter { $ > 2 } -> map { $ * 2 } -> fold(0) { $@ + $ }
357
- # Result: 24
358
- ```
359
-
360
- ### Empty Collections
361
-
362
- `filter` returns `[]` for empty collections or when nothing matches.
363
-
364
- ```rill
365
- [] -> filter { $ > 0 }
366
- # Result: []
367
-
368
- [1, 2, 3] -> filter { $ > 10 }
369
- # Result: []
370
- ```
371
-
372
- ---
373
-
374
- ## fold — Sequential Reduction
375
-
376
- `fold` reduces a collection to a single value. Requires an accumulator.
377
-
378
- Syntax forms:
379
- - Block form: `collection -> fold(init) { body }`
380
- - Closure form: `collection -> fold |x, acc = init| (body)`
381
- - Variable closure: `collection -> fold $fn`
382
-
383
- ### Basic Usage
384
-
385
- ```rill
386
- # Sum numbers
387
- [1, 2, 3] -> fold(0) { $@ + $ }
388
- # Result: 6
389
-
390
- # Same with inline closure
391
- [1, 2, 3] -> fold |x, sum = 0| ($sum + $x)
392
- # Result: 6
393
- ```
394
-
395
- ### Common Patterns
396
-
397
- #### Sum
398
-
399
- ```rill
400
- [1, 2, 3, 4, 5] -> fold(0) { $@ + $ }
401
- # Result: 15
402
- ```
403
-
404
- #### Product
405
-
406
- ```rill
407
- [1, 2, 3, 4] -> fold(1) { $@ * $ }
408
- # Result: 24
409
- ```
410
-
411
- #### Maximum
412
-
413
- ```rill
414
- [3, 1, 4, 1, 5, 9] -> fold(0) {
415
- ($@ > $) ? $@ ! $
416
- }
417
- # Result: 9
418
- ```
419
-
420
- #### Count
421
-
422
- ```rill
423
- [1, 2, 3, 4, 5] -> fold(0) { $@ + 1 }
424
- # Result: 5
425
- ```
426
-
427
- #### String Join
428
-
429
- ```rill
430
- ["a", "b", "c"] -> fold("") { "{$@}{$}" }
431
- # Result: "abc"
432
-
433
- # With separator
434
- ["a", "b", "c"] -> fold |x, acc = ""| {
435
- ($acc -> .empty) ? $x ! "{$acc},{$x}"
436
- }
437
- # Result: "a,b,c"
438
- ```
439
-
440
- ### Dict Reduction
441
-
442
- When folding over a dict, `$` contains `key` and `value` fields.
443
-
444
- ```rill
445
- [a: 1, b: 2, c: 3] -> fold |entry, sum = 0| ($sum + $entry.value)
446
- # Result: 6
447
- ```
448
-
449
- ### Reusable Reducers
450
-
451
- Define closures for common reductions.
452
-
453
- ```rill
454
- # Define reusable reducers
455
- |x, sum = 0| ($sum + $x) :> $summer
456
- |x, max = 0| (($x > $max) ? $x ! $max) :> $maxer
457
-
458
- # Use with different data
459
- [1, 2, 3] -> fold $summer # 6
460
- [3, 7, 2] -> fold $maxer # 7
461
- [9, 1, 5] -> fold $maxer # 9
462
- ```
463
-
464
- ### Empty Collections
465
-
466
- `fold` returns the initial value for empty collections. The body never executes.
467
-
468
- ```rill
469
- [] -> fold(0) { $@ + $ }
470
- # Result: 0
471
-
472
- [] -> fold(42) { $@ + $ }
473
- # Result: 42
474
-
475
- [] -> fold |x, acc = 100| ($acc + $x)
476
- # Result: 100
477
- ```
478
-
479
- ---
480
-
481
- ## Comparison: each vs fold
482
-
483
- Both `each` and `fold` support accumulators. The difference is in what they return.
484
-
485
- | Feature | each | fold |
486
- |---------|------|------|
487
- | Returns | List of ALL results | Final result ONLY |
488
- | Use case | Scan/prefix-sum | Reduce/aggregate |
489
-
490
- ### Side-by-Side Example
491
-
492
- ```rill
493
- # each: returns every intermediate result
494
- [1, 2, 3] -> each(0) { $@ + $ }
495
- # Result: [1, 3, 6] (running totals)
496
-
497
- # fold: returns only the final result
498
- [1, 2, 3] -> fold(0) { $@ + $ }
499
- # Result: 6 (final sum)
500
- ```
501
-
502
- ### When to Choose
503
-
504
- Use `each` with accumulator when you need intermediate states (scan pattern):
505
-
506
- ```rill
507
- # Running balance
508
- [100, -50, 200, -75] -> each(0) { $@ + $ }
509
- # Result: [100, 50, 250, 175]
510
- ```
511
-
512
- Use `fold` when you only need the final result:
513
-
514
- ```rill
515
- # Final balance
516
- [100, -50, 200, -75] -> fold(0) { $@ + $ }
517
- # Result: 175
518
- ```
519
-
520
- ---
521
-
522
- ## Chaining Operators
523
-
524
- Combine operators for multi-stage transformations.
525
-
526
- ```rill
527
- # Double each element, then sum
528
- [1, 2, 3] -> map { $ * 2 } -> fold(0) { $@ + $ }
529
- # Result: 12
530
-
531
- # Filter even numbers (using parallel filter)
532
- [1, 2, 3, 4, 5] -> filter { ($ % 2) == 0 }
533
- # Result: [2, 4]
534
-
535
- # Complex pipeline: filter, then transform
536
- [1, 2, 3, 4, 5] -> filter { $ > 2 } -> map { $ * 10 }
537
- # Result: [30, 40, 50]
538
- ```
539
-
540
- ---
541
-
542
- ## Closure Arity Rules
543
-
544
- For inline closures with accumulators, specific rules apply.
545
-
546
- ### Requirements
547
-
548
- 1. At least 2 parameters — first receives element, last is accumulator
549
- 2. Last parameter must have default — the default is the initial value
550
- 3. Parameters between first and last must have defaults — no gaps
551
- 4. Incoming args must exactly fill params before accumulator
552
-
553
- ### Valid Closures
554
-
555
- | Closure | Element Params | Accumulator | Notes |
556
- |---------|---------------|-------------|-------|
557
- | `\|x, acc = 0\|` | 1 required | `acc` | Standard case |
558
- | `\|x = 1, acc = 0\|` | 1 optional | `acc` | Element overrides default |
559
- | `\|a, b = 0, acc = 0\|` | 1 required, 1 optional | `acc` | `b` unused |
560
-
561
- ### Invalid Closures
562
-
563
- | Closure | Problem |
564
- |---------|---------|
565
- | `\|x\|` | No accumulator parameter |
566
- | `\|acc = 0\|` | Only 1 param; element overwrites accumulator |
567
- | `\|x, acc\|` | Accumulator has no default |
568
- | `\|a, b, acc = 0\|` | Gap: `b` has no default |
569
-
570
- ---
571
-
572
- ## Error Cases
573
-
574
- | Case | Example | Error |
575
- |------|---------|-------|
576
- | fold without accumulator | `[1,2] -> fold { $ }` | fold requires accumulator |
577
- | fold closure missing default | `[1,2] -> fold \|x, acc\| body` | accumulator requires default |
578
- | break in map | `[1,2] -> map { break }` | break not supported in map |
579
- | break in fold | `[1,2] -> fold(0) { break }` | break not supported in fold |
580
-
581
- ---
582
-
583
- ## Iterating Different Types
584
-
585
- ### Lists
586
-
587
- ```rill
588
- [1, 2, 3] -> each { $ * 2 }
589
- # Result: [2, 4, 6]
590
- ```
591
-
592
- ### Strings
593
-
594
- Iterates over characters.
595
-
596
- ```rill
597
- "abc" -> each { "{$}!" }
598
- # Result: ["a!", "b!", "c!"]
599
- ```
600
-
601
- ### Dicts
602
-
603
- Iterates over entries with `key` and `value` fields.
604
-
605
- ```rill
606
- [a: 1, b: 2] -> each { "{$.key}={$.value}" }
607
- # Result: ["a=1", "b=2"]
608
- ```
609
-
610
- ---
611
-
612
- ## Nested Collections
613
-
614
- Process nested structures with nested operators.
615
-
616
- ```rill
617
- # Double nested values
618
- [[1, 2], [3, 4]] -> map |inner| { $inner -> map { $ * 2 } }
619
- # Result: [[2, 4], [6, 8]]
620
-
621
- # Sum all nested values
622
- [[1, 2], [3, 4]] -> fold(0) |inner, total = 0| { $total + ($inner -> fold(0) { $@ + $ }) }
623
- # Result: 10
624
- ```
625
-
626
- ---
627
-
628
- ## Performance Considerations
629
-
630
- ### Sequential vs Parallel
631
-
632
- | Scenario | Recommendation |
633
- |----------|----------------|
634
- | CPU-bound computation | `each` or `map` (similar performance) |
635
- | I/O-bound operations | `map` (concurrent benefits) |
636
- | Order-dependent logic | `each` (guaranteed order) |
637
- | Stateful accumulation | `each` or `fold` (no parallel option) |
638
-
639
- ### Memory
640
-
641
- - `each` and `map` allocate result lists proportional to input size
642
- - `fold` maintains constant memory (accumulator only)
643
-
644
- ---
645
-
646
- ## Quick Reference
647
-
648
- ```rill
649
- # each - sequential, all results
650
- [1, 2, 3] -> each { $ * 2 } # [2, 4, 6]
651
- [1, 2, 3] -> each(0) { $@ + $ } # [1, 3, 6] (running sum)
652
-
653
- # map - parallel, all results
654
- [1, 2, 3] -> map { $ * 2 } # [2, 4, 6]
655
- ["a", "b"] -> map |x| { "{$x}!" } # ["a!", "b!"]
656
-
657
- # filter - parallel, matching elements
658
- [1, 2, 3, 4, 5] -> filter { $ > 2 } # [3, 4, 5]
659
- |x| { $x % 2 == 0 } :> $isEven
660
- [1, 2, 3, 4, 5] -> filter $isEven # [2, 4]
661
-
662
- # fold - sequential, final result only
663
- [1, 2, 3] -> fold(0) { $@ + $ } # 6
664
- [1, 2, 3] -> fold |x, s = 0| ($s + $x) # 6
665
-
666
- # Dict iteration
667
- [a: 1, b: 2] -> each { $.key } # ["a", "b"]
668
- [a: 1, b: 2] -> each { $.value } # [1, 2]
669
-
670
- # Break (each only)
671
- [1, 2, 3] -> each { ($ > 2) ? break ! $ } # [1, 2] (partial results)
672
-
673
- # Empty collections
674
- [] -> each { $ } # []
675
- [] -> map { $ } # []
676
- [] -> filter { $ } # []
677
- [] -> fold(42) { $ } # 42
678
- ```
679
-
680
- ---
681
-
682
- ## See Also
683
-
684
- - [Iterators](08_iterators.md) — Lazy sequences with `range`, `repeat`, `.first()`
685
- - [Reference](11_reference.md) — Complete language specification
686
- - [Closures](06_closures.md) — Closure semantics and patterns
687
- - [Guide](01_guide.md) — Beginner introduction
688
- - [Examples](12_examples.md) — Workflow examples