Sequences are Keikaku's most powerful feature - lazy iterators that produce values on-demand, support bidirectional communication, and enable memory-efficient stream processing.
Define a sequence with the sequence keyword. Use yield to produce values.
1# Simple counter sequence2sequence count_up(start, end):3 i := start4 cycle while i <= end:5 yield i6 i = i + 178# Iterate with cycle through9cycle through count_up(1, 5) as num:10 declare("Number:", num)1112# Output:13# Number: 114# Number: 215# Number: 316# Number: 417# Number: 5For fine-grained control, use proceed() to advance the generator step by step.
1sequence fibonacci():2 a := 03 b := 14 cycle while true:5 yield a6 temp := a + b7 a = b8 b = temp910# Get first 10 Fibonacci numbers manually11fib := fibonacci()12cycle from 0 to 10 as _:13 declare(proceed(fib))1415# Output: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34The delegate keyword flattens nested generators, yielding all values from an inner sequence.
1sequence header():2 yield "=== START ==="3 yield "Initializing..."45sequence body():6 yield "Processing item 1"7 yield "Processing item 2"8 yield "Processing item 3"910sequence footer():11 yield "Cleanup complete"12 yield "=== END ==="1314# Main sequence delegates to sub-sequences15sequence full_report():16 delegate header()17 delegate body()18 delegate footer()1920cycle through full_report() as line:21 declare(line)2223# Output:24# === START ===25# Initializing...26# Processing item 127# Processing item 228# Processing item 329# Cleanup complete30# === END ===1# Tree traversal with delegation2sequence flatten(items):3 cycle through items as item:4 foresee classify(item) == "list":5 delegate flatten(item) # Recurse into nested list6 otherwise:7 yield item89nested := [1, [2, 3, [4, 5]], 6, [7]]10cycle through flatten(nested) as val:11 declare(val)1213# Output: 1, 2, 3, 4, 5, 6, 7Keikaku sequences support sending values INTO a running generator using transmit() and receive().
1sequence echo():2 cycle while true:3 received := receive()4 foresee received:5 yield "Echo: " + text(received)6 otherwise:7 yield "Waiting..."89gen := echo()10declare(proceed(gen)) # Waiting...11declare(transmit(gen, "hello")) # Echo: "hello"12declare(transmit(gen, 42)) # Echo: 4213declare(transmit(gen, "world")) # Echo: "world"1sequence accumulator():2 total := 03 cycle while true:4 received := receive()5 foresee received:6 total = total + received7 yield total89acc := accumulator()10proceed(acc) # Initialize (yields 0)11declare(transmit(acc, 10)) # 1012declare(transmit(acc, 5)) # 1513declare(transmit(acc, 25)) # 4014declare(transmit(acc, 100)) # 1401sequence running_avg():2 total := 0.03 count := 04 cycle while true:5 received := receive()6 foresee received:7 total = total + received8 count = count + 19 foresee count > 0:10 yield total / count11 otherwise:12 yield 0.01314avg := running_avg()15proceed(avg)16declare(transmit(avg, 10)) # 10.017declare(transmit(avg, 20)) # 15.0 (30/2)18declare(transmit(avg, 30)) # 20.0 (60/3)For simple transformations, use inline generator expressions - they're concise and lazy.
1items := [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]23# Lazy squares (computed on-demand)4squares := (x * x for x through items)56# Filtered values7evens := (x for x through items where x % 2 == 0)89# Combined: squares of even numbers10even_squares := (x * x for x through items where x % 2 == 0)1112cycle through even_squares as val:13 declare(val)14# Output: 4, 16, 36, 64, 100The disrupt() function throws an exception INTO a generator, which can be caught with attempt/recover.
1sequence worker():2 cycle while true:3 attempt:4 yield "Working..."5 recover as err:6 declare("Worker caught:", err)7 yield "Recovered"89gen := worker()10declare(proceed(gen)) # Working...11declare(disrupt(gen, "Stop")) # Worker caught: Stop12 # Recovered13declare(proceed(gen)) # Working...1sequence fetch_pages(total_pages):2 page := 13 cycle while page <= total_pages:4 # Simulate fetching page data5 sleep(100)6 yield "Page " + text(page) + " data"7 page = page + 189# Process pages lazily - only fetch when needed10cycle through fetch_pages(5) as data:11 declare("Processing:", data)12 # Can stop early if needed13 foresee contains(data, "3"):14 declare("Found target, stopping")15 terminate1sequence traffic_light():2 states := ["GREEN", "YELLOW", "RED"]3 index := 04 cycle while true:5 yield states[index]6 index = (index + 1) % 378light := traffic_light()9cycle from 0 to 7 as _:10 declare("Light is:", proceed(light))1112# Output cycles: GREEN, YELLOW, RED, GREEN, YELLOW, RED, GREEN