Recetario ejecutable
Aprende Zolo con ejemplos
Lee programas completos con sus explicaciones. Empieza por valores y funciones, después explora datos, errores, efectos e integraciones.
Este catálogo muestra solo las recetas con contenido completo en el idioma seleccionado.
Empieza por un resultado
Usa una ruta corta cuando quieras un modelo mental funcional sin leer todo el catálogo.
Aprende el núcleo
Bindings, operadores, flujo y funciones.
Empezar por lo esencialModela datos fiables
Structs, accesores, enums y Result.
Empezar por lo esencialConstruye servicios
Rutas HTTP, JSON, bases de datos y workers.
Empezar por lo esencialExplora temas avanzados
Comptime, reflexión, máquinas de estado y efectos.
Empezar por lo esencialLa biblioteca completa de recetas
Abre solo el acto que necesitas. La búsqueda recorre títulos, descripciones, capítulos y sintaxis.
01 Acto 1 Fundamentos
Variables y Bindings
6 recetas
- Bindings: let, let mut y var Crear bindings inmutables con let, mutables con let mut, y el alias var.
- Constantes y Override const para valores fijos en tiempo de compilación; override para constantes reemplazables en tiempo de carga.
- Anotaciones de Tipo y Opcionales Inferencia automática vs anotación explícita; el tipo T? para valores que pueden ser nil.
- Shadowing y Alcance Redeclarar un nombre con let (shadowing) y cómo el alcance léxico define el tiempo de vida de un binding.
- Desestructuración Extraer múltiples valores de arrays, structs y enums en un único patrón.
- Clases de Almacenamiento y Descarte var<lazy>, var<persistent>, var<atomic>: control de inicialización y ciclo de vida; y _ para descartar valores.
Operadores
6 recetas
- Aritmética Operadores aritméticos: +, -, *, /, %, **, unario -, división entera ~/ y asignación compuesta.
- Comparación y Lógica Operadores relacionales (==, !=, <, <=, >, >=) y lógicos (&&, ||, !) con evaluación en cortocircuito.
- Comparaciones encadenadas Escribe mínimo <= valor < máximo en una cadena. Cada operando compartido se evalúa una vez y una comparación falsa detiene la cadena. Las comprobaciones de intervalo no repiten una expresión potencialmente costosa.
- Rangos y Spread Operadores de rango (.. exclusivo, ..= inclusivo), slicing de arrays y spread ... en literales.
- Pipeline Operadores de pipeline |> (encadenamiento data-first) y &. (efecto secundario sin romper el flujo).
- Seguridad con Nil Operadores ?. (navegación segura), ?? (coalescencia de nil) y ? (propagación de nil).
Control de Flujo
6 recetas
- if / else Condicionales como sentencia y como expresión, if-let y let-else.
- Condiciones con enlaces Las condiciones separadas por comas se evalúan de izquierda a derecha con cortocircuito. Los enlaces exitosos están disponibles en las condiciones siguientes y en el cuerpo. Un guard con enlaces debe salir por todas las rutas de fallo.
- Bucles while, while-let, bucles con valor, for sobre rangos y colecciones, break/continue etiquetados.
- Iteración filtrada con for case for case patrón in valores omite valores que no coinciden y enlaza solo el cuerpo exitoso. Un for común con patrón refutable conserva su panic ante una incompatibilidad. El iterable se evalúa una vez y continue sigue la regla normal del bucle.
- Match Coincidencia de patrones: literales, or, rangos, guardas, structs, enums y anidamiento.
- defer Programa limpieza para la salida del ámbito, en orden LIFO.
02 Acto 2 Funciones y Lógica
Funciones
15 recetas
- Funciones con Nombre Declaración con fn, tipos explícitos o inferidos, y funciones auxiliares locales.
- Funciones con cuerpo de expresión Usa = expresión en una función o método pequeño. La expresión proporciona el retorno; return, propagación de Result, genéricos y valores por defecto conservan la semántica de un cuerpo en bloque.
- Lambdas y funciones anónimas Funciones anónimas con |args| expr y capturas de ámbito léxico.
- Lambdas cortas de predicado Los accesos desde underscore usan el mismo parámetro implícito. Combina campos, cálculos y pruebas booleanas; usa una lambda explícita si el alcance resulta ambiguo.
- Lambdas unarias completas Con una firma comprobada de callback de un argumento, underscore representa el parámetro completo, incluso en cálculos y llamadas anidadas comunes. Los callbacks anidados obtienen su propio parámetro. Bloques, lambdas explícitas, colecciones y pipes siguen siendo límites de alcance.
- Bloques finales nombrados Varios callbacks pueden aparecer después de la llamada como bloques etiquetados. Las etiquetas resuelven parámetros de función y permiten otro orden. Crear el callback no ejecuta su cuerpo; las capturas mutables conservan sus celdas.
- Parámetros Flexibles Valores por defecto con p: T = expr y varargs con args: ...T.
- Etiquetas externas de argumentos Separa la etiqueta pública del nombre local del parámetro: from source: int. El llamador usa from: y la función lee source. Las etiquetas forman parte de la interfaz y se conservan en valores de función.
- Argumentos nombrados abreviados Una llamada con name: pasa la variable name del llamador. Puedes mezclar valores explícitos y abreviados y reordenarlos por etiqueta. Una variable ausente es un error; el formateador conserva la abreviatura.
- Argumentos nombrados obligatorios Los parámetros después de * deben pasarse con sus etiquetas externas. Los valores por defecto pueden omitirse. El contrato sigue métodos, declaraciones exportadas y valores de función tipados; pasar la función como callback no elimina el requisito.
- Retornos Múltiples y Recursión Devolver varios valores mediante [T] con desestructuración, y funciones que se llaman a sí mismas.
- Cláusulas de función por patrón Las declaraciones consecutivas de la misma función eligen el cuerpo por patrones de parámetros y guards opcionales, en el orden escrito. Forman una función y deben cubrir los casos; los guards solos no garantizan cobertura. Los contratos y etiquetas públicas deben coincidir.
- Condiciones de entrada y retorno Una actualización de inventario debe comprobar la cantidad solicitada y el saldo restante. Use `requires` para las condiciones de entrada y `ensures` para el valor devuelto, accesible mediante el nombre `result`.
- Funciones de Orden Superior Funciones como argumento o retorno, composición, map/filter/reduce y closures con estado mutable.
- Generadores y Corrutinas fn* y yield para secuencias perezosas; async fn para tareas cooperativas.
Coincidencia de Patrones
9 recetas
- Patrones Básicos: Literales, Comodín y Binding Los tres bloques fundamentales de todo patrón: coincidir por valor exacto, ignorar con `_` o capturar el valor en un nombre.
- Patrones Or, Rangos y Guardas Agrupa alternativas con `|`, clasifica intervalos numéricos con `..=` y refina patrones con condiciones extra `if`.
- Binding con @ El operador `@` captura el valor que satisface un subpatrón, combinando verificación y binding en un solo paso.
- Desestructuración: tuplas, arreglos, structs y enums Extrae campos y elementos de estructuras compuestas directamente en el patrón — en `let`, `match` y `for`.
- Patrones Anidados Combina patrones dentro de patrones para extraer datos de estructuras profundas en una sola rama de match.
- Patrones en Instrucciones: if let, while let, let else y match-expresión Más allá del `match`, los patrones aparecen en `if let`, `while let`, `let else` y como expresiones que devuelven un valor.
- Enlaces de patrones con is Usa is con un patrón de valor para probar y enlazar en una condición. Las capturas son visibles solo en el camino exitoso, incluidas condiciones siguientes. Las pruebas existentes is Tipo e is not Tipo mantienen su significado.
- Capturas tipadas en strings Un literal pat compara la cadena completa y convierte las capturas antes de exponer enlaces. Una conversión escalar o construcción validada fallida significa que no coincide. Usa el primer delimitador sin retroceso; se rechazan capturas adyacentes sin delimitador.
- Patrones de captura como valores Guarda un literal pat como valor reutilizable. Su método parse devuelve Result con un record de capturas de tipos exactos. Entrada incompatible y conversiones fallidas devuelven errores estructurados. La construcción retiene las funciones de conversión sin ejecutar sus predicados.
Manejo de Errores
10 recetas
- Result: éxito o error como valor Crea e inspecciona Result.Ok / Result.Err; usa is_ok, unwrap, unwrap_or y match exhaustivo.
- El operador ? Propaga Result y Option automáticamente con ? — sin boilerplate de match anidado.
- Límites locales de Result attempt ejecuta un bloque y envuelve su resultado normal en Ok. Un ? de Result que falla sale del attempt más cercano como Err. Un Result al final permanece anidado. No captura panics; la propagación de opcionales requiere conversión explícita del error.
- Combinadores de Result Transforma y encadena resultados con map, map_err, and_then y or_else sin desempaquetar.
- Recuperación de Result en expresiones recover evalúa el Result una vez y extrae Ok. Sus patrones corresponden al contenido de Err y deben cubrir ese tipo. Las ramas que continúan devuelven el tipo del éxito. Retornos, propagación y limpieza pertenecen al alcance exterior.
- Opcionales T?, nil, ??, ?. e if let — representa ausencia de valor sin error.
- panic, try/catch y catch_panic Señala invariantes rotos con panic; captúralos con try/catch/finally y catch_panic.
- defer, defer_ok y defer_err Garantiza la limpieza de recursos al salir del ámbito; filtra por camino de salida con defer_ok/defer_err.
- Alcances visibles de recursos using recurso = adquisición { cuerpo } instala la limpieza tras una adquisición exitosa. El tipo debe implementar core::cleanup::Cleanup. La limpieza sigue las salidas léxicas y las transferencias de propiedad la desactivan. Un método llamado close no demuestra el protocolo.
- Guards y retorno anticipado Valida precondiciones al inicio de la función y simplifica el camino feliz con ? en pipelines.
03 Acto 3 Datos y Tipos
Estructuras de Datos
20 recetas
- Arreglos (arrays) Colección ordenada con indexación, slicing, spread y operaciones funcionales.
- Entradas condicionales en arrays Usa if condición => valor y for elemento in elementos => valor dentro de un array. Las entradas se producen en el orden escrito. Las condiciones falsas omiten entradas; nil ocupa una posición. Los arrays anidados siguen siendo valores sin un spread explícito.
- Mapas y Sets Mapas clave/valor con el literal `#{}` y sets para pertenencia sin duplicados.
- Tipos de map explícitos Escribe los tipos de map como #{K: V}. Las llaves con campos nombrados siempre describen un record, incluso campos llamados int o String. Las llaves vacías representan un record vacío. Map<K, V> sigue disponible.
- Comprensiones de maps Construye maps con entradas for e if dentro de #{ }. Las claves calculadas usan [expresión]: valor. Iterables, claves y valores se evalúan una vez en orden; las claves repetidas siguen el reemplazo normal de maps. Los enlaces de bucles y filtros quedan en su entrada.
- Tuplas Agrupación posicional con destructuring — múltiples valores de retorno y pares.
- Records anónimos independientes Sin un tipo nominal esperado, .{ campos } infiere un record anónimo con tipos exactos y acceso normal a campos. Un struct esperado selecciona la construcción nominal contextual. Un tipo esperado inválido genera un diagnóstico y no se sustituye silenciosamente por un tipo estructural.
- Estructuras (structs) Registros con campos con nombre, anidamiento, mutación y métodos con `impl`.
- Construcción contextual Cuando se espera un tipo struct exacto, .{ campos } construye ese struct sin repetir su nombre. Siguen aplicándose los valores por defecto, la privacidad y los campos obligatorios. El compilador nunca adivina una identidad nominal por los nombres de campos.
- Actualizaciones inmutables anidadas La actualización with evalúa la base una vez y copia la raíz y los records modificados del camino. Los hijos intactos siguen compartidos. El resultado conserva su tipo nominal; se rechazan caminos conflictivos y copias de recursos lineales.
- Actualizaciones inmutables calculadas Una actualización with acepta operadores compuestos como value += 1. Lee el campo anterior una vez y calcula el reemplazo sin modificar el original. Siguen aplicándose restricciones de visibilidad, tipos, caminos conflictivos y copias lineales.
- Proyección tipada de records user.{ id, name } evalúa user una vez y crea un record anónimo con los campos físicos visibles seleccionados. Conserva tipos exactos. Se rechazan selecciones repetidas, campos inaccesibles o calculados y copias lineales prohibidas.
- Caminos de campos tipados field User::address.city crea un FieldPath<User, str> sin leer una instancia. get lee el campo; set devuelve una actualización inmutable y comparte hijos intactos. Conserva privacidad y tipos exactos; se rechazan miembros calculados y almacenamiento lineal.
- Enumeraciones (enums) Variantes unitarias, con datos posicionales, con campos con nombre y genéricas.
- Newtypes Wrappers opacos para distinguir tipos con el mismo formato físico en el dominio.
- Newtypes escalares validados Un newtype con where incorpora el predicado a la construcción. Su constructor new devuelve Result; trata el fallo o propágalo. Las operaciones derivadas mantienen la validación. Un newtype sin where conserva su constructor directo.
- Cuándo Usar Cada Tipo Guía de decisión: array vs set vs map vs struct vs enum vs newtype.
- Layout de Memoria `@repr`, `@align` y `@size` para control de layout en FFI y GPU.
- Incrustación de Campos con `using` Promueve los campos de un struct incrustado al acceso por punto del struct externo con `using`.
- Iteradores Personalizados Conecta cualquier tipo a `for x in` implementando Iterator<T> o IntoIterator<T>.
Strings
9 recetas
- Literales y Escapes Comillas dobles, secuencias de escape (\n \t \" \\) y el tipo char.
- Literales de cadena nominales validados Un literal como Email\"ana@empresa.com\" se acepta solo si el predicado del newtype de cadena validado acepta su contenido estático durante la compilación. Las cadenas dinámicas usan el constructor falible. Se conserva la semántica de los templates etiquetados por funciones.
- Concatenación e Interpolación El operador + para unir strings y la sintaxis {expr} para incrustar valores.
- Especificadores de Formato Precisión de floats (:.Nf), zero-padding (:0Nd) y hexadecimal (:#x) en la interpolación.
- Mayúsculas, Minúsculas y Trim .upper, .lower, .trim, .trim_start y .trim_end para normalizar texto.
- Búsqueda y Prueba .contains, .starts_with y .ends_with para verificar substrings sin regex.
- Split y Replace .split(sep) divide en array; .replace(old, new) sustituye todas las ocurrencias.
- Longitud e Iteración de Caracteres .len() retorna bytes; .chars() devuelve un array de strings para iterar carácter a carácter.
- Módulo String String.upper, String.sub, String.reverse — el estilo funcional equivalente a los métodos.
Iteradores y Pipes
6 recetas
- Operador Pipe `|>` encadena llamadas data-first, haciendo las transformaciones legibles de izquierda a derecha.
- Operador Tap `&.` ejecuta un efecto secundario y devuelve el valor original — el "espía" del pipeline.
- Fuentes y Transformaciones de Iter `Iter::range`, `Iter::from`, `map` y `filter` construyen y transforman secuencias de forma lazy.
- Reducción y Paginación `fold` colapsa una secuencia en un valor; `take` y `skip` limitan y paginan iteradores.
- Combinando Iteradores `zip` empareja dos iteradores; `chain` los concatena; `collect` y `each` son los consumidores terminales.
- Generadores y secuencias infinitas `fn*` + `yield` crean secuencias lazy bajo demanda; los ranges infinitos (`0..`) se componen con `take` en pipelines.
04 Acto 4 Abstracción
Programación Orientada a Objetos
6 recetas
- Bloques impl y Métodos de Instancia Cómo agrupar métodos en un tipo con impl, usar self y mutar campos directamente.
- Funciones Asociadas y Múltiples Bloques impl Constructores y utilidades sin self, llamados con Type::nombre(), y cómo dividir métodos en bloques impl separados.
- Rasgos (traits) Define interfaces con trait, impleméntalas en tipos concretos con impl Trait for Type, usa métodos por defecto y combina múltiples traits.
- Genéricos Parametriza funciones, structs y enums con <T> para escribir código que funcione con cualquier tipo.
- Arrays fijos y tamaños genéricos constantes Compruebe el tamaño exacto de un paquete e infiéralo en funciones reutilizables.
- Sobrecarga de Operadores, to_string y Encadenamiento Vincula operadores a métodos por convención de nombre o @op, controla la representación textual con to_string, y crea APIs fluentes con encadenamiento.
05 Acto 5 Metaprogramación
Decoradores
7 recetas
- Caché de Resultados Memoización automática con @memoize y caché con expiración mediante @cached(ttl).
- Rendimiento y Diagnóstico Instrumentación automática con @benchmark, @log y tolerancia a fallos con @retry.
- Estructuras: derivación y validación Generación automática de Eq, Clone y Debug con @derive, y validación de campos con @validate.
- Deriving uniforme Añade un sufijo deriving a structs y enums para solicitar los productores existentes. Usa la misma validación e implementación generada que los decoradores de derive. Los traits no admitidos y campos incompatibles generan diagnóstico, sin crear implementaciones sin verificar.
- Tests y Benchmarks con el Runner Funciones descubiertas automáticamente por el runner: @test para tests unitarios y @bench para medición de rendimiento.
- Rutas HTTP y Calidad de API Rutas declarativas con @get/@post, API obsoleta con @deprecated, retorno obligatorio con @must_use y control de lint con @diagnostic.
- Composición y Decorators Propios Apilamiento de decorators, parámetros @const en tiempo de compilación y mixins definidos por el usuario con super().
Macros
5 recetas
- Definición e Invocación Cómo declarar un macro con `macro name(p) { ... }` y llamarlo con `name!(arg)`.
- stringify! y assert! Inspeccionar el código fuente en tiempo de expansión y crear verificaciones ricas con `stringify!`.
- Higiene, Recursión y Argumentos de Bloque Las variables internas no se filtran al llamador; los macros pueden invocarse a sí mismos; bloques `{}` como argumento.
- DSL de Logging Macros pequeños componen un mini-lenguaje de log con niveles estandarizados.
- macro_rules! Macros al estilo Rust con múltiples brazos, repetición `$(...),*` y tipos de captura.
Evaluación en Tiempo de Compilación
5 recetas
- Bloque comptime comptime { ... } evalúa un bloque en línea en el compilador y reemplaza el resultado por un literal.
- Funciones comptime Declara helpers reutilizables con @comptime fn e invócalos con comptime f(x) — el call-site se convierte en un literal.
- Recursión, bucles y tablas Funciones comptime recursivas, bucles for dentro de bloques comptime y generación de arrays literales en tiempo de compilación.
- stdlib e incrustación de archivos Los métodos de string, math.* y comptime fs.read() funcionan en contexto comptime — normaliza textos e incrusta archivos como literales.
- const_assert Falla la build si un invariante en tiempo de compilación no se cumple — costo cero en producción.
Schemas
5 recetas
- Valores por Defecto Declara campos con `= valor` y obtén una instancia lista con `Schema.default()`.
- Introspección de Campos `Schema.fields()` devuelve los nombres de los campos en orden de declaración, lo que permite renderizado genérico y migraciones.
- Parsear y Serializar `Schema.parse(mapa)` valida la entrada devolviendo un `Result`; `instancia.to_map()` convierte de vuelta a un mapa.
- Restricciones `where` Añade invariantes de dominio a campos con `where |v| <bool>` — verificadas automáticamente durante `parse`.
- Invariantes entre campos de schemas Añade predicados where después de un schema para validar el valor completo. La conversión de campos y los valores por defecto ocurren primero. Los invariantes devuelven bool y se ejecutan en orden; los fallos producen DecodeError estructurado en la ruta del objeto.
06 Acto 6 Estructura del Proyecto
Módulos
14 recetas
- mod y use Registra un módulo con `mod` y trae nombres al ámbito con `use`.
- Visibilidad y pub `pub` exporta un elemento; sin `pub` es privado al módulo.
- Estilos de importación Calificado, por lista o múltiples módulos: cuándo usar cada estilo.
- Plugins nativos y stdlib `use plugin` para plugins nativos; rutas calificadas `std::` no necesitan `use`.
- Módulos inline y visibilidad granular Módulos declarados dentro del archivo, `use ... as`, y modificadores `pub(mod)` / `pub(crate)`.
- Proyecto multi-archivo Cómo funcionan `mod` y `use` en un programa con múltiples archivos.
- C# · .NET Integra funciones C# tipadas, objetos CLR, callbacks y llamadas asíncronas. Prepara con las herramientas .NET y conserva el runtime compatible al distribuir.
- Python · CPython Ejecuta Python en el proceso con imports nativos y conversión tipada. Windows con CPython 3.12 está verificado; necesitas un intérprete compatible y las dependencias nativas de los paquetes.
- JavaScript / TypeScript · Node Usa JavaScript y TypeScript mediante Node integrado, incluidos módulos nativos y Promises. El shim, runtime y ABI de addons deben coincidir. int de Zolo usa bigint en firmas inline.
- Java / Kotlin · JVM Comparte una JVM para Java y Kotlin, con imports nativos, objetos vivos y dependencias Maven. Preparar fuentes y el editor requiere las herramientas correspondientes; las aplicaciones preparadas necesitan un JRE compatible. JVM 8, 11 y 23 están verificadas en Windows x64.
- C / C++ · Clang · C ABI Prepara bibliotecas C17 y C++17 con Clang. C++ expone clases concretas admitidas; la propiedad nativa y los punteros o templates no admitidos requieren adaptadores explícitos. El código preparado se ejecuta sin el compilador de fuentes.
- Rust · rustc · Cargo Compila funciones Rust tipadas y records copiados en una biblioteca específica del destino. Las dependencias Cargo participan del flujo con lock. Los artefactos distribuidos no necesitan rustc ni fuentes; objetos retenidos y genéricos abiertos requieren adaptadores.
- Go · Go · cgo Prepara exports Go con cgo y un compilador C compatible. Funciones tipadas, structs públicos copiados y módulos usan el puente común. Los artefactos preparados no necesitan Go ni la caché de módulos; receivers retenidos y variádicos requieren adaptadores.
- Dependencias externas y locks Declara dependencias una vez en el alcance del archivo. Importa los providers explícitamente; sus alias seleccionan el mismo entorno. Los imports nativos eligen los símbolos usados en cada fragmento.
Documentación
4 recetas
- Comentarios Comentarios de línea (//), bloque (/* */), anidamiento y convenciones TODO/FIXME/NOTE.
- Comentarios de documentación Doc comments /// y /** */ en funciones, structs, enums y traits — aparecen en el hover del editor.
- Doc Tags Etiquetas @param, @returns, @throws, @example, @see, @since y @deprecated en doc comments.
- Código Autodocumentado Nombres descriptivos, tipos explícitos, aliases, constantes nombradas y structs/enums como documentación viva.
Directivas de Módulo
2 recetas
Ganchos de Ciclo de Vida
3 recetas
- Gancho de Cierre Registrar código de limpieza con `on shutdown` — se ejecuta al salir normalmente o vía `process.exit`.
- Múltiples Ganchos Componer `on shutdown`, `on panic` y `on signal` en el mismo programa; orden de disparo y LIFO.
- Pánico y Señales Interceptar errores fatales con `on panic` y señales del SO con `on signal`.
07 Acto 7 Concurrencia y Reactividad
Expresiones Temporales
8 recetas
- Literales de Duración Sufijos de unidad en los números: ns, us, ms, s, min, h, d, w — todos se convierten en i64 en milisegundos.
- Aritmética con Duraciones Suma, resta, multiplicación y división entre duraciones; comparaciones directas.
- Cast de Unidades Extrae componentes de reloj con `as h`, `as min`, `as s`, `as ms` para formatear duraciones.
- Sufijos de unidades declarados Asocia @unit a un newtype escalar para dar un sufijo tipado a los literales. Conserva el tipo nominal y la precisión escalar. Un sufijo solo no define conversión: declara dimensiones y escalas para convertir automáticamente.
- Dimensiones y escalas de unidades Declara unidades base, dimensiones derivadas y escalas exactas con @unit. Multiplicación y división derivan dimensiones; as convierte solo dimensiones compatibles y comprueba representabilidad. Los sufijos de duración mantienen el comportamiento en milisegundos fuera de un contexto dimensional.
- Sleep Pausa la ejecución con `sleep <dur>` o `sleep(<dur>)` — cooperativo, cede el control al scheduler.
- Agendamiento: every, after y timeout Bucle periódico con `every`, disparo único con `after`, y cancelación por plazo con `timeout`.
- Patrones Prácticos Heartbeat, TTL, backoff exponencial, bandas de alerta y calentamiento combinado con bucle periódico.
Concurrencia
11 recetas
- Corrutinas y Generadores El primitivo base de la concurrencia en Zolo: coroutine.create/resume/yield y funciones generadoras fn*.
- Delegación lazy de generadores yield ... hijo delega un valor cada vez y mantiene el cursor del hijo entre reanudaciones. No materializa un array. Cerrar el generador exterior cierra el hijo activo y ejecuta su limpieza; yield común conserva su comportamiento.
- Async / Await y Fetch async fn, await, Promise.all/race/any y la API fetch para peticiones HTTP concurrentes.
- Plazos de await await tarea within duración devuelve un Result tipado de timeout. Al expirar, el scheduler solicita cancelación y espera la limpieza cooperativa. Una tarea que devuelve Result produce un Result anidado; elige qué capa propagar. El trabajo nativo sin checkpoints no puede interrumpirse por la fuerza.
- Lectura de una fuente asíncrona `for await` pide un valor a la vez a la fuente y espera a `next()` antes de ejecutar el cuerpo del bucle.
- Spawn, Temporización y Cancelación spawn lanza tareas cooperativas; every/after programan trabajo en el tiempo; la cancelación usa flags compartidas.
- Pipelines y Máquinas de Estado Generadores encadenados en etapas pull-based y máquinas de estado expresadas como secuencias de yield.
- Canales Paso de mensajes al estilo CSP: channel(N), send/recv, for-in, canales acotados y contrapresión.
- Concurrencia Estructurada, Select y Worker Pool scope espera a todos los hijos; select espera en múltiples canales; el worker pool implementa fan-out + fan-in.
- Resultados paralelos nombrados Las tareas nombradas en parallel producen un record tipado tras la unión estructurada. Cada tarea captura el alcance exterior; las etiquetas no son variables para tareas hermanas. Los fallos cancelan y esperan cooperativamente a las hermanas. Se rechazan resultados transitivamente lineales.
- Límite del trabajo concurrente `parallel(limit: 2) [for id in ids => await load_profile(id)]` procesa un array con un máximo de dos trabajos activos y devuelve los resultados en el orden de entrada.
Signals
5 recetas
- Signal Básico Crear un signal con `signal()`, leer con `.get()` y escribir con `.set()`.
- Efectos El `effect` se ejecuta inmediatamente al crearse y se re-ejecuta cada vez que un signal rastreado cambia.
- Valores Computados El `computed` crea un signal derivado memoizado: recalcula solo cuando una dependencia cambia.
- Lectura Sin Rastreo `signal_untrack`, `peek` y `modify`: lee un signal sin crear dependencia y actualiza de forma funcional.
- Batch, Dispose y Demo Completa Agrupa múltiples escrituras con `signal_batch`, cancela effects con `.dispose()` y ve los tres primitivos compuestos.
Máquinas de Estado
6 recetas
- Declaración y Transiciones Cómo declarar estados, definir el estado inicial y disparar eventos con `.send`.
- Eventos tipados y datos de estado Una máquina tipada posee sus enums State y Event. Los patrones de transición enlazan datos del evento y estado solo en esa transición. Los datos iniciales se evalúan una vez por instancia. send devuelve false si no hay transición; can_send comprueba patrones sin ejecutar guards ni acciones.
- Acciones de Transición Bloques de código que se ejecutan automáticamente cuando ocurre una transición.
- Consulta y Observadores `.can_send` verifica si un evento es aplicable; `.on_transition` registra observadores globales.
- Introspección `.transitions()` expone la tabla completa de transiciones para herramientas, diagramas y tests.
- Máquinas indexadas por estado new_static crea una máquina con propiedad y testigo de estado. send la consume y devuelve el tipo del estado destino; un guard fallido devuelve la máquina y el evento originales. Las funciones pueden exigir Order<.Paid>. erase_state devuelve una máquina dinámica cuando ya no necesitas comprobación estática.
Efectos Algebraicos
8 recetas
- Fundamentos Declara un efecto, dispara operaciones con perform e instala un handler con handle … with.
- Múltiples Efectos with E1 + E2 combina efectos en la firma; handlers anidados y efectos transitivos completan el cuadro.
- resume y abort resume(v) devuelve el control a perform con un valor; abort(v) descarta la continuación y termina el handle.
- Handlers como Valor handler { … } crea un valor de primera clase; compose, override, record y panic_unhandled como capas sobre él.
- Handlers antes del bloque with handler_value { cuerpo } evalúa e instala el handler antes del cuerpo. Tiene la misma semántica que handle cuerpo with handler_value. Los bloques anidados restauran el handler exterior; retornos y limpieza conservan sus límites léxicos. El valor debe ser un Handler comprobado.
- Reemplazos tipados de handlers Un handler con selectores de operaciones sustituye solo esas operaciones y conserva la cobertura de efectos y el tipo de respuesta restantes. Las firmas y cuerpos se comprueban contra el efecto real. La composición conserva el frame y la semántica léxica de abort.
- Patrones Funcionales Reader, State y Writer implementados como efectos; caso real con Db + Fs + Log + Metric y mocks en @test.
- Tipos Avanzados multi fn, efectos genéricos State<T>, polimorfismo de fila, aliases de efecto y combinadores de std::effect.
08 Acto 8 Biblioteca Estándar
Biblioteca Estándar
26 recetas
- Matemáticas (std::math) Funciones matemáticas, constantes, aritmética decimal exacta y comparación aproximada entre floats.
- Cadenas (std::string) Limpieza, división, sustitución, búsqueda, conversión de mayúsculas/minúsculas, iteración por carácter y formateo.
- Arreglos (std::array) Mutación, transformación, filtrado, agregación, búsqueda y aplanado de arrays.
- Vectores (std::vec) Vectores 2D/3D/4D: constructores, aritmética, producto escalar y vectorial, longitud, normalización y swizzle rgba.
- Mapas (std::map) Creación, inserción, lectura, eliminación, iteración y la diferencia entre literales #{} y Map::new().
- Conjuntos (std::set) Unicidad, pertenencia, eliminación, operaciones de conjunto (unión e intersección) y conversión con arrays.
- Iteradores (std::Iter) Secuencias perezosas: range, map, filter, fold, take, skip, zip, collect y each.
- Resultado (std::Result) Manejo de errores sin excepciones: Ok, Err, unwrap, map, and_then y el operador ?.
- JSON (std::json) Serializar y deserializar JSON: encode, decode, manejo de errores, literal json"...", path e interop con schemas.
- YAML (std::yaml) Parsear y serializar YAML: configuraciones jerárquicas, listas y round-trip.
- TOML (std::toml) Parsear y serializar TOML: secciones, tipos explícitos y round-trip.
- CSV (std::csv) Parsear y serializar CSV: filas, cabeceras, escape de comillas y round-trip.
- Expresiones Regulares (std::regex) Validar, extraer, sustituir y dividir cadenas con expresiones regulares.
- Fecha y Hora (std::datetime) Obtén el instante actual, formatea y analiza fechas, y realiza aritmética de calendario con std::datetime.
- Rutas (std::path) Manipula rutas de forma portable: une componentes, extrae partes, normaliza y resuelve rutas relativas.
- Sistema de Archivos (std::fs) Lee, escribe, elimina archivos, lista directorios y trabaja con archivos temporales usando std::fs.
- Variables de Entorno (std::env) Lee, define y elimina variables de entorno; obtén información del sistema con std::env.
- Proceso (std::process) Accede a argumentos, directorio de trabajo, ejecuta comandos externos e inspecciona el proceso actual con std::process.
- Reactor de I/O (std::io_runtime) Timers basados en el reactor de I/O: sleep de una vez, timers periódicos con cancelación.
- Cliente HTTP (std::http) Realiza peticiones GET, POST y otras vía std::http.client — cabeceras personalizadas, cuerpo JSON y manejo de errores.
- URLs (std::url) Parsing, codificación porcentual y construcción de query strings con std::url.
- Criptografía (std::crypto) Generación de IDs únicos y aleatoriedad criptográficamente segura con std::crypto.
- Hashes (std::hash) SHA-256, SHA-512, MD5, CRC32 y HMAC para integridad de contenido y autenticación de mensajes con std::hash.
- Base64, Hex y Base32 (std::base64) Codificación y decodificación Base64 estándar, URL-safe, Hex y Base32 para representar datos binarios como texto.
- Registros (std::log) Logging estructurado por nivel de severidad, control de verbosidad y formato personalizado con std::log.
- Estadísticas (std::stats) Tendencia central, dispersión, percentiles, correlación y regresión lineal con std::stats.
09 Acto 9 Plataforma y Aplicaciones
Servidor HTTP
7 recetas
- Cliente HTTP — GET Realizando solicitudes GET con cabeceras opcionales y leyendo el objeto de respuesta.
- Cliente HTTP — POST JSON y fetch Enviando datos con http.post y usando http.fetch para métodos arbitrarios y timeout.
- Servidor — Enrutador y Decoradores Creando un servidor HTTP con http.router() mediante pipes o con decoradores @get/@post.
- Parámetros de Ruta y Middleware Leyendo :id y query string mediante req.params/req.query; añadiendo middlewares con http.middleware.
- Respuestas y Workers http.response, http.html y http.redirect para control de estado; http.workers para paralelismo.
- Elementos condicionales con v:if Use `v:if={condition}` cuando una condición decide si existe un elemento completo.
- Formularios de Action Tipados Envía campos escalares a una @action con HTML nativo y conversión en el servidor desde su firma.
Base de Datos
7 recetas
- Conexión y Ping Abrir una conexión con Database.open, verificar con ping y cerrar con defer.
- DDL e Inserción Crear tablas con db.execute e insertar filas contando las afectadas.
- Consulta de Filas db.query devuelve una lista de maps {columna: valor} que se puede iterar con for.
- Consultas Parametrizadas Usar ? + array de bindings para pasar valores externos con seguridad.
- Transacciones db.transaction garantiza atomicidad: commit automático al retornar, rollback automático en caso de error.
- sql"…" — Plantilla Segura y Scalar El literal sql"..." auto-parametriza las interpolaciones y expone los métodos :query, :execute y :scalar.
- Protección contra SQL Injection Las interpolaciones en sql"..." son siempre parámetros vinculados — los metacaracteres SQL en el valor son literales, nunca ejecutados.
CLI y Herramientas
9 recetas
- Argumentos del Proceso Leer la línea de comandos con `process.argv()` y aislar los argumentos del usuario.
- Variables de Entorno y Plataforma Leer, definir y eliminar variables de entorno; detectar SO, arquitectura y directorio home.
- Ciclo de Vida del Proceso Terminar con `process.exit`, registrar hooks `on shutdown`, capturar panics y señales del SO.
- Comando Doctor Patrón de diagnóstico: agregar verificaciones de entorno y salir con código no-cero cuando algo falla.
- Builder @cli Parsing declarativo con `@cli` + `@arg`: flags, posicionales, `--help` automático y subcomandos.
- Literales de Comando y Seguridad Construye comandos lazy con sh"…", interpola argv de forma segura y maneja errores de proceso tipados.
- Efectos y Pipelines de Procesos Simula la ejecución, conecta procesos reales y transforma datos estructurados del sistema.
- Streaming y Scripts Ejecutables Consume la salida de procesos de forma incremental y ejecuta archivos .zolo con shebang en Unix.
- Comandos Paralelos e Interfaz de Terminal Ejecuta comandos independientes en paralelo y añade estilos ANSI accesibles a CLIs interactivas.
Recarga en caliente
6 recetas
- Reload Básico El "hello world" de zolo dev: edita un módulo, guárdalo y ve la nueva versión en acción sin reiniciar la VM.
- Preservación de Estado pub let con tipo de runtime estable sobrevive al swap — el valor acumulado continúa; solo el nuevo inicializador literal es descartado.
- Hooks del Ciclo de Reload Tres puntos de extensión del pipeline de swap: __on_reload para notificación, #[hot_dispose] para capturar estado antes, y #[hot_accept] para restaurarlo después.
- Reload de Assets HMR para archivos de datos: edita config.json, shaders o CSVs y el hook __on_asset_reload reacciona sin reiniciar la VM.
- Undo/Redo y Casos Avanzados Viaje en el tiempo por el historial de swaps via :undo / :redo / :history, más reload transparente en bucles cerrados sin yield y referencias de closure capturadas fuera del live-binding.
- Bucle de Render y Servidor HTTP Hot reload en un bucle de renderización wgpu con 1000 cubos y en un servidor HTTP en ejecución — sin perder el listener ni el estado GPU.
10 Acto 10 Build, Pruebas y Distribución
Testing
5 recetas
- Matchers con expect() La biblioteca expect() y sus matchers: igualdad, longitud, pertenencia, prefijo y negación.
- Suites con @suite Agrupa tests en módulos anotados con @suite, incluyendo suites anidadas.
- Atributos de Test Controla la ejecución con skip, should_throw, only y tag en los decoradores @test y @suite.
- Pruebas con nombres legibles Una declaración test usa un título entre comillas y el runner existente. Descubrimiento, filtros, informes y navegación conservan ese título. Los atributos y suites existentes siguen disponibles. Ejecutar el archivo normalmente no ejecuta sus pruebas: usa zolo test.
- Hooks de Ciclo de Vida Ejecuta código antes y después de cada test o de toda la suite con @before_each, @after_each, @before_all y @after_all.
Compilación
4 recetas
- Ejecutar o compilar VM interpretada (`zolo run`) y backend nativo (`zolo build`): cuándo usar cada uno y qué cambia entre ellos.
- Flags --emit Detener el pipeline de compilación antes: `--emit ir` imprime el ZoloIR; `--emit obj` escribe un archivo objeto sin enlazar.
- Build de Release El flag `--release` activa las optimizaciones de Cranelift para generar un binario más rápido, a costa de un build más lento.
- compile y bundle `zolo compile` muestra el Lua generado para la VM; `zolo bundle` agrupa la entrada y sus módulos en un único archivo Lua portátil.
WebAssembly
4 recetas
- Emitir Wasm Compila un programa Zolo a `.wasm` con `zolo build --emit wasm`; entiende el modo VM-embedded y el ABI host-shim predeterminado.
- Perfiles de Host Selecciona el perfil de runtime con `--host wasi|browser` y habilita el backend AOT experimental con `--aot`.
- Exportar Funciones Usa `@export` para exponer funciones Zolo a JavaScript/TypeScript mediante AOT wasm con `--host browser`.
- Arreglos (arrays) en Wasm Usa arrays en funciones AOT y exporta funciones que reciben o retornan `[int]`, `[bool]` y `[str]` a JavaScript.
Distribución
3 recetas
- Archivos .zar y .zex Empaqueta código como biblioteca reutilizable (`.zar`) o ejecutable portátil (`.zex`) con `zolo build --emit`.
- Binario Standalone Embebe el runtime en el `.zex` con `--standalone` para distribuir sin depender de que `zolo` esté instalado.
- GUI y Windowed Distribuye apps de escritorio sin ventana de consola con `--windowed` / `--gui`; ejecuta archivos listos con `zolo run`.
Integración con el SO
1 recetas