Este artículo forma parte de una serie que explora ejercicios del libro 'Structure and Interpretation of Computer Programs' (SICP) de Abelson y Sussman, trasladándolos a Haskell. En esta entrega, el autor replica en Haskell el simulador de circuitos digitales que SICP implementa usando estado mutable oculto y paso de mensajes, un enfoque con sabor a programación orientada a objetos.
El texto comienza definiendo un tipo Wire con dos IORefs: uno para los procedimientos de acción (suscriptores a la señal) y otro para el valor actual de la señal (Low o High). Se implementan get_signal, set_signal —que dispara las acciones cuando la señal cambia— y add_action para registrar suscriptores. Una probe es simplemente una acción que imprime el valor de la wire.
Sobre esa base se construyen componentes básicos: inverter, and_gate y or_gate, todos como procedimientos de acción instalados en sus wires de entrada. Estos componentes son abiertos (cualquier usuario puede añadir los suyos), tienen un número variable de entradas/salidas y se componen libremente: el autor define half_adder y full_adder combinando puertas y sumadores.
El reto más singular es replicar la agenda global mutable que SICP usa para simular retardos de propagación. El autor lo logra mediante unsafePerformIO para crear the_agenda como variable global impura, reconociendo que es una mala práctica y que rompe garantías propias de Haskell. La función propagate extrae el siguiente paso temporal mínimo de la agenda, actualiza el tiempo y ejecuta las acciones programadas hasta que el circuito se estabiliza.
El artículo cierra la puerta a la implementación práctica de la simulación temporal y deja al lector con un ejemplo de cómo Haskell puede aproximar patrones imperativos cuando es necesario, aunque con costes claros.
