Mojo: el lenguaje que le enseñó a Python a hablar con el silicio
Creado por Modular, la empresa de Chris Lattner, mantiene la sintaxis que ya conocés y le agrega
tipos, control de memoria y compilación nativa. La promesa es incómoda de tan simple: escribir el prototipo y
la versión de producción en el mismo archivo.
Hay una escena que se repite en casi todos los equipos que trabajan con inteligencia artificial. Alguien
prototipa una idea en Python, funciona, y entonces empieza la parte fea: reescribir esa misma lógica en C++ o
en CUDA porque en producción tiene que correr rápido. Dos lenguajes, dos bases de código, dos equipos que no
siempre hablan el mismo idioma y una montaña de errores que aparecen justo en la traducción. La industria le
puso nombre a esa maldición: el problema de los dos lenguajes. Mojo nació para intentar
romperlo.
Quién está detrás
El dato no es menor, porque explica buena parte de las expectativas. Mojo es obra de Modular, compañía
fundada por Chris Lattner y Tim Davis, y presentada públicamente en mayo de 2023. Lattner no es
un desconocido: creó LLVM, la infraestructura de compiladores sobre la que se apoya medio mundo del
software; escribió Clang; diseñó Swift en Apple; y más tarde impulsó MLIR, la representación intermedia que
hoy sostiene buena parte del stack de compilación para machine learning.
Es decir: no se trata de un lenguaje improvisado por entusiastas, sino del cuarto o quinto intento de
alguien que lleva veinte años construyendo las capas invisibles sobre las que corre el software moderno. Y
esta vez el objetivo declarado no es un lenguaje más, sino unificar la infraestructura de la IA, que hoy
está fragmentada en decenas de frameworks, kernels y compiladores que apenas se entienden entre sí.
Python por fuera, sistemas por dentro
La decisión de diseño más audaz de Mojo fue no inventar una sintaxis nueva. Toma la de Python —
indentación, def, decoradores, la estética general — y construye debajo un lenguaje de
sistemas completo. La meta a largo plazo declarada por Modular es llegar a ser un superconjunto de Python,
de modo que el código Python existente sea código Mojo válido. Todavía no está en ese punto, y conviene
decirlo con todas las letras, pero la interoperabilidad ya permite importar y usar paquetes del ecosistema
de Python desde Mojo.
La diferencia asoma apenas se mira una función. Mojo mantiene def con su flexibilidad
habitual, pero suma fn: una función estricta, con tipos obligatorios y verificaciones en
tiempo de compilación. El mismo archivo puede contener las dos formas, y esa convivencia es justamente la
idea. Prototipás suelto arriba y endurecés abajo, sin cambiar de lenguaje ni de repositorio.
# Estilo Python: cómodo para prototipar
def saludar(nombre):
return "Hola, " + nombre
# Estilo sistemas: tipado y estricto
fn sumar(a: Int, b: Int) -> Int:
return a + b
# Sin despacho dinámico: el layout
# se resuelve en compilación
struct Punto:
var x: Float64
var y: Float64
A eso se suman los struct, que a simple vista parecen clases de Python pero no lo son: se
resuelven por completo en tiempo de compilación, sin despacho dinámico ni la indirección que arrastra un
objeto tradicional. El resultado es un tipo de dato con la comodidad de escritura de Python y el costo de
ejecución de una estructura de C.
Tres formas de resolver el mismo problema
| Aspecto | Python | C++ / CUDA | Mojo |
|---|---|---|---|
| Curva de entrada | Muy baja: es el idioma común de la ciencia de datos | Alta: memoria, punteros y modelo de hardware | Baja para empezar, creciente a medida que se baja de nivel |
| Velocidad de ejecución | Interpretado; depende de librerías escritas en C | Máxima, compilada y ajustada a mano | Compilada de forma nativa mediante MLIR y LLVM |
| Paralelismo | Limitado por el GIL en hilos de CPU | Total, pero con toda la gestión a cargo del programador | Sin GIL, con primitivas de vectorización y paralelismo integradas |
| Manejo de memoria | Automático, con recolector de basura | Manual o mediante punteros inteligentes | Modelo de propiedad de valores, en la línea de Rust y Swift |
| Camino a producción | Suele exigir reescritura en otro lenguaje | Ya es el destino final | El mismo archivo evoluciona de prototipo a versión optimizada |
| Ecosistema | Enorme y maduro | Enorme, con fuerte dependencia del proveedor de GPU | Joven, apoyado en la interoperabilidad con Python |
MLIR: la pieza que casi nadie ve
Debajo de la sintaxis amable hay una apuesta técnica concreta. Mojo se construyó sobre
MLIR (Multi-Level Intermediate Representation), una infraestructura de compilación que Lattner
impulsó durante su paso por Google y que hoy vive dentro del proyecto LLVM. La idea de MLIR es permitir que
un compilador razone en varios niveles de abstracción al mismo tiempo, desde una operación matemática de
alto nivel hasta la instrucción concreta que ejecuta un acelerador.
Eso es exactamente lo que necesita el mundo de la IA, donde el mismo modelo tiene que correr sobre CPU,
GPU y chips especializados que aparecen cada año. Los lenguajes clásicos fueron diseñados cuando el
objetivo era un procesador y punto. Mojo parte de la premisa contraria: el destino es heterogéneo desde el
primer día, y el compilador debe poder hablarle a cada pieza de silicio sin que el programador cambie de
herramienta.
Sin GIL, con SIMD y con dueños
Tres características explican de dónde sale el rendimiento. La primera es la ausencia del
GIL, el bloqueo global del intérprete que en CPython impide que varios hilos ejecuten
bytecode en paralelo y que obliga a rodeos incómodos cuando se quiere aprovechar una CPU moderna. Mojo no
lo tiene, y el paralelismo real de hilos deja de ser una excepción para volverse el comportamiento
esperado.
La segunda es el tratamiento de SIMD como ciudadano de primera clase. Las instrucciones que
operan sobre varios datos a la vez, que en otros lenguajes se alcanzan con intrínsecos o rezando para que
el compilador vectorice solo, en Mojo se expresan directamente en el tipo. Junto con las utilidades para
vectorizar y paralelizar bucles, permite ajustar el código al hardware sin abandonar el archivo.
La tercera es el modelo de propiedad de valores, emparentado con el de Rust y Swift, que
define con claridad quién es dueño de un dato, quién solo lo lee y quién puede modificarlo. Es la vía para
obtener seguridad de memoria sin pagar el costo de un recolector de basura corriendo detrás.
El pulso contra el monocultivo de CUDA
Hay una lectura estratégica que no conviene pasar por alto. Durante más de quince años, programar
aceleradores para IA significó, en la práctica, programar en CUDA, y CUDA corre sobre hardware de una sola
compañía. Ese es el verdadero foso competitivo de NVIDIA: no solo los chips, sino la década y media de
software, librerías y costumbres construidas encima.
Mojo, junto con la plataforma MAX de Modular, se presenta como una alternativa a esa
dependencia: escribir kernels de alto rendimiento en un solo lenguaje y poder ejecutarlos sobre hardware de
distintos fabricantes. Es una ambición enorme y sería ingenuo darla por cumplida, porque la ventaja de
NVIDIA es tanto técnica como cultural. Pero explica por qué un lenguaje joven despierta tanta atención
entre quienes pagan la factura de la infraestructura.
Lo que todavía no es
El entusiasmo conviene administrarlo. Mojo sigue siendo un proyecto en evolución y hay cosas que aún no están resueltas:
¿Vale la pena aprenderlo?
Depende de a qué te dediques. Si trabajás en desarrollo web, aplicaciones de negocio o automatización, no
hay ninguna urgencia: Python sigue siendo la respuesta correcta y lo seguirá siendo por mucho tiempo. Pero
si tu trabajo toca kernels, inferencia, rendimiento o infraestructura de modelos, Mojo es la clase de
apuesta que conviene mirar de cerca antes de que deje de ser opcional.
Y hay algo más de fondo, que trasciende a este lenguaje en particular. Durante décadas, la programación de
alto nivel y la de sistemas fueron dos mundos separados por una frontera que casi nadie cruzaba dos veces
en el mismo proyecto. Mojo apuesta a que esa frontera era un accidente histórico y no una ley de la
naturaleza. Si acierta, el próximo salto de rendimiento en inteligencia artificial no vendrá solamente de
chips más grandes, sino de que por fin podamos escribir para ellos sin cambiar de idioma a mitad de
camino.