10 pontos por GN⁺ 2024-12-29 | 3 comentários | Compartilhar no WhatsApp

#9512 - Rewrite It in Rust

  • O shell Fish foi reescrito em Rust. Não há nenhum código C++ e ele é composto quase 100% de Rust puro
  • Há cerca de 2 anos, foi aberto o PR (#9512) para migrar o Fish de C++ para Rust
  • O Fish já havia passado por uma transição de C para C++ no passado, mas a mudança para Rust foi um projeto muito maior

Problemas no C++

  • Diferenças de ferramentas e compiladores: as ferramentas de C++ não são boas, e adotar padrões modernos de C++ traz complexidade para mantenedores de pacotes e contribuidores.
  • Segurança de threads: a execução interna de comandos do Fish atualmente ocorre de forma serial, e adicionar prompt assíncrono ou conclusão não bloqueante exige processamento paralelo.
  • Complexidade da linguagem: arquivos de cabeçalho, templates e tratamento de strings em C++ são complexos e inseguros.
  • Comunidade: C++ não atrai muitos contribuidores.
  • Problemas de dependência: havia incômodo com a instabilidade e os problemas de build de certas bibliotecas C (curses).

Por que escolher Rust

  • Diversão e interesse: o Fish é um projeto de hobby, então precisava de uma linguagem divertida e interessante. Rust é mais atraente para contribuidores.
  • Ótimas ferramentas: é possível instalar o compilador facilmente com rustup, e as mensagens de erro são claras.
  • Ergonomia: oferece um sistema explícito de use e recursos seguros como Option e Result.
  • Bom design de linguagem: o sistema de ponteiros e opções do Rust é muito mais seguro que o do C++.
  • Suporte a paralelismo: Send e Sync do Rust permitem processamento paralelo com segurança.
  • Gerenciamento de dependências: é fácil adicionar suporte a formatos externos como YAML e JSON.

Suporte a plataformas

  • A maioria das principais plataformas (macOS, Linux, BSD etc.) é suportada, e suporte nativo ao Windows não é um objetivo
  • O Fish é um shell centrado em UNIX, focado em APIs UNIX e linguagens de script, mais do que no ambiente Windows

Processo de port

  • O Fish fez a transição gradual de C++ para Rust no estilo "o peixe de Theseus". Os componentes foram migrados um a um para Rust, configurando a coexistência entre C++ e Rust
    • Navio de Teseu (Ship of Theseus): “Se todas as tábuas de madeira de um navio forem substituídas por novas, ele ainda será o mesmo navio?”
  • Uso de FFI: foi usado autocxx para gerar bindings entre C++ e Rust, portando um componente por vez.
  • Port de grande escala: certas partes (como processamento de I/O) foram migradas de uma vez para reduzir código FFI complexo.
  • Melhoria de ferramentas: durante o port, o autocxx foi customizado para resolver problemas de interoperabilidade entre Rust e C++.

Linha do tempo

  • Janeiro de 2023: PR inicial aberto
  • Janeiro de 2024: código C++ completamente removido
  • Dezembro de 2024: lançamento da versão beta do Fish 4.0

Atritos com Rust

  • Problemas de portabilidade: a abordagem #[cfg(...)] do Rust é ineficiente para lidar com diferenças de sistema em baixo nível.
  • Localização: strings de formatação em Rust são verificadas em tempo de compilação, mas não podem ser traduzidas.
  • Tempo de build: usar LTO e o build de release padrão pode aumentar o tempo de compilação.
  • Alguns erros foram cometidos durante o port, mas a maioria foi resolvida com facilidade.

Principais resultados

  • Remoção de curses: o banco de dados terminfo foi substituído por um crate Rust, resolvendo estado global e problemas de build
  • Executável único: agora é possível gerar um binário do Fish com todas as dependências incluídas
    • Isso torna o pacote do Fish auto-instalável, facilitando o uso pelos usuários
  • Melhoria de desempenho: otimização do uso de memória e maior facilidade para adicionar novos recursos

Limitações

  • Não foi possível remover completamente o CMake
  • Suporte ao Cygwin foi descontinuado: não há target Rust para ele
  • No Windows, ainda só é possível executar via WSL

Presente e futuro

  • O Fish 4.0 foi portado com sucesso e teve melhorias de desempenho.
  • O Fish continua sendo um shell UNIX, e a transição para Rust abriu espaço para adicionar novos recursos.
  • Agora ele tem uma base de código totalmente migrada para Rust, mais fácil de manter e expandir do que antes. Será possível adicionar novos recursos aproveitando as vantagens do Rust
  • Essa transição foi concluída com sucesso e teve impacto positivo tanto para contribuidores quanto para usuários

3 comentários

 
annyeong 2024-12-30

Invejo a usabilidade do fish, mas por causa de problemas como compatibilidade e desempenho, venho configurando o zsh para ficar o mais parecido possível com o fish. Estou curioso para ver como ficou o fish depois das mudanças 👀

 
GN⁺ 2024-12-29
Comentários no Hacker News
  • Parabéns à equipe do Fish, e os detalhes do projeto são interessantes. Fico curioso se este é o maior projeto a fazer uma migração completa de C++ para Rust. Pode trazer lições úteis para outros projetos

    • O Fish não foi lançado como um programa híbrido de C++ e Rust. Isso porque a etapa final de testes não havia sido concluída
    • Há quem não entenda a motivação para adicionar recursos de C++ ao Rust, mas isso pode se tornar um bom estudo de caso
    • Há opiniões de que seria bom poder escrever novo código Rust em uma base de código C++
  • A principal reclamação sobre Rust é o suporte à detecção por versão. A detecção por funcionalidade é melhor para distribuições, navegadores web e compiladores

    • Detecção por versão/nome é o motivo de Chrome e IE fingirem ser Mozilla, e de Clang fingir ser GCC. A detecção por funcionalidade não causa esses problemas
  • Um dos objetivos da migração era remover o CMake, mas isso falhou. O Cargo é excelente para build, mas é simples demais para instalação. O Fish tem muitos scripts e documentação, então não se encaixa bem no caso de uso do Cargo

    • Preferem que outra ferramenta seja implementada, em vez de expandir o Cargo para esse caso de uso
  • Alguns anos atrás, quando migrei de bash para zsh, fiquei satisfeito, mas ao experimentar o fish em um computador novo, o zsh passou a parecer incômodo e ultrapassado. Recomendo usar o fish por algumas semanas

  • É uma pena que não haja suporte ao Cygwin. Espero que Rust passe a oferecer suporte ao Cygwin como alvo de build

  • Impressiona o esforço da equipe do Fish, e há expectativa para ver como o projeto vai evoluir

  • Fico curioso sobre quão fácil será para os mantenedores de pacotes empacotar o Rust-fish seguindo as diretrizes do Debian

  • Parabéns à equipe do Fish, a opinião é que o melhor shell ficou ainda melhor. Sugerem atualizar o tagline do projeto para "Finally, a shell for the 00s!"

  • Depois de mudar de zsh para Fish, a configuração ficou mais simples, e como o Fish funciona como esperado, não há intenção de mudar de novo

  • O macro cfg! é compilado para true/false, então o código dentro de um guarda if precisa ser compilado. Se compilar sem my_feature, isso pode falhar

  • O Fish usa threads para autocompletar e destacar sintaxe, e existe um projeto de longo prazo para adicionar concorrência à linguagem