@rcrsr/rill 0.4.1 → 0.4.3

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.
@@ -1,7 +1,30 @@
1
- RILL LANGUAGE REFERENCE FOR LLM AGENTS
2
- =======================================
3
-
4
- Rill is a pipe-based scripting language. Data flows through pipes (->), not assignment (=).
1
+ RILL LANGUAGE REFERENCE
2
+ =======================
3
+
4
+ Rill is designed to be generated by LLMs and understood by humans. The focus is on auditable LLM output, not ergonomic human authoring. It combines the flexibility of imperative languages with the strictness of declaritive specifications.
5
+
6
+ STRENGTHS AND USE CASES
7
+ -----------------------
8
+ Strengths:
9
+ - Unambiguous syntax: $ prefix, explicit operators, no implicit coercion
10
+ - Single-pass parseable: LLMs generate correct code without symbol tables
11
+ - Readable by humans: pipe chains show data flow left-to-right
12
+ - Safe defaults: immutable values, type locking, no null/undefined
13
+
14
+ Use cases:
15
+ - Workflow orchestration: chain LLM calls, API requests, transformations
16
+ - State machines: (cond) @ { } loops with $ as state dict handle multi-state logic
17
+ - Data pipelines: each/map/filter/fold process collections declaratively
18
+ - Prompt engineering: parse LLM output with parse_json, parse_xml, parse_fence
19
+
20
+ State machine pattern ($ carries state through iterations):
21
+ [state: "init", data: $input]
22
+ -> ($.state != "done") @ {
23
+ $.state -> [
24
+ init: { [state: "process", data: transform($.data)] },
25
+ process: { [state: "done", data: finalize($.data)] }
26
+ ]
27
+ }
5
28
 
6
29
  NAMING CONVENTION: snake_case
7
30
  -----------------------------
@@ -118,9 +141,11 @@ Strings: "hello {$var}" # interpolation with {}
118
141
  Numbers: 42, 3.14, -7
119
142
  Booleans: true, false
120
143
  Lists: [1, 2, 3]
144
+ [...$list, 4] # spread: inline list elements
121
145
  Dicts: [name: "alice", age: 30] # identifier keys
122
146
  [1: "one", 2: "two"] # number keys (incl. negative: [-1: "neg"])
123
147
  [true: "yes", false: "no"] # boolean keys
148
+ [["a", "b"]: 1] # multi-key: [a: 1, b: 1]
124
149
  Tuples: *[1, 2, 3] # for argument unpacking
125
150
  Closures: |x|($x + 1) # like lambda/arrow functions
126
151
  Type annot: "hi" :> $x:string # lock type on capture
@@ -318,7 +343,11 @@ DICT DISPATCH (single key):
318
343
  Pipe a value to a dict to match keys and return associated values:
319
344
  $val -> [apple: "fruit", carrot: "veg"] # returns "fruit" if $val is "apple"
320
345
  $val -> [apple: "fruit"] ?? "not found" # default if no match
321
- $method -> [["GET", "HEAD"]: "safe", ["POST", "PUT"]: "unsafe"] # multi-key
346
+ $method -> [["GET", "HEAD"]: "safe", ["POST", "PUT"]: "unsafe"] # multi-key dispatch
347
+
348
+ Multi-key dispatch uses the same syntax as multi-key dict literals:
349
+ [["GET", "HEAD"]: "safe"] # dict with keys "GET" and "HEAD" both = "safe"
350
+ "GET" -> [["GET", "HEAD"]: "safe"] # "safe" (matches "GET" key)
322
351
 
323
352
  Type-aware matching (keys matched by value AND type):
324
353
  1 -> [1: "number", "1": "string"] # "number" (number key matches)
@@ -393,11 +422,40 @@ Slice (/<start:stop:step>):
393
422
  [0,1,2,3,4] -> /<::-1> # [4,3,2,1,0] (reverse)
394
423
  "hello" -> /<1:4> # "ell"
395
424
 
425
+ LIST SPREAD IN LITERALS
426
+ -----------------------
427
+
428
+ Inline list elements into a new list using ... (spread operator):
429
+ [1, 2] :> $a
430
+ [...$a, 3] # [1, 2, 3]
431
+ [...$a, ...$b] # concatenate lists
432
+ [...[], 1] # [1] (empty spread contributes nothing)
433
+ [...($nums -> map {$ * 2})] # spread expression result
434
+ [...$nested[0]] # spread from nested access
435
+
436
+ Error: spreading non-list throws RUNTIME_TYPE_ERROR
437
+ "hello" :> $s
438
+ [...$s] # ERROR: Spread requires list, got string
439
+
440
+ MULTI-KEY DICT LITERALS
441
+ -----------------------
442
+
443
+ Map multiple keys to the same value using list syntax:
444
+ [["a", "b"]: 1] # [a: 1, b: 1]
445
+ [[1, "1"]: "x"] # [1: "x", "1": "x"] (mixed types)
446
+ [a: 0, ["b", "c"]: 1] # [a: 0, b: 1, c: 1] (mixed entries)
447
+ [a: 0, ["a", "b"]: 1] # [a: 1, b: 1] (last-write-wins)
448
+
449
+ Error cases:
450
+ [[]: 1] # ERROR: empty key list
451
+ [[[1, 2], "a"]: 1] # ERROR: non-primitive key element
452
+
396
453
  TUPLES FOR ARGUMENT UNPACKING
397
454
  -----------------------------
398
455
 
399
456
  *[1, 2, 3] -> $fn() # positional: $fn(1, 2, 3)
400
457
  *[b: 2, a: 1] -> $fn() # named: $fn(a=1, b=2)
458
+ *[...$list, 3] -> $fn() # spread in tuple: combines elements
401
459
 
402
460
  SPREAD OPERATOR (@)
403
461
  -------------------
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rcrsr/rill",
3
- "version": "0.4.1",
3
+ "version": "0.4.3",
4
4
  "description": "Rill - An embeddable scripting language for orchestrating LLM workflows",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",