¿Por qué los mejores lenguajes de programación no son los más usados? Llevamos décadas con esta pregunta dando vueltas y la respuesta incómoda sigue siendo la misma: porque la calidad técnica nunca fue el factor determinante. Nunca lo fue. Y sin embargo, cada vez que aparece una propuesta nueva de diseño de lenguajes, el debate se centra en la sintaxis, en el sistema de tipos, en la ergonomía. Como si el problema fuera ese.
Leí el post en HN sobre un lenguaje diseñado para ser "perfeccionable" — un sistema donde la sintaxis puede evolucionar de forma controlada, donde el lenguaje puede corregir sus propios errores de diseño sin romper compatibilidad hacia atrás. La idea me pareció hermosa. Genuinamente. Y después me quedé sentado diez minutos pensando en todo lo que no va a funcionar.
Este es el post más pesimista que voy a escribir este mes.
Diseño de lenguajes de programación, evolución de sintaxis y la trampa del mérito técnico
El argumento de los lenguajes "perfeccionables" arranca desde un diagnóstico correcto: todos los lenguajes maduros acumulan deuda de diseño. Python tiene el GIL. JavaScript tiene this. C++ tiene... bueno, C++. Y una vez que esas decisiones están en producción, cambiarlas es casi imposible porque hay millones de líneas de código que dependen de ese comportamiento roto.
La solución propuesta es elegante en papel: diseñás el lenguaje desde el día cero con mecanismos de evolución. Cada feature tiene un ciclo de vida explícito. Podés deprecar sintaxis, introducir nuevas formas, y el tooling te ayuda a migrar. El lenguaje puede aprender de sus propios errores.
Es exactamente el tipo de idea que genera 400 comentarios en Hacker News y ningún adoption real cinco años después.
No digo esto con cinismo. Lo digo porque lo viví tres veces.
Los tres lenguajes que amé y que el ecosistema abandonó
Coffeescript, 2012. Tenía 21 años, estaba cursando Ciencias de la Computación en la UBA de día y trabajando de noche, y CoffeeScript me pareció la solución obvia a todo lo horrible de JavaScript. Sintaxis limpia, funciones flecha antes de que existieran, clases que tenían sentido. Llegué a escribir código de producción en CoffeeScript. Era genuinamente más lindo.
Después llegó ES6. Y Babel. Y el ecosistema entero migró en 18 meses. No porque CoffeeScript fuera malo — sino porque las empresas grandes metieron fichas en ES6, porque los IDEs lo adoptaron, porque los hiring managers empezaron a pedir "JavaScript moderno". CoffeeScript no perdió por mérito técnico. Perdió porque jugó solo.
Elixir, 2018. Me enamoré de Elixir en una semana. Concurrencia como ciudadana de primera clase, pattern matching real, procesos livianos, fault tolerance por diseño. Construí un par de servicios internos. Evangelicé dentro del equipo. Era el lenguaje que resolvía exactamente los problemas que yo tenía.
Lo abandoné en 2020 no porque Elixir se pusiera peor. Lo abandoné porque cuando necesité sumar gente al equipo, el pool de candidatos con experiencia en Elixir en Argentina era microscópico. Cada vez que pedía ayuda en un problema raro, el tiempo de respuesta de la comunidad era 10x el de Stack Overflow para Python. El lenguaje era mejor. El ecosistema no lo era.
Nim, 2021. Esto ya lo conté menos. Nim tiene una de las propuestas técnicas más interesantes que vi: compila a C, tiene metaprogramación poderosa, sintaxis pythónica, performance de lenguaje de sistemas. Lo estudié en serio durante la pandemia, cuando hice mi pivot a software development.
Nim existe. Nim tiene usuarios. Nim sigue en desarrollo activo. Pero si hoy tuvieras que elegir entre Nim y Go para un proyecto nuevo, la decisión no sería técnica — sería sobre quién lo usa, qué empresas lo respaldan, cuántos paquetes tiene, si tu próximo empleador lo conoce.
# Este código Nim que escribí en 2021 sigue siendo de mis favoritos
# Un servidor HTTP simple con tipos expresivos
import asynchttpserver, asyncdispatch, json
# El sistema de tipos de Nim permitía esto de forma elegante
type
ApiResponse = object
status: string
data: JsonNode
timestamp: int64
proc handleRequest(req: Request): Future[void] {.async.} =
# Pattern matching real, sin el boilerplate de otros lenguajes
case req.url.path
of "/health":
let resp = ApiResponse(
status: "ok",
data: newJNull(),
timestamp: getTime().toUnix()
)
await req.respond(Http200, $(%resp))
else:
await req.respond(Http404, "not found")
Este código nunca llegó a producción. No porque no funcionara. Porque el CTO preguntó "¿y quién más en el mercado usa esto?" y la respuesta honesta era "pocos".
Por qué un lenguaje 'perfeccionable' enfrenta exactamente el mismo problema
La propuesta de un lenguaje con evolución de sintaxis controlada tiene un problema de bootstrap que no se resuelve con buenas ideas de diseño.
Para que el mecanismo de evolución sea valioso, necesitás una base de código existente que necesite evolucionar. Para tener esa base de código, necesitás adopción. Para tener adopción, necesitás tooling maduro, paquetes, IDEs, cursos, empresas que contraten. Todo eso tarda años y requiere que alguien apueste recursos reales.
Es la misma trampa en la que cayeron CoffeeScript, Elixir para empresas conservadoras, y Nim. No es una trampa de calidad técnica. Es una trampa de coordinación.
Miré cómo los benchmarks de agentes de IA están siendo rotos y pensé algo similar: los rankings técnicos miden lo que es medible, no lo que importa en producción. Un lenguaje puede ganar todos los benchmarks de ergonomía y diseño y aun así ser irrelevante en cinco años.
Pensé también en el debate sobre contribuir al kernel de Linux con IA. Linux lleva 30 años de inercia acumulada. C tiene 50. No son los mejores lenguajes posibles para lo que hacen — son los lenguajes que ganaron la guerra de adopción temprana y ahora tienen fosos tan profundos que ninguna superioridad técnica los cruza.
Los errores que comete todo diseñador de lenguajes nuevos
Error 1: Creer que el problema es técnico. El diseño de lenguajes de programación es un problema de redes sociales tanto como de ciencias de la computación. El lenguaje que adoptan las empresas grandes se vuelve el estándar. El que no las consigue, queda en nicho permanente.
Error 2: Subestimar el costo de migración. Incluso un lenguaje con mecanismos perfectos de evolución requiere que los devs aprendan esos mecanismos, que el tooling los soporte, que los code reviews incluyan nueva semántica. La energía cognitiva tiene límite. Cuando TypeScript compite con "aprender el sistema de tipos evolutivos de X", TypeScript gana por default.
Error 3: Confundir la comunidad early adopter con tracción real. Los primeros 500 usuarios de cualquier lenguaje interesante son entusiastas que escriben compiladores como hobby. Eso no predice nada sobre adopción corporativa. Y sin adopción corporativa, no hay paquetes de terceros serios, no hay hiring market, no hay futuro.
Error 4: No tener una empresa respaldando. Rust tiene Mozilla y ahora la Rust Foundation. Go tiene Google. Kotlin tiene JetBrains. Swift tiene Apple. TypeScript tiene Microsoft. ¿Qué tiene tu lenguaje perfeccionable? Si la respuesta es "una comunidad apasionada", ya sé cómo termina la historia.
// Mientras tanto, esto es lo que corro en producción en 2026
// TypeScript: no el mejor lenguaje posible, sino el que ganó
interface EvolucionLenguaje {
meritotecnico: number; // Lo que los diseñadores optimizan
adopcionCorporativa: number; // Lo que determina el resultado
toolingMaturo: boolean; // El factor que nadie menciona en los posts de HN
empresaDetras: string | null; // null === riesgo existencial
}
// La función que ningún post de "lenguaje del futuro" quiere escribir
function prediccionSupervivencia(lang: EvolucionLenguaje): string {
if (!lang.empresaDetras && lang.adopcionCorporativa < 0.3) {
return "nicho eterno o muerte silenciosa"; // CoffeeScript, Nim, Elm...
}
if (lang.toolingMaturo && lang.empresaDetras) {
return "tiene chances reales"; // Rust, Go, Kotlin
}
return "depende de si alguien grande apuesta"; // El limbo
}
Esto conecta con algo que escribí sobre seguridad en code reviews: los problemas técnicos más interesantes raramente son los que determinan qué tecnología sobrevive. Lo que sobrevive es lo que tiene suficiente inercia organizacional para que sea más caro abandonarlo que aguantarlo.
La parte que me rompe el corazón
Hay algo genuinamente triste en esto que quiero ser honesto sobre.
La idea de un lenguaje que puede corregir sus propios errores de diseño es una respuesta real a un problema real. Python 3 tardó más de una década en reemplazar a Python 2 — y eso con Guido van Rossum, con la PSF, con Google metiendo recursos. Imaginate hacer esa transición sin esa infraestructura.
Cuando vi el post de la bailarina con ALS controlando una performance con ondas cerebrales, pensé en la distancia entre lo que es técnicamente posible y lo que llega a ser ubicuo. La tecnología BCI existe desde hace décadas. La implementación en vivo que vi fue hermosa. Pero entre eso y que sea mainstream hay un abismo que no cruza la calidad técnica sola.
Los lenguajes son igual. Los deadlocks en Rust son un problema real que Rust resuelve con elegancia técnica notable. Pero Rust tardó 10 años en llegar al kernel de Linux, y eso con Mozilla y la Rust Foundation empujando. Un lenguaje indie con mejores ideas no tiene esos 10 años ni ese respaldo.
La idea hermosa sin adopción es filosofía. Y la filosofía no corre en producción.
FAQ: Diseño de lenguajes de programación y evolución de sintaxis
¿Por qué los lenguajes de programación técnicamente superiores no siempre ganan?
Porque la adopción de un lenguaje depende más de efectos de red que de mérito técnico. Un lenguaje con peor diseño pero más paquetes disponibles, más devs en el mercado laboral y más soporte de IDEs es más atractivo en la práctica que uno técnicamente superior pero con ecosistema pequeño. COBOL sigue corriendo sistemas bancarios críticos no porque sea el mejor lenguaje sino porque el costo de migrar supera cualquier beneficio técnico.
¿Qué significa que un lenguaje sea 'perfeccionable' o tenga evolución de sintaxis controlada?
Es un diseño donde el lenguaje incluye mecanismos explícitos para deprecar features, introducir nueva sintaxis de forma gradual y migrar código existente de forma asistida. La idea es evitar el problema de Python 2→3: poder mejorar el lenguaje sin romper compatibilidad ni requerir migraciones manuales masivas. Técnicamente interesante, pero requiere que haya código existente que migrar, lo que requiere adopción previa.
¿Hay ejemplos de lenguajes que evolucionaron su sintaxis con éxito?
JavaScript es el caso más notorio: ES6, ES7 y versiones posteriores introdujeron cambios radicales (arrow functions, async/await, módulos) sin romper código viejo gracias a Babel y transpilación. Pero JavaScript lo logró porque ya tenía adopción masiva antes de empezar a evolucionar. Python también evolucionó, pero la transición 2→3 tardó 12 años y tuvo fricción enorme. Rust introduce cambios con editions (Rust 2018, Rust 2021) — ese es probablemente el modelo más cercano a lo que se propone.
¿Por qué fracasan tantos lenguajes de programación prometedores?
Por el problema del bootstrap: necesitás ecosistema para tener adopción, y necesitás adopción para tener ecosistema. Los lenguajes que rompen ese ciclo generalmente lo hacen porque una empresa grande los adopta internamente (Go en Google, Kotlin en JetBrains/Android, Swift en Apple) o porque resuelven un problema tan específico y urgente que la comunidad construye el ecosistema desde abajo (Rust para sistemas sin GC en Mozilla). Sin alguno de esos dos caminos, el lenguaje queda en nicho permanente.
¿Tiene sentido aprender un lenguaje de programación que no es mainstream?
Sí, pero con expectativas claras. Aprender Elixir, Haskell, Nim o cualquier lenguaje de nicho te hace mejor programador — te expone a paradigmas y soluciones que después aplicás en cualquier lenguaje. El problema es construir un producto o servicio que dependa de ese lenguaje para una empresa: el riesgo de no encontrar devs, de que los paquetes queden sin mantenimiento o de que el lenguaje deje de evolucionar es real y hay que pesarlo.
¿Cuál es el factor más subestimado en el éxito de un lenguaje de programación?
El tooling del día uno. No el tooling cuando el lenguaje madura — el tooling disponible cuando un dev lo prueba por primera vez. Si el autocompletado no funciona bien en VS Code, si el debugger es complicado, si el formatter no existe, el dev lo descarta en la primera tarde y nunca vuelve. Rust invirtió enormemente en rust-analyzer y cargo desde muy temprano. Go tuvo gofmt desde el principio. Eso no es accidental — los diseñadores que entienden que el lenguaje compite por tiempo de atención de devs priorizan tooling sobre features del lenguaje.
Lo que pienso de verdad
Quiero que este lenguaje perfeccionable tenga éxito. Genuinamente. La idea de poder corregir errores de diseño en producción es una de las respuestas más honestas al problema de la deuda técnica en lenguajes maduros.
Pero soy empirico, no romántico. Los números no mienten: de todos los lenguajes con propuestas técnicas interesantes que aparecen en HN cada año, menos del 1% llegan a tener adopción corporativa significativa en diez años. No por falta de buenas ideas. Por falta de la combinación específica de respaldo institucional, timing de mercado y tooling temprano que convierte un experimento en infraestructura.
Lo que más me preocupa del discurso de "lenguajes perfeccionables" es que asume que el problema central es técnico. Que si diseñás bien el mecanismo de evolución, el lenguaje va a poder adaptarse y sobrevivir. Pero la evolución no te salva si no tenés masa crítica para empezar a evolucionar.
Yo sigo escribiendo TypeScript. No porque sea el mejor lenguaje posible. Porque es el que tiene el ecosistema que necesito, el que mi equipo conoce, el que los candidatos traen en el CV, el que Railway soporta de primera clase, el que tiene 15 años de soluciones stackeadas en Stack Overflow.
Y eso, más que cualquier elegancia de diseño, es lo que determina qué corre en producción mañana a las 3am cuando algo rompe.
¿Vos también tenés tu lenguaje favorito que nunca llegó a ningún lado? Me interesa saber cuál es y por qué creés que no pegó. Escribime.
Este artículo fue publicado originalmente en juanchi.dev
Top comments (0)