Resolviendo elegantemente el problema de la expresión: despacho múltiple y métodos abiertos

2025-09-07

Este artículo profundiza en el 'problema de la expresión', un desafío que afecta tanto a la programación orientada a objetos como a la funcional: agregar nuevos tipos de datos y operaciones sin modificar el código existente. Usando ejemplos en C++ y Haskell, el autor ilustra el núcleo del problema. La OOP tradicional lucha por extender tipos y operaciones simultáneamente, y la programación funcional enfrenta limitaciones similares. El artículo analiza a fondo el patrón de visitante y sus extensiones, utilizando finalmente los multimethods y protocolos de Clojure para demostrar cómo el despacho múltiple y los métodos abiertos resuelven elegantemente el problema de la expresión, permitiendo un código flexible y extensible.

Leer más
Desarrollo despacho múltiple

El Problema de la Expresión: Soluciones Elegantes en OOP y FP

2025-09-07

Este artículo profundiza en el "problema de la expresión" en el diseño de software: cómo agregar nuevos tipos de datos y operaciones sin modificar el código existente. El autor utiliza ejemplos en C++ y Haskell para ilustrar las limitaciones de la programación orientada a objetos y funcional en la resolución de este problema. El artículo luego explora soluciones elegantes utilizando el patrón visitor y los multimethods y protocolos de Clojure. El enfoque de Clojure aprovecha inteligentemente el poder de los métodos abiertos, separando las definiciones de métodos de las definiciones de tipo, permitiendo una extensión flexible sin modificar el código existente.

Leer más

Forth revisitado: Dos implementaciones y reflexiones sobre un lenguaje peculiar

2025-08-28

El autor revisita el lenguaje Forth, un lenguaje que conoció por primera vez hace 20 años. Durante dos meses, implementó dos intérpretes Forth: goforth (en Go) y ctil (en C). goforth, un intérprete puro, es simple pero carece de funciones avanzadas. ctil, más cercano a una implementación Forth tradicional, permite extender el lenguaje usando el propio Forth, mostrando su poder. El autor argumenta que las fortalezas únicas de Forth residen en su contexto de hardware antiguo. Sin embargo, su modelo basado en pila lo hace menos legible y menos práctico en contextos modernos, siendo más adecuado como un proyecto de aprendizaje para comprender los principios de los compiladores y las máquinas virtuales.

Leer más

Algoritmo de Unificación: Implementación y Aplicaciones

2025-08-18

Esta publicación profundiza en el algoritmo de unificación, un proceso para resolver automáticamente ecuaciones entre términos simbólicos. Tiene un amplio uso en programación lógica e inferencia de tipos. Comenzando con la coincidencia de patrones, la publicación construye el concepto de unificación, proporcionando una implementación en Python basada en el algoritmo mejorado de Norvig. La implementación incluye definiciones de estructuras de datos, la función principal `unify`, funciones auxiliares `unify_variable` y `occurs_check`, junto con ejemplos de código detallados y resultados de ejecución.

Leer más
Desarrollo unificación

La Elegante Conexión Entre la Multiplicación de Polinomios, la Convolución y el Procesamiento de Señales

2025-05-21

Esta publicación explora la conexión entre la multiplicación de polinomios, la convolución y el procesamiento de señales. Comienza explicando visualmente la multiplicación de polinomios usando tablas y diagramas, revelando su naturaleza fundamental como una operación de convolución. Luego, presenta señales y sistemas discretos, enfocándose en sistemas lineales invariantes en el tiempo (LTI). Explica que cualquier señal puede descomponerse en una secuencia de señales de impulso escaladas y desplazadas, y la respuesta de un sistema LTI puede calcularse usando convolución. Finalmente, trata brevemente las propiedades de la convolución y su relación con la transformada de Fourier, destacando que la transformada de Fourier de una convolución es igual al producto de las transformadas de Fourier de sus operandos, permitiendo un cálculo eficiente de la convolución.

Leer más

Filtros de Bloom: Una Estructura de Datos Probabilística para la Pertenencia Eficiente a Conjuntos

2025-05-02

