Lisette — un lenguaje pequeño que compila al runtime de Go con sintaxis basada en Rust
(lisette.run)- Lenguaje pequeño que usa sintaxis estilo Rust y funciona sobre el runtime de Go, combinando las ventajas de ambos lenguajes
- Estructura que refuerza la seguridad y expresividad con tipos de datos algebraicos, pattern matching, sistema de tipos Hindley-Milner e inmutabilidad por defecto
- Garantiza interoperabilidad con el ecosistema de Go mediante import directo de paquetes Go, operador pipeline, bloques
tryy concurrencia basada entask - Mejora la experiencia del desarrollador y la estabilidad del código con detección de errores en tiempo de compilación, mensajes de diagnóstico claros y soporte LSP
- Un punto clave es que el código de Lisette se transforma en código Go legible, por lo que puede integrarse naturalmente con proyectos Go existentes
Resumen de Lisette
- Lisette es un lenguaje pequeño basado en sintaxis de Rust que compila al runtime de Go
- Se caracteriza por tipos de datos algebraicos, pattern matching, sin
nil, sistema de tipos Hindley-Milner, inmutabilidad por defecto e interoperabilidad con el ecosistema de Go - Puede instalarse con el comando
cargo install lisette, y permite importar y usar directamente paquetes de Go comofmt,ioyos
Sintaxis familiar
- Tiene una estructura sintáctica similar a Rust
- Soporta pattern matching mediante
enumymatch - Permite definir métodos con bloques
structeimpl
- Soporta pattern matching mediante
- Es un lenguaje orientado a expresiones, por lo que
if,lety los bloques devuelven valores - Soporta encadenamiento y lambdas, lo que permite expresar de forma concisa el manejo de variables de entorno o la manipulación de cadenas
- Soporta interfaces y genéricos, y permite escribir funciones genéricas mediante definiciones
interfacey restriccionesT: Trait - Permite manejar de forma concisa el tipo
Optioncon las sintaxis if let y let else
Seguridad
-
Detecta en tiempo de compilación errores que podrían ocurrir en el runtime de Go
- Si no se manejan todos los patrones en una sentencia
match, se genera un error - No se permite usar
nil; los valores faltantes se representan con Option<T> - Se genera una advertencia si se ignora un valor de retorno Result
- Se genera una advertencia si un tipo privado se expone en una API pública
- Se genera un error si una variable inmutable se pasa como argumento mutable
- Si falta un campo de una estructura, ocurre un error de compilación
- Los mensajes de diagnóstico incluyen ubicación exacta en el código y sugerencias de corrección
- Con soporte para LSP (Language Server Protocol) puede usarse en editores principales como VSCode, Neovim y Zed
- Si no se manejan todos los patrones en una sentencia
Usabilidad
- Diseñado con énfasis en la interoperabilidad con Go
- El operador pipeline (
|>) permite expresar el encadenamiento de funciones de forma concisa - Los bloques
trysimplifican la propagación de errores - La concurrencia se implementa con
taskyChannel, de forma similar a las goroutines de Go - Los atributos de serialización permiten especificar nombres de campos JSON, omisión, conversión a cadena y etiquetas de validación
- Incluye bloques
recoverpara recuperación depanic, y permite manejo seguro de errores con el tipoResult - Soporta la sintaxis defer para garantizar liberación de recursos o rollback de transacciones
Resultado de compilación transparente
- El código de Lisette se transforma en código Go claro y fácil de leer
- Los tipos
OptionyResultse convierten respectivamente en las estructuraslisette.Optionylisette.Result - La sintaxis
matchse transforma en condicionales de Go para manejar cada rama - El operador
?se sustituye internamente por código de verificación deResult
- Los tipos
- Como ejemplo, la función
classifyrecibeOption<int>y se transforma en condicionales explícitos de Go, mientras que la funcióncombinese convierte en código Go que verificaResult
Información adicional
- Repositorio oficial: github.com/ivov/lisette
- Publicado bajo licencia MIT, y desarrollado por Iván Ovejero a partir de 2026
1 comentarios
Comentarios en Hacker News
Hablé con el autor y, aunque no probé el lenguaje directamente, Lisette me parece interesante y claramente mejorado frente a Go
Aun así, creo que es difícil superar por completo las limitaciones de Go. Por ejemplo, el problema del
typed nilque viene de los tipos de interfaz de Go se maneja con Option en Lisette, pero el doble desempaquetado (Some(Some(h))) puede volverse incómodoAdemás, la forma en que Go maneja defer sigue siendo poco práctica y no permite liberación automática de recursos como RAII
TypeScript complementó a JavaScript porque no había una alternativa que pudiera ejecutarse en el navegador, pero ahora existe WASM, así que la situación es distinta
Por eso surge la duda de “si ya existe Rust, ¿por qué hacer que Go se parezca a Rust?”. Aun así, Lisette parece apuntar a un punto intermedio
Al final, Lisette parece adecuado para quienes quieren mejorar una base de código existente en Go o seguir usando el runtime de Go
Lo que me da curiosidad es la ausencia de una guía de inicio rápido que responda: “¿cómo empiezo a escribir este archivo en Lisette en lugar de Go?”
Artículo relacionado: Go is still not good
En dominios donde se manejan grafos de referencias complejos, el GC es esencial, y gracias a la estructura de stacks en modo usuario de Go, tiene un modelo de memoria eficiente
Go también sirve bien para crear este tipo de herramientas CLI rápidas — por ejemplo: wordle-tui
Tiene muchas ventajas: sintaxis simple, soporte multiplataforma, runtime y GC integrados, estructura de “errors as values”, green threads y un compilador AOT rápido
El
deferde Go es útil, pero el manejo de errores y las reglas de alcance se sienten incómodosTypeScript tampoco resolvió ese problema, y de hecho es peor. Por eso hice yo mismo un paquete de tipo Option y lo publiqué en NPM → fp-sdk
Ya existen varios lenguajes que compilan a Go — XGo, Borgo, Soppo, etc.
(T, error)por un tipo Result, pero semánticamente no son exactamente lo mismoPor ejemplo, en
io.Reader.Read,(n!=0, io.EOF)significa finalización normal, así que tratarlo simplemente como error causaría un comportamiento incorrectoLa calidad de los mensajes de error de Lisette es impresionante. Las pistas de “help” se sienten realmente útiles
Aun así, me preocupa que el código transformado a Go pueda volverse verboso, y que en errores de runtime haya que depurar en código Go
También parece difícil llamar a Lisette desde código Go existente
Me pregunto si Lisette es un lenguaje experimental o si realmente apunta a producción
lis run --debug, se insertan comentarios//line source.lis:21:5en el código Go para que los stack traces se mapeen al código original de LisetteEl LSP maneja los errores de compilación tomando como referencia los archivos
.lisPor ahora no existe la función de llamar a Lisette desde Go, pero la prioridad es permitir importar paquetes de Go desde Lisette
Al principio era un experimento, pero el objetivo es convertirlo en un lenguaje de nivel producción
Me pregunto por qué no adoptaron tal cual una sintaxis parecida a Rust
Por ejemplo:
import "foo.bar"en lugar deuse foo::bar,Bar.Baz =>en lugar deBar::Baz =>, etc.Quien conoce Rust puede confundirse, y quien no lo conoce no transfiere ese conocimiento a Rust
intyfloat64siguen las reglas de nombres de tipos de Go.en lugar de+El runtime de Go es bueno, pero el lenguaje en sí se siente tosco y sin intención de mejorar
Así que si alguien llega al punto de usar un transpiler, probablemente de verdad odia Go
Me pregunto por qué Rust y otros lenguajes de su familia separan struct y method
No entiendo por qué no se pueden definir métodos directamente dentro del struct
Además, los bloques
implpueden tener restricciones genéricas distintas de las del struct, por lo que se pueden definir variosPor último, Rust es un lenguaje diseñado para pensar alrededor de la forma (Shape) de los datos
implse parecen a los métodos de Go, y no diría que uno sea claramente mejor que el otroSi existiera un lenguaje con apariencia de Python pero que compilara a Rust o Go, sería realmente genial
Lisette parece un lenguaje que logra bien el equilibrio entre la simplicidad de Go y la complejidad de Rust
Me pregunto si hay alguna razón por la que la velocidad de compilación deba ser mucho más lenta que la de Go, y qué partes de Rust se excluyeron intencionalmente
Por ejemplo: borrow checking, tipos de datos, async, etc.
Go es un lenguaje fácil de aprender, pero le faltan funciones
Lisette parece un lenguaje interesante que llena esos vacíos
Así como TypeScript extendió JavaScript, agregar a Go un sistema de tipos expresivo y un compilador estricto podría convertirlo en un excelente lenguaje de backend
Mi sugerencia personal sería soportar compartición de tipos con frontends en TypeScript. Esa es una de las razones por las que TypeScript también es popular en backend
Como desarrollador de automatización de infraestructura que duda entre la seguridad de Rust y la simplicidad de Go, la idea de poner la usabilidad de Rust sobre el runtime de Go me parece muy atractiva
Voy a seguir de cerca la evolución del proyecto