Programação funcional para Dart,
com laziness e concorrência embutidas.

FxDart é um port em Dart do FxTS — uma biblioteca para compor pipelines preguiçosos sobre dados síncronos e assíncronos, onde transformar seis requisições sequenciais de 1 segundo em um lote concorrente de 2 segundos é uma única chamada de método.

📒 Veja em ação: Daily Ledger — um app completo feito com FxDart →

⚖️ Dart vs FxDart — 53 tarefas reais, lado a lado →

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

▲ Isto está ao vivo — edite o código e pressione Executar. Ele compila com o compilador Dart de verdade e executa no seu navegador.

O que é FxDart?

FxDart traz o modelo de programação do FxTS para Dart: um kit de ~120 funções pequenas e componíveis para transformar coleções e dados assíncronos. Três ideias o definem:

Eventos no tempo, e falhas como valores, vivem nas outras duas superfícies. Qual superfície? é a decisão; esta página continua sendo a de marketing.

Por que precisamos disso?

Dart já tem Iterable e Stream. O FxDart conquista seu espaço onde eles se esgotam:

ProblemaDart puroFxDart
Limitar chamadas de API concorrentes a n, mantendo a ordem Filas manuais, Completers, controle minucioso .map(fetch).concurrent(3)
Pipelines de transformação assíncronos Stream é baseado em push; misturar await, backpressure e laziness fica intrincado Cadeia baseada em pull — cada valor só é calculado quando pedido
Manipulação de dados (group, index, count, partition, zip, chunk…) Loops escritos à mão toda vez Uma função nomeada e bem testada por conceito
Transformações de várias etapas legíveis Chamadas aninhadas ou variáveis intermediárias Cadeias fx() da esquerda para a direita, totalmente tipadas

Prós & Contras

✓ Prós

  • Laziness de graça — pipelines fazem short-circuit; só os valores pedidos são calculados.
  • Concorrência que preserva a ordem com um único operador: concurrent(n) / concurrentPool(n) na ordem de conclusão.
  • Cadeias totalmente tipadasfx() mantém a inferência de ponta a ponta; operadores síncronos são funções comuns sobre Iterables nativos, então tudo interopera com Dart comum.
  • Funções pequenas e focadas — ~120 operadores cobrindo transform / filter / slice / combine / aggregate / object / util.
  • Semântica testada em produção — comportamento portado do FxTS junto com mais de 850 de seus testes.
  • Zero dependências — Dart puro.

✗ Contras

  • Sem currying data-last — Dart não tem sobrecarga de funções, então o estilo pipe curried do FxTS vira cadeias; o pipe() dinâmico perde os tipos estáticos.
  • Uma segunda abstração assíncronaFxAsyncIterable existe porque Stream não consegue expressar o canal de retorno da concorrência; a ponte é fácil, mas é mais um conceito a aprender.
  • Curva de aprendizado — pensar em pipelines preguiçosos é diferente de loops imperativos.
  • Nem sempre o mais rápido — em hot loops minúsculos, um for escrito à mão pode superar a composição de operadores; o FxDart otimiza para clareza e trabalho I/O-bound.
  • Algumas APIs do TS não portam literalmente — elas ganham grafias nativas do Dart: curry vira o getter de extensão tipado .curried, com os nomes antigos mantidos como stubs deprecados para migração.

Uma amostra de concorrência

Seis requisições falsas de 300 ms cada — sequencialmente ~1,8 s, com concurrent(3) cerca de 0,6 s. Tente mudar o número:

Comece a aprender

FxDart 101 →

Um curso guiado: aulas, demos ao vivo e um playground para cada função.

Primeira aula: map →

Comece pelo operador mais fundamental.

Instalar →

Coloque o fxdart no seu pubspec e explore o código-fonte.