Programación funcional para Dart,
con pereza y concurrencia integradas.

FxDart es un port a Dart de FxTS: una librería para componer pipelines perezosos sobre datos síncronos y asíncronos, donde convertir seis peticiones secuenciales de 1 segundo en un lote concurrente de 2 segundos es una sola llamada a un método.

📒 Míralo en acción: Daily Ledger — una app completa hecha con FxDart →

⚖️ Dart vs FxDart — 53 tareas reales, lado a lado →

RxDart vs FxDart — push vs pull, 50 veredictos honestos →

▲ Esto está vivo: edita el código y pulsa Ejecutar. Se compila con el compilador real de Dart y se ejecuta en tu navegador.

¿Qué es FxDart?

FxDart lleva el modelo de programación de FxTS a Dart: un conjunto de ~120 funciones pequeñas y componibles para transformar colecciones y datos asíncronos. Lo definen tres ideas:

Los eventos en el tiempo, y los fallos como valores, viven en las otras dos superficies. ¿Qué superficie? es la decisión; esta página sigue siendo la de marketing.

¿Por qué la necesitamos?

Dart ya tiene Iterable y Stream. FxDart se gana su sitio donde estos se quedan cortos:

ProblemaDart puroFxDart
Limitar a n las llamadas concurrentes a una API, sin perder el orden Colas manuales, Completers, control minucioso .map(fetch).concurrent(3)
Pipelines de transformación asíncronos Stream se basa en push; mezclar await, contrapresión y pereza se complica Cadena basada en pull: cada valor se calcula solo cuando se pide
Manipulación de datos (agrupar, indexar, contar, particionar, zip, chunk…) Bucles escritos a mano cada vez Una función con nombre y bien probada por concepto
Transformaciones legibles de varios pasos Llamadas anidadas o variables intermedias Cadenas fx() de izquierda a derecha, totalmente tipadas

Ventajas & desventajas

✓ Ventajas

  • Pereza sin esfuerzo: los pipelines cortocircuitan; solo se calculan los valores solicitados.
  • Concurrencia que preserva el orden con un solo operador: concurrent(n) / concurrentPool(n) por orden de finalización.
  • Cadenas totalmente tipadas: fx() mantiene la inferencia de principio a fin; los operadores síncronos son funciones normales sobre Iterables nativos, así que todo interopera con Dart corriente.
  • Funciones pequeñas y específicas: ~120 operadores que cubren transformación / filtrado / segmentación / combinación / agregación / objeto / util.
  • Semántica probada en producción: comportamiento portado desde FxTS junto con más de 850 de sus tests.
  • Cero dependencias: Dart puro.

✗ Desventajas

  • Sin currificación data-last: Dart no tiene sobrecarga de funciones, así que el estilo currificado con pipe de FxTS se convierte en cadenas; el pipe() dinámico pierde los tipos estáticos.
  • Una segunda abstracción asíncrona: FxAsyncIterable existe porque Stream no puede expresar el canal de retorno de la concurrencia; el puente es fácil, pero es un concepto más que aprender.
  • Curva de aprendizaje: pensar en pipelines perezosos no es lo mismo que pensar en bucles imperativos.
  • No siempre es lo más rápido: en bucles diminutos y muy calientes, un for escrito a mano puede superar a la composición de operadores; FxDart optimiza la claridad y el trabajo limitado por E/S.
  • Algunas APIs de TS no se portan literalmente: adoptan una forma nativa de Dart; por ejemplo, curry pasa a ser el getter de extensión tipado .curried, y los nombres antiguos se conservan como stubs obsoletos para la migración.

Un aperitivo de concurrencia

Seis peticiones simuladas de 300 ms cada una: en secuencia ~1,8 s, con concurrent(3) unos 0,6 s. Prueba a cambiar el número:

Empieza a aprender

FxDart 101 →

Un curso guiado: lecciones, demos en vivo y un playground para cada función.

Primera lección: map →

Empieza por el operador más fundamental.

Instalar →

Añade fxdart a tu pubspec y explora el código fuente.