Determinismo como alternativa a la funcionalidad pura en el núcleo de tu app
Un artículo propone relajar el patrón 'Functional Core, Imperative Shell' para permitir núcleos deterministas con estado mutable, ampliando su aplicabilidad.

Un artículo publicado en outdata.net propone una variante del patrón de arquitectura "Functional Core, Imperative Shell" acuñado por Gary Bernhardt. La premisa es clara: no todo el código del núcleo necesita ser puramente funcional para ser determinista y, por tanto, testeable. El autor argumenta que basta con que el núcleo sea determinista, permitiendo el uso de máquinas de estado y mutación local, siempre que se aíslen las dependencias externas e inciertas en la "cáscara" imperativa.
El texto parte de la definición clásica: un núcleo funcional puro no realiza IO ni actualiza estado destructivo, lo que garantiza que los mismos inputs produzcan los mismos outputs. Sin embargo, el autor introduce un ejemplo en JavaScript donde una función pura de suma y una clase que actúa como máquina de estado producen resultados idénticos para la misma secuencia de operaciones. La clase muta su estado interno, pero su comportamiento es completamente predecible. Aquí está la clave: la determinación no exige inmutabilidad absoluta, sino repetibilidad.
Para identificar dónde colocar la lógica, el artículo sugiere trabajar de forma inversa: aislar todo aquello que no es determinista. Llamadas a generadores de números aleatorios no sembrados, operaciones asíncronas, red, interacciones con bases de datos o lecturas del reloj del sistema deben vivir en la capa externa. Si encuentras estas dependencias dentro de la lógica de negocio, son puntos naturales para refactorizar: extraerlas o inyectar sus resultados como parámetros.
El autor reconoce que en codebases heredados o generados a la velocidad de la luz, la distinción rara vez es nítida. Usa una metáfora interesantes: el "desfragmentación del determinismo". Igual que el antiguo desfragmentador de disco de Windows recogía fragmentos dispersos, el objetivo es agrupar los fragmentos de lógica determinista escondidos en el código. No se trata de reescribir la base entera, sino de identificar miles de micro-núcleos deterministas y gradualmente reducir la superficie de código difícil de testear. Incluso en sistemas complejos, reducir de miles a cientos de núcleos aislables mejora la confianza en el sistema.
El artículo cierra con un tono optimista hacia el desarrollo práctico: asume que dentro de cualquier sistema caótico hay máquinas de estado bien definidas esperando a ser extraídas. La propuesta no es dogmática sobre el paradigma funcional, sino pragmática: busca testabilidad y fiabilidad operativa mediante la separación estricta entre lo que es predecible y lo que no.


