@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,695 +0,0 @@
1
- # rill Conventions and Idioms
2
-
3
- *Idiomatic patterns for readable, maintainable rill code*
4
-
5
- This document collects conventions and best practices. It is a living document that will grow as the language matures.
6
-
7
- ---
8
-
9
- ## Naming
10
-
11
- ### Case Style: snake_case
12
-
13
- Use **snake_case** for all identifiers in rill:
14
-
15
- ```rill
16
- # variables
17
- "hello" :> $user_name
18
- [1, 2, 3] :> $item_list
19
- true :> $is_valid
20
-
21
- # closures
22
- |x|($x * 2) :> $double_value
23
- |s|($s -> .trim) :> $cleanup_text
24
-
25
- # dict keys
26
- [first_name: "Alice", last_name: "Smith", is_active: true] :> $user
27
- ```
28
-
29
- ### Variables
30
-
31
- Use descriptive snake_case names with `$` prefix:
32
-
33
- ```rill
34
- "hello" :> $greeting # good: descriptive
35
- "hello" :> $g # avoid: too terse
36
- ```
37
-
38
- For loop variables, short names are acceptable when scope is small:
39
-
40
- ```rill
41
- [1, 2, 3] -> each |x| ($x * 2) # fine: small scope
42
- ```
43
-
44
- ### Closures
45
-
46
- Name closures for their action:
47
-
48
- ```rill
49
- |x|($x * 2) :> $double # verb describing transformation
50
- |s|($s -> .trim) :> $cleanup # verb describing action
51
- ||{ $.count * $.price } :> $total # noun for computed value
52
- ```
53
-
54
- ---
55
-
56
- ## Capture and Flow
57
-
58
- ### Prefer inline capture when continuing the chain
59
-
60
- Capture mid-chain with `:>` to store and continue:
61
-
62
- ```text
63
- # good: capture and continue
64
- prompt("Read file") :> $raw -> log -> .contains("ERROR") ? {
65
- error("Failed: {$raw}")
66
- }
67
-
68
- # less clear: separate statements
69
- prompt("Read file") :> $raw
70
- $raw -> log
71
- $raw -> .contains("ERROR") ? { error("Failed: {$raw}") }
72
- ```
73
-
74
- ### Use explicit capture before branching
75
-
76
- Capture values before conditionals when you need them in multiple branches:
77
-
78
- ```text
79
- # good: $result available in both branches
80
- checkStatus() :> $result
81
- $result -> .contains("OK") ? {
82
- "Success: {$result}"
83
- } ! {
84
- "Failed: {$result}"
85
- }
86
- ```
87
-
88
- ---
89
-
90
- ## Collection Operators
91
-
92
- ### Choose the right operator
93
-
94
- | Use case | Operator | Why |
95
- |----------|----------|-----|
96
- | Transform each element | `map` | Parallel, all results |
97
- | Transform with side effects | `each` | Sequential order |
98
- | Keep matching elements | `filter` | Parallel filter |
99
- | Reduce to single value | `fold` | Final result only |
100
- | Running totals | `each(init)` | All intermediate results |
101
- | Find first match | `each` + `break` | Early termination |
102
-
103
- ### Prefer method shorthand in collection operators
104
-
105
- ```rill
106
- # good: concise
107
- ["hello", "world"] -> map .upper
108
-
109
- # equivalent but verbose
110
- ["hello", "world"] -> map { $.upper() }
111
- ["hello", "world"] -> map |x| $x.upper()
112
- ```
113
-
114
- Method chains work too:
115
-
116
- ```rill
117
- [" HELLO ", " WORLD "] -> map .trim.lower
118
- ```
119
-
120
- ### Use grouped form for negation
121
-
122
- ```rill
123
- # correct: grouped negation
124
- ["", "a", "b"] -> filter (!.empty)
125
-
126
- # wrong: .empty returns truthy elements
127
- ["", "a", "b"] -> filter .empty # returns [""]
128
- ```
129
-
130
- ### Use fold for reduction, each(init) for running totals
131
-
132
- ```rill
133
- # sum: use fold (returns final value)
134
- [1, 2, 3] -> fold(0) { $@ + $ } # 6
135
-
136
- # running sum: use each (returns all intermediates)
137
- [1, 2, 3] -> each(0) { $@ + $ } # [1, 3, 6]
138
- ```
139
-
140
- ### Break returns partial results in each
141
-
142
- ```rill
143
- [1, 2, 3, 4, 5] -> each {
144
- ($ == 3) ? break
145
- $ * 2
146
- }
147
- # Result: [2, 4] (elements processed BEFORE break)
148
- ```
149
-
150
- ---
151
-
152
- ## Loops
153
-
154
- ### Use $ as accumulator in while/do-while
155
-
156
- ```rill
157
- # good: $ accumulates naturally
158
- 0 -> ($ < 5) @ { $ + 1 }
159
-
160
- # avoid: named variables don't persist across iterations
161
- 0 -> ($ < 5) @ {
162
- $ :> $x # $x exists only in this iteration
163
- $x + 1
164
- }
165
- ```
166
-
167
- ### Prefer do-while for retry patterns
168
-
169
- Do-while runs body at least once, eliminating duplicate first-attempt code:
170
-
171
- ```text
172
- # good: body runs at least once
173
- @ {
174
- attemptOperation()
175
- } ? (.contains("RETRY"))
176
-
177
- # less clean: separate first attempt
178
- attemptOperation() :> $result
179
- $result -> .contains("RETRY") @ {
180
- attemptOperation()
181
- }
182
- ```
183
-
184
- ### Use each for collection iteration, not while
185
-
186
- ```text
187
- # good: each is designed for collections
188
- $items -> each { process($) }
189
-
190
- # avoid: manual iteration with while
191
- $items -> .first() -> (!$.done) @ {
192
- process($.value)
193
- $.next()
194
- }
195
- ```
196
-
197
- ---
198
-
199
- ## Conditionals
200
-
201
- ### Condition must be boolean
202
-
203
- The condition in `cond ? then ! else` must evaluate to boolean:
204
-
205
- ```rill
206
- # correct: .contains() returns boolean
207
- "hello" -> .contains("ell") ? "found" ! "not found"
208
-
209
- # correct: comparison returns boolean
210
- 5 -> ($ > 3) ? "big" ! "small"
211
- ```
212
-
213
- ### Use ?? for defaults, not conditionals
214
-
215
- ```text
216
- # good: concise default
217
- $dict.field ?? "default"
218
-
219
- # avoid: verbose conditional
220
- $dict.?field ? $dict.field ! "default"
221
- ```
222
-
223
- ### Chain conditionals for multi-way branching
224
-
225
- ```text
226
- ($status == "ok") ? {
227
- "Success"
228
- } ! ($status == "pending") ? {
229
- "Waiting"
230
- } ! {
231
- "Unknown: {$status}"
232
- }
233
- ```
234
-
235
- ---
236
-
237
- ## Closures
238
-
239
- ### Use braces for complex bodies
240
-
241
- ```rill
242
- # simple: parentheses ok
243
- |x|($x * 2) :> $double
244
-
245
- # complex: braces required
246
- |n| {
247
- ($n < 1) ? 1 ! ($n * $factorial($n - 1))
248
- } :> $factorial
249
- ```
250
-
251
- ### Capture loop variable explicitly for deferred closures
252
-
253
- ```rill
254
- # good: explicit capture per iteration
255
- [1, 2, 3] -> each {
256
- $ :> $item
257
- || { $item }
258
- } :> $closures
259
-
260
- # result: closures return [1, 2, 3] when called
261
- ```
262
-
263
- ### Dict closures for computed properties
264
-
265
- Zero-arg closures auto-invoke when accessed:
266
-
267
- ```rill
268
- [
269
- items: [1, 2, 3],
270
- count: ||{ $.items -> .len }
271
- ] :> $data
272
-
273
- $data.count # 3 (auto-invokes)
274
- ```
275
-
276
- Parameterized closures work as methods:
277
-
278
- ```rill
279
- [
280
- name: "test",
281
- greet: |x|{ "{$.name}: {$x}" }
282
- ] :> $obj
283
-
284
- $obj.greet("hello") # "test: hello"
285
- ```
286
-
287
- ---
288
-
289
- ## Type Safety
290
-
291
- ### Annotate closure parameters for clarity
292
-
293
- ```rill
294
- |name: string, count: number| {
295
- "{$name}: {$count}"
296
- } :> $format
297
- ```
298
-
299
- ### Capture with type annotation for documentation
300
-
301
- ```rill
302
- "processing" :> $status:string
303
- ```
304
-
305
- ### Use type assertions sparingly
306
-
307
- Type assertions (`:type`) are for validation, not conversion:
308
-
309
- ```text
310
- # good: validate external input
311
- parseJson($input):dict :> $data
312
-
313
- # unnecessary: type is already known
314
- 5:number :> $n
315
- ```
316
-
317
- ---
318
-
319
- ## String Handling
320
-
321
- ### Use triple-quotes for multiline content
322
-
323
- ```text
324
- """
325
- Analyze this content:
326
- {$content}
327
-
328
- Provide a summary.
329
- """
330
- ```
331
-
332
- ### Use .empty for emptiness checks
333
-
334
- ```rill
335
- # good
336
- "" -> .empty ? "empty" ! "not empty"
337
- ```
338
-
339
- Avoid direct string comparison (not allowed):
340
-
341
- ```text
342
- # this pattern doesn't work in rill
343
- $str == "" ? "empty"
344
- ```
345
-
346
- ### Chain string methods naturally
347
-
348
- ```rill
349
- " HELLO world " -> .trim.lower.split(" ")
350
- ```
351
-
352
- ---
353
-
354
- ## Error Handling
355
-
356
- ### Validate early with conditionals
357
-
358
- ```text
359
- $input -> .empty ? { error("Input required") }
360
-
361
- # continue with validated input
362
- process($input)
363
- ```
364
-
365
- ### Use explicit signals for workflow control
366
-
367
- ```text
368
- prompt("...") :> $result
369
-
370
- $result -> .contains(":::ERROR:::") ? {
371
- error("Operation failed: {$result}")
372
- }
373
-
374
- $result -> .contains(":::DONE:::") ? {
375
- "Complete" -> return
376
- }
377
- ```
378
-
379
- ---
380
-
381
- ## Parsing LLM Output
382
-
383
- ### Chain parsers for structured extraction
384
-
385
- ```text
386
- # extract JSON from code fence
387
- $response -> parseFence("json") -> parseJson :> $data
388
- ```
389
-
390
- ### Use parseAuto for unknown formats
391
-
392
- ```text
393
- $response -> parseAuto :> $parsed
394
- ($parsed.type == "json") ? {
395
- $parsed.data
396
- } ! {
397
- error("Expected JSON, got {$parsed.type}")
398
- }
399
- ```
400
-
401
- ### Extract XML tags for Claude-style responses
402
-
403
- ```text
404
- $response -> parseXml("thinking") -> log
405
- $response -> parseXml("answer") :> $answer
406
- ```
407
-
408
- ---
409
-
410
- ## Anti-Patterns
411
-
412
- ### Avoid reassigning variables
413
-
414
- Variables lock to their first type. Reassigning suggests misuse:
415
-
416
- ```text
417
- # avoid: confusing reassignment
418
- "initial" :> $x
419
- "updated" :> $x # works but unclear
420
-
421
- # prefer: new variable or functional style
422
- "initial" -> transform() :> $result
423
- ```
424
-
425
- ### Avoid bare $ in stored closures
426
-
427
- ```rill
428
- # confusing: what is $?
429
- || { $ + 1 } :> $fn # $ is undefined when called
430
-
431
- # clear: explicit parameter
432
- |x| { $x + 1 } :> $fn
433
- ```
434
-
435
- ### Avoid break in parallel operators
436
-
437
- Break is not supported in `map` or `filter` (they run in parallel):
438
-
439
- ```text
440
- # wrong: break in map
441
- [1, 2, 3] -> map { ($ > 2) ? break }
442
-
443
- # correct: use each if you need break
444
- [1, 2, 3] -> each { ($ > 2) ? break }
445
-
446
- # or filter first
447
- [1, 2, 3] -> filter { $ <= 2 } -> map { $ }
448
- ```
449
-
450
- ### Avoid complex logic in conditions
451
-
452
- ```text
453
- # hard to read
454
- (($x > 5) && (($y < 10) || ($z == 0))) ? { ... }
455
-
456
- # clearer: extract to named check
457
- ($x > 5) :> $big_enough
458
- (($y < 10) || ($z == 0)) :> $valid_range
459
- ($big_enough && $valid_range) ? { ... }
460
- ```
461
-
462
- ---
463
-
464
- ## Formatting
465
-
466
- ### Spacing Rules
467
-
468
- **Operators**: space on both sides
469
-
470
- ```text
471
- # good
472
- 5 + 3
473
- $x -> .upper
474
- "hello" :> $greeting
475
- ($a == $b) ? "yes" ! "no"
476
-
477
- # avoid
478
- 5+3
479
- $x->.upper
480
- "hello":>$greeting
481
- ```
482
-
483
- **Parentheses**: no inner spaces
484
-
485
- ```text
486
- # good
487
- ($x + 1)
488
- ($ > 3) ? "big"
489
- [1, 2, 3] -> each |x| ($x * 2)
490
-
491
- # avoid
492
- ( $x + 1 )
493
- ( $ > 3 ) ? "big"
494
- ```
495
-
496
- **Braces**: space after `{` and before `}`
497
-
498
- ```text
499
- # good
500
- { $x + 1 }
501
- [1, 2, 3] -> each { $ * 2 }
502
- |x| { $x -> .trim }
503
-
504
- # avoid
505
- {$x + 1}
506
- [1, 2, 3] -> each {$ * 2}
507
- ```
508
-
509
- **Multiline braces**: opening brace on same line, closing on own line
510
-
511
- ```text
512
- # good
513
- [1, 2, 3] -> each {
514
- $ :> $item
515
- $item * 2
516
- }
517
-
518
- # avoid
519
- [1, 2, 3] -> each
520
- {
521
- $ * 2
522
- }
523
- ```
524
-
525
- **Brackets**: no inner spaces for indexing
526
-
527
- ```text
528
- # good
529
- $list[0]
530
- $dict.items[1]
531
-
532
- # avoid
533
- $list[ 0 ]
534
- ```
535
-
536
- **List/dict literals**: space after colons and commas
537
-
538
- ```text
539
- # good
540
- [1, 2, 3]
541
- [name: "alice", age: 30]
542
-
543
- # avoid
544
- [1,2,3]
545
- [name:"alice",age:30]
546
- ```
547
-
548
- **Closure parameters**: no space before pipe, space after
549
-
550
- ```text
551
- # good
552
- |x| ($x * 2)
553
- |a, b| { $a + $b }
554
- || { $.count }
555
-
556
- # avoid
557
- | x | ($x * 2)
558
- |a,b|{ $a + $b }
559
- ```
560
-
561
- **Method calls**: no space before dot or parentheses
562
-
563
- ```text
564
- # good
565
- $str.upper()
566
- $list.join(", ")
567
- "hello" -> .trim.lower
568
-
569
- # avoid
570
- $str .upper()
571
- $list.join (", ")
572
- ```
573
-
574
- **Pipes**: space on both sides of `->` and `:>`
575
-
576
- ```text
577
- # good
578
- "hello" -> .upper -> .len
579
- "value" :> $x -> log
580
-
581
- # avoid
582
- "hello"->.upper->.len
583
- "value":>$x->log
584
- ```
585
-
586
- **Implicit `$` shorthand**: prefer sugared forms
587
-
588
- ```text
589
- # methods: $.foo() -> .foo
590
- # good
591
- "hello" -> .upper -> .len
592
- [1, 2, 3] -> map .str
593
-
594
- # avoid
595
- "hello" -> $.upper() -> $.len
596
- [1, 2, 3] -> map $.str
597
-
598
- # global functions: foo($) -> foo
599
- # good
600
- "hello" -> log -> .upper
601
- 42 -> type
602
-
603
- # avoid
604
- "hello" -> log($) -> .upper
605
- 42 -> type($)
606
-
607
- # closures: $fn($) -> $fn
608
- # good
609
- |x| ($x * 2) :> $double
610
- 5 -> $double
611
-
612
- # avoid
613
- 5 -> $double($)
614
- ```
615
-
616
- **No throwaway captures**: don't capture just to continue
617
-
618
- ```text
619
- # avoid: unnecessary intermediate variables
620
- "hello" :> $x
621
- $x -> .upper :> $y
622
- $y -> .len
623
-
624
- # good: use line continuation instead
625
- "hello"
626
- -> .upper
627
- -> .len
628
-
629
- # good: capture only when reused later
630
- "hello" :> $input
631
- $input -> .upper :> $upper
632
- "{$input} became {$upper}" # both variables referenced
633
- ```
634
-
635
- **Chain continuations**: indent continued lines by 2 spaces
636
-
637
- ```text
638
- # good: align continuation with pipe
639
- $data
640
- -> .filter { $.active }
641
- -> map { $.name }
642
- -> .join(", ")
643
-
644
- # good: long method chains
645
- " hello world "
646
- -> .trim
647
- -> .upper
648
- -> .split(" ")
649
- -> .join("-")
650
-
651
- # good: capture mid-chain
652
- prompt("analyze {$file}")
653
- :> $result
654
- -> log
655
- -> .contains("ERROR") ? { error($result) }
656
-
657
- # avoid: no indent on continuation
658
- $data
659
- -> .filter { $.active }
660
- -> map { $.name }
661
- ```
662
-
663
- ### One statement per line for complex code
664
-
665
- ```text
666
- # good: clear structure
667
- $input -> validate() :> $valid
668
- $valid -> process() :> $result
669
- $result -> format()
670
-
671
- # acceptable for simple chains
672
- $input -> .trim -> .lower -> .split(" ")
673
- ```
674
-
675
- ### Indent block contents
676
-
677
- ```rill
678
- {
679
- "first" :> $a
680
- "second" :> $b
681
- "{$a} {$b}"
682
- }
683
- ```
684
-
685
- ### Align related captures
686
-
687
- ```text
688
- prompt("Get name") :> $name
689
- prompt("Get age") :> $age
690
- prompt("Get role") :> $role
691
- ```
692
-
693
- ---
694
-
695
- *This document will be extended as conventions emerge from real-world usage.*