Hace casi un año escribí ¿Acabaremos programando todos en ensamblador?, que comenzaba así:
Un lenguaje de programación es un lenguaje que media entre el que nos es familiar a los humanos y el que reconocen las computadoras. Los lenguajes de alto nivel nos resultan más cómodos; los de bajo nivel, más crípticos. Todos conocemos, pienso, el trade-off.
Hay lenguajes muy próximos a los humanos, como scratch o logo. Otros, a la máquina, como C o ensamblador. Mucha gente opta por uno en la zona media del espectro, como Python.
Hace un año, motivado por las primeras noticias que me llegaron sobre la moda del vibe coding, escribí también:
En el momento en que, como Karpathy hoy, los humanos nos olvidemos de que el código existe, ¿para qué necesitaremos que los LLMs generen Python?, ¿por qué no C o, ya puestos, ensamblador directamente?
Sin embargo, no es evidente que el lugar ideal para los LLMs dentro del espectro sea el aledaño al hierro.
Supongamos que alguien se plantea diseñar un lenguaje de programación. Lo hace pensando en un público, en una serie de requisitos. Si quiere que resulte fácil de leer y mantener, que no abrume al programador con detallitos de implementación, que sea modular, que sea expresivo, generoso en azúcar sintáctico, etc., le puede acabar saliendo algo parecido a Python. Si sacrifica la robustez en aras de la facilidad de uso en modo interactivo (o REPL), igual construye algo que se parezca a R.
La pregunta que le viene de manera natural a la cabeza a uno es: ¿cuáles deberían ser las características de un lenguaje de programación apropiado para los LLMs? ¿Cómo sería el lenguaje de programación resultante? Y una primera respuesta a estas preguntas la proporciona nanolang, una primera propuesta —al menos, de la que tenga noticia— de un lenguaje de programación pensado específicamente para ser escrito por LLMs y no por humanos. Algunas de sus características específicas son:
- Sintaxis mínima en pro de la economía de tokens. Se puede escribir
fnen lugar defunctionoi32en lugar deint32. Se puede reducir el número de caracteres (ergo, tokens) necesarios para definir o llamar a una función. Los humanos agradecemos cierto grado de redundancia —el lenguaje natural también lo tiene— pero las máquinas, no tanto. - Sintaxis unívoca (no ambigua). Por ejemplo, usa la notación polaca para las expresiones matemáticas, que evita la complejidad de las reglas de precedencia de operadores. Así,
3 * 5 + 4se escribiría algo así(+ (* 3 5) 4), que evita mantener la regla implícita de que el producto se resuelve antes que la suma. Aunque los humanos odiemos la notación polaca, a las máquinas les encanta. - Test obligatorios en las funciones para tratar de alinear mejor su implementación en código a la esperada y que aquella no sea solo un mejor esfuerzo probabilístico.
- Tipado estático. Universalmente odiado por los humanos no neurodivergentes.
- Una standard library pequeña y bien estructurada.
- Finalmente, en aras de la eficiencia y portabilidad, el código generado por nanolang se transpila a C.
A saber qué pasará en unos años.
De todos modos, no tengo claro que a corto plazo vaya a resolver los problemas que nos encontramos los científicos de datos. En particular, veo mucha distancia entre lo descrito arriba y un sistema que pueda responder en tiempo real a peticiones del tipo:
Baja tales datos de tal sitio, ajusta tal tipo de modelo y construye tales gráficos de tal manera concreta.
No es suficiente con una biblioteca estándar pequeña y estructurada. Hacen falta extensiones y módulos no presentes en nanolang. Pero todos nos acordamos de cómo Python no fue una alternativa a R o SAS durante mucho tiempo y lo que ha sucedido después, tras asentarse el ecosistema de datos alrededor de pandas.