Los filtros de Bloom son estructuras de datos probabilísticas que prueban de manera eficiente si un elemento es miembro de un conjunto, utilizando un espacio mínimo. Al aplicar hash a los elementos en múltiples ubicaciones en una matriz de bits, los filtros de Bloom ofrecen pruebas de pertenencia rápidas, aunque con una pequeña posibilidad de falsos positivos. Ideales para escenarios donde la mayoría de las consultas devuelven un resultado negativo, los filtros de Bloom aceleran significativamente las búsquedas. Este artículo detalla los principios subyacentes, la implementación (con un ejemplo en Go), y la derivación matemática. Un ejemplo práctico demuestra el cálculo de parámetros óptimos para un conjunto de miles de millones de elementos con una tasa de falsos positivos del 1%, destacando su eficacia en el procesamiento de datos a gran escala.

Leer más

Transformers Eficientes: Mezcla de Expertos con Acceso Disperso (MoE)

2025-04-20

Las capas de alimentación directa en los modelos Transformer suelen ser masivas, creando un cuello de botella de eficiencia. La Mezcla de Expertos con Acceso Disperso (MoE) ofrece una solución elegante. MoE descompone la capa de alimentación directa grande en varias redes más pequeñas de "expertos" y utiliza un enrutador para seleccionar el subconjunto óptimo de expertos para el cálculo de cada token, reduciendo significativamente el coste computacional y mejorando la eficiencia. Esta publicación detalla el funcionamiento de MoE, proporciona una implementación de NumPy y analiza cuestiones clave como el equilibrio de carga de los expertos.

Leer más

Entropía cruzada: Una inmersión profunda en la función de pérdida para la clasificación

2025-04-13

Esta publicación proporciona una explicación clara del papel de la entropía cruzada como función de pérdida en las tareas de clasificación del aprendizaje automático. Comenzando con conceptos de la teoría de la información, como el contenido de información y la entropia, se construye hasta la entropía cruzada, comparándola con la divergencia KL. El artículo concluye demostrando la relación entre la entropía cruzada y la estimación de máxima verosimilitud con ejemplos numéricos, aclarando su aplicación en el aprendizaje automático.

Leer más

Haciendo Milagros con Cuatro 2s: Una Solución Elegante a un Rompecabezas Matemático

2025-02-23

Un rompecabezas matemático aparentemente simple: usando solo cuatro 2s y cualquier operación matemática, genera cualquier número natural. Desde la aritmética de la escuela primaria hasta las matemáticas avanzadas de la universidad, todos pueden participar. Inicialmente un desafío aparentemente simple, la dificultad aumenta con la introducción de exponentes, factoriales, etc. Finalmente, el físico Dirac, usando raíces cuadradas anidadas y logaritmos, encontró una solución general, resolviendo elegantemente este problema centenario, incluso con solo cuatro 2s.

Leer más

Decoradores JIT de Python: Tres estrategias de implementación

2025-02-03

Este artículo profundiza en el popular patrón de decorador JIT en Python, particularmente su uso en las bibliotecas JAX y Triton. El autor implementa tres decoradores JIT desde cero utilizando un ejemplo simplificado: basado en AST, basado en bytecode y basado en rastreo. El enfoque basado en AST manipula directamente el Árbol de Sintaxis Abstracto; el enfoque basado en bytecode aprovecha el intérprete de bytecode de Python; y el enfoque basado en rastreo construye un IR de expresión rastreando la ejecución de la función en tiempo de ejecución. El artículo detalla las ventajas y desventajas de cada enfoque y utiliza JAX y Numba como ejemplos para ilustrar sus estrategias en aplicaciones del mundo real.

Leer más

Implementando Raft: Una inmersión en el consenso distribuido

2024-12-21

Esta es la primera entrada de una serie que detalla el algoritmo de consenso distribuido Raft y su implementación en Go. Raft resuelve el problema de replicar una máquina de estado determinista en varios servidores, asegurando la disponibilidad del servicio incluso con fallos de servidores. La entrada presenta los componentes principales de Raft: la máquina de estado, el registro, el módulo de consenso, los roles de líder/seguidor y la interacción del cliente. Se discute la tolerancia a fallos de Raft, el teorema CAP y la elección de Go como lenguaje de implementación. Las entradas posteriores profundizarán en los detalles de la implementación del algoritmo.

Leer más