Saltar al contenido

Pipelines y Máquinas de Estado

En esta página

Cuando cada etapa de un procesamiento es un generador que consume otro generador, obtienes un pipeline pull-based: nada se materializa en memoria hasta que el consumidor final solicita un valor. Compón tantas etapas como quieras — el costo es constante por ítem.

Pipeline de tres etapas (source → keep_evens → square) y extracción manual de N ítems de una secuencia infinita.

06-coroutine-pipelines.zolo
Playground
// Feature: pipelines with coroutines/generators

// Syntax: chain `fn*` consuming each other.

// When to use: stage-based processing (parsing, transformation,

// aggregation) without huge intermediate buffers.

//

// Each stage is a generator: pull-based, lazy, composable.


// Stage 1: produces integers 1..N.

fn* source(n: int) {
  var i = 1
  while i <= n {
    yield i
    i += 1
  }
}

// Stage 2: keeps even numbers (receives a generator handle).

fn* keep_evens(input: any) {
  var v = input()
  while v is not nil {
    if v % 2 == 0 {
      yield v
    }
    v = input()
  }
}

// Stage 3: maps to the square.

fn* square(input: any) {
  var v = input()
  while v is not nil {
    yield v * v
    v = input()
  }
}

// Composed pipeline.

let pipe = square(keep_evens(source(8)))
var x = pipe()
while x is not nil {
  print("out: {x}")
  x = pipe()
}

// expected: out: 4, out: 16, out: 36, out: 64


// Manual pull of N items.

fn take(input: any, n: int) -> [int] {
  let result: [int] = []
  var i = 0
  while i < n {
    let v = input()
    if v is nil { break }
    result.push(v)
    i += 1
  }
  return result
}

fn* naturals() {
  var i = 1
  loop {
    yield i
    i += 1
  }
}

let first10 = take(naturals(), 10)
print("first 10: {first10}")
// expected: first 10: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Las corrutinas también modelan máquinas de estado sin enum + switch: la posición de ejecución entre dos yield es el estado. Esto es natural para parsers por fases, árboles de diálogo, agentes con pasos y NPCs de juegos.

NPC con cuatro estados (idle/patrol/chase/attack), mini-lexer y árbol de diálogo, todos expresados via yield.

07-state-machine.zolo
Playground
// Feature: state machines with coroutines

// Syntax: each `yield` is a transition; state lives between yields.

// When to use: step-by-step parsers, agents with phases, game NPCs,

// flows with state rollback.

//

// The coroutine "remembers" the execution point. No need for enum +

// switch — the code flow itself is the machine.


// NPC with 4 states: idle -> patrol -> chase -> attack -> idle...

// Note: a real loop would use `while true { ... }`; here we unroll

// two cycles to keep the example short and avoid a known codegen

// edge case (multiple `fn*` with looping body in one file).

fn* npc_brain(name: str) {
  yield "{name}: idle"
  yield "{name}: patrol"
  yield "{name}: chase"
  yield "{name}: attack"
  yield "{name}: idle"
  yield "{name}: patrol"
}

let bot = npc_brain("orc-1")
for _ in 0..6 {
  print(bot())
}

// SKIP: state-based parser with nested while + yield inside if/else

// branches currently triggers a Lua codegen ambiguity in the runtime.

// The pattern is valid Zolo, but the lowered code becomes ambiguous.

// A simpler example below shows the same idea (state via `yield`)

// without the nested loops.

//

// Tiny lexer-like state machine: emits a token per call.

fn* tokens_demo() {
  yield "ID(abc)"
  yield "NUM(123)"
  yield "ID(def)"
  yield "NUM(45)"
}

let tokens = tokens_demo()
var t = tokens()
while t != nil {
  print(t)
  t = tokens()
}

// Dialogue with phases: each `yield` waits for the player to press "next".

fn* dialogue() {
  yield "Hello, traveler."
  yield "You look tired."
  yield "Want a potion?"
  yield "Good luck on the journey!"
}

let d = dialogue()
var line = d()
while line != nil {
  print("[npc] {line}")
  line = d()
}

¿Cuándo usar este patrón vs. machine X { ... }? Prefiere corrutinas cuando el estado es un flujo (parser, diálogo lineal). Usa la palabra clave machine cuando el estado es un grafo con transiciones explícitas (protocolos, dispositivos).

Consulta también

Buscar en Zolo

9 resultados

enespt-br