3 pontos por GN⁺ 23 일 전 | 1 comentários | Compartilhar no WhatsApp
  • Linguagem pequena que usa sintaxe no estilo Rust e roda sobre o runtime de Go, combinando as vantagens das duas linguagens
  • Estrutura que reforça segurança e expressividade com tipos de dados algébricos, pattern matching, sistema de tipos Hindley-Milner e imutabilidade por padrão
  • Garante interoperabilidade com o ecossistema Go por meio de import direto de pacotes Go, operador de pipeline, blocos try e concorrência baseada em task
  • Melhora a experiência do desenvolvedor e a estabilidade do código com detecção de erros em tempo de compilação, mensagens de diagnóstico claras e suporte a LSP
  • O ponto central é que o código Lisette é transformado em código Go legível e fácil de entender, permitindo integração natural com projetos Go existentes

Visão geral do Lisette

  • Lisette é uma linguagem pequena baseada em sintaxe Rust que compila para o runtime de Go
  • Tem como características tipos de dados algébricos, pattern matching, ausência de nil, sistema de tipos Hindley-Milner, imutabilidade por padrão e interoperabilidade com o ecossistema Go
  • Pode ser instalada com o comando cargo install lisette, e permite importar e usar diretamente pacotes do Go como fmt, io e os

Sintaxe familiar

  • Possui uma estrutura de sintaxe semelhante à de Rust
    • Suporte a pattern matching com enum e match
    • Permite definir métodos com blocos struct e impl
  • É uma linguagem orientada a expressões, em que if, let e blocos retornam valores
  • Suporta encadeamento e lambdas, permitindo expressar de forma concisa o tratamento de variáveis de ambiente ou manipulação de strings
  • Suporta interfaces e genéricos, permitindo definir interface e escrever funções genéricas com restrições T: Trait
  • Permite tratar o tipo Option de forma concisa com as sintaxes if let e let else

Segurança

  • Detecta em tempo de compilação erros que poderiam ocorrer no runtime de Go

    • Gera erro se nem todos os padrões forem tratados em uma instrução match
    • Não permite uso de nil; valores ausentes são representados com Option<T>
    • Gera aviso ao ignorar um valor de retorno Result
    • Gera aviso ao expor um tipo privado em uma API pública
    • Gera erro ao passar uma variável imutável como argumento mutável
    • Gera erro de compilação ao omitir campos de struct
    • As mensagens de diagnóstico fornecem localização exata no código e sugestões de correção
    • Com suporte a LSP (Language Server Protocol), pode ser usado em editores principais como VSCode, Neovim e Zed

Usabilidade

  • Projetada com foco em interoperabilidade com Go
  • O operador de pipeline (|>) permite expressar encadeamento de funções de forma concisa
  • Blocos try simplificam a propagação de erros
  • A concorrência é implementada com task e Channel, de forma semelhante às goroutines do Go
  • Atributos de serialização permitem definir nome de campo em JSON, omissão, conversão para string e tags de validação
  • Fornece blocos recover para recuperação de panic, permitindo tratamento seguro de erros com o tipo Result
  • Suporta a instrução defer, garantindo limpeza de recursos ou rollback de transações

Resultado de compilação transparente

  • O código Lisette é transformado em código Go claro e legível
    • Os tipos Option e Result são convertidos respectivamente para as structs lisette.Option e lisette.Result
    • A instrução match é convertida em condicionais de Go para tratar cada ramo
    • O operador ? é internamente substituído por código de verificação de Result
  • Como exemplo, a função classify recebe Option<int> e é convertida em condicionais explícitas em Go, enquanto a função combine é convertida em código Go que verifica Result

Informações adicionais

  • Repositório oficial: github.com/ivov/lisette
  • Disponível sob a licença MIT, e desenvolvido por Iván Ovejero em 2026

1 comentários

 
GN⁺ 23 일 전
Comentários no Hacker News
  • Conversei com o autor e, embora eu não tenha usado a linguagem diretamente, Lisette parece interessante e claramente melhorada em relação ao Go
    Ainda assim, acho difícil superar completamente as limitações do Go. Por exemplo, o problema de typed nil vindo dos tipos de interface do Go é tratado com Option no Lisette, mas o desembrulho duplo (Some(Some(h))) pode ficar estranho
    Além disso, a forma como o Go lida com defer continua sendo incômoda e não oferece liberação automática de recursos como RAII
    O motivo de o TypeScript ter complementado o JavaScript foi que não havia uma alternativa executável no navegador, mas agora existe WASM, então a situação é diferente
    Por isso, fica a dúvida: “se já existe Rust, por que tornar Go parecido com Rust?”. Ainda assim, Lisette parece mirar esse meio-termo
    No fim, Lisette parece ser apropriada para quem quer melhorar uma base de código Go existente ou continuar usando o runtime do Go
    O que sinto falta é de um guia de início rápido que responda: “como começar a escrever o arquivo a seguir em Lisette em vez de Go?”
    Post de blog relacionado: Go is still not good

    • O Go continua sendo único por oferecer um runtime de concorrência baseado em GC
      Em domínios que lidam com grafos de referência complexos, GC é essencial, e a estrutura de stacks em modo usuário do Go permite um modelo de memória eficiente
    • Em linguagens com GC, a velocidade de desenvolvimento é muito maior. Já fiz chatbots em Rust e Python, e mesmo tendo experiência com Rust, Python foi muito mais rápido
      O Go também é adequado para criar esse tipo de ferramenta CLI rápida — por exemplo: wordle-tui
    • O Go tem muitas esquisitices como linguagem, mas como alvo de compilação é excelente
      A sintaxe é simples, há suporte multiplataforma, runtime e GC embutidos, estrutura de “errors as values”, green threads, compilador AOT rápido e várias outras vantagens
      O defer do Go é útil, mas o tratamento de erros e as regras de escopo são estranhos
    • Foi marcante a expressão do blog de que “Go é uma linguagem que acidentalmente criou NULL duas vezes”
      O TypeScript também não resolveu esse problema e, na verdade, é ainda pior. Por isso, criei eu mesmo um pacote de tipo Option e publiquei no NPM → fp-sdk
    • O async do Rust é menos conveniente que o do Go por não ter GC. Só isso já é um motivo para escolher o runtime do Go
  • Já existem várias linguagens que compilam para Go — XGo, Borgo, Soppo, etc.

    • Borgo e Lisette apenas substituem o retorno (T, error) por um tipo Result, mas isso não é semanticamente idêntico
      Por exemplo, em io.Reader.Read, (n!=0, io.EOF) significa término normal, então tratá-lo simplesmente como erro leva a comportamento incorreto
    • Tenho curiosidade sobre como erros de compilação na linguagem-alvo são repassados para a linguagem-fonte
  • A qualidade das mensagens de erro do Lisette impressiona. As dicas de “help” parecem realmente úteis
    Ainda assim, me preocupa que o código convertido para Go possa ficar verboso e que, em caso de erro em runtime, seja preciso depurar no código Go
    Também parece difícil chamar Lisette a partir de código Go existente
    Fico curioso se Lisette é uma linguagem experimental ou se busca uso real em produção

    • O desenvolvedor respondeu diretamente: ao usar a opção lis run --debug, comentários //line source.lis:21:5 são inseridos no código Go, então o stack trace é mapeado para o código Lisette original
      O LSP lida com erros de compilação com base nos arquivos .lis
      No momento não existe recurso para chamar Lisette a partir de Go, mas a prioridade é o recurso de importar pacotes Go no Lisette
      Começou como experimento, mas o objetivo é evoluir para uma linguagem em nível de produção
  • Fico curioso sobre por que não adotaram diretamente a sintaxe parecida com Rust
    Ex.: import "foo.bar" em vez de use foo::bar, Bar.Baz => em vez de Bar::Baz =>, etc.
    Quem conhece Rust pode se confundir, e quem não conhece não transfere esse conhecimento depois para Rust

    • Essas diferenças de sintaxe são pequenas; o ponto central é trazer o sistema de tipos do Rust para o Go
      int e float64 seguem a convenção de nomenclatura de tipos do Go
    • Quando se alterna entre várias linguagens, a semelhança de sintaxe pode acabar gerando mais confusão. Por exemplo, no PHP eu vivo esquecendo que preciso usar . em vez de +
    • Eu também tentei inicialmente criar uma linguagem estilo Rust baseada em TypeScript, mas no fim percebi que o próprio Rust não é tão difícil quanto parece
    • Implementar um modelo de memória estilo Rust numa linguagem com GC é algo muito pouco natural. É como se cada objeto tivesse seu próprio espaço de endereçamento, o que complica bastante
    • Lisette é uma linguagem inspirada em Rust, não uma tentativa de se tornar Rust. O principal público-alvo são desenvolvedores Go
  • O runtime do Go é bom, mas a linguagem em si parece truncada e sem vontade de melhorar
    Então, se alguém chega ao ponto de usar um transpiler, provavelmente é porque realmente odeia Go

  • Tenho curiosidade sobre por que Rust e linguagens da família Rust separam struct e method
    Não entendo por que não se pode definir métodos diretamente dentro da struct

    • Em Rust, os campos da struct afetam os auto-traits, então é importante conseguir enxergar os campos de uma vez
      Além disso, blocos impl podem ter restrições genéricas diferentes das da struct, então é possível definir vários
      Por fim, Rust é uma linguagem projetada para pensar a partir da forma (Shape) dos dados
    • Pessoalmente, sinto que os blocos impl se parecem com os métodos do Go, e não vejo claramente um dos dois como melhor
  • Se existisse uma linguagem com cara de Python, mas que compilasse para Rust ou Go, isso seria realmente incrível

    • Mojo é uma linguagem de alto desempenho com sintaxe baseada em Python criada pelo criador do Swift
    • Spy é uma tentativa inicial que compila para C, e Nim também é uma linguagem madura de linha parecida
    • Nim tem sintaxe parecida com Python, um sistema de tipos estático e compila para vários alvos, como wasm e C
    • Static Python Skill é uma tentativa de compilar Python de forma estática
    • Grumpy era um transpiler de Python→Go criado pelo Google, mas não recebe atualizações há 9 anos (voltado ao Python 2.7)
  • Lisette parece uma linguagem que equilibra bem a simplicidade do Go com a complexidade do Rust
    Fico curioso se existe algum motivo para a compilação ser muito mais lenta que a do Go e quais partes dos recursos do Rust foram deixadas de fora de propósito
    Ex.: borrow checking, tipos de dados, async etc.

  • Go é fácil de aprender, mas é uma linguagem com poucos recursos
    Lisette parece interessante por ser uma linguagem que preenche essas lacunas
    Assim como o TypeScript expandiu o JavaScript, adicionar ao Go um sistema de tipos expressivo e um compilador rigoroso poderia torná-lo uma ótima linguagem de backend
    Minha sugestão pessoal seria oferecer suporte a compartilhamento de tipos com frontends em TypeScript. Esse é um dos motivos pelos quais TypeScript também é popular no backend

  • Como desenvolvedor de automação de infraestrutura dividido entre a segurança do Rust e a simplicidade do Go, acho muito atraente a ideia de colocar a usabilidade do Rust sobre o runtime do Go
    Vou continuar acompanhando a evolução do projeto