2 pontos por GN⁺ 2023-08-20 | 1 comentários | Compartilhar no WhatsApp
  • À medida que o WebAssembly ganha importância na nuvem e na computação de borda, o Moonbit mira ser uma linguagem Wasm-first que facilita aproveitar a eficiência, a segurança e o tamanho reduzido do Wasm
  • Moonbit mira as limitações de Rust e C/C++, cuja dificuldade de aprendizado e longos tempos de compilação pesam, e de Go, cujo código gerado é grande e ineficiente
  • O foco do design está em builds e execução rápidos, saída Wasm pequena e facilidade de uso, incluindo otimização com múltiplas representações intermediárias, análise semântica paralela por função e reanálise incremental
  • No exemplo de Fibonacci, destaca inferência de tipos para funções locais, a menor saída Wasm, desempenho mais rápido que Go e semelhante ao Rust, além de suporte a closures recursivas e exhaustive pattern match
  • Atualmente oferece IDE online, ferramentas CLI, documentação e extensão para VSCode, com objetivo de alcançar beta status no fim do 2º trimestre de 2024 e abrir o código-fonte após atingir qualidade beta

Objetivo de uma linguagem que prioriza WebAssembly

  • WebAssembly é uma arquitetura de conjunto de instruções multiplataforma e vem ganhando importância na nuvem e na computação de borda por suas características de eficiência, segurança, tamanho reduzido e padrão aberto
  • A visão é que as opções existentes não aproveitam plenamente o potencial do Wasm
    • Linguagens Wasm de baixo nível, como Rust e C/C++, são difíceis de aprender, e seus longos tempos de compilação podem desacelerar o desenvolvimento
    • Linguagens de alto nível como Go geram código ineficiente e grande, dificultando aproveitar as vantagens de velocidade e tamanho reduzido do Wasm
  • Moonbit busca ser uma linguagem Wasm-first que compila e executa rapidamente, gera uma saída Wasm pequena e é fácil de aprender como Go

Design da linguagem e equipe

  • Moonbit é liderado por Hongbo Zhang e por uma equipe com mais de 10 anos de experiência em design e desenvolvimento de linguagens
  • Zhang contribuiu para OCaml, ReScript e Flow, e foi chief architect do compilador rápido, da biblioteca padrão e do sistema de build do toolchain do ReScript
  • O design da linguagem é influenciado tanto por Go quanto por Rust
    • Adota a simplicidade de Go, especialmente o sistema de pacotes
    • Inclui a expressividade de Rust, pattern matching, inferência de tipos, genéricos e ad-hoc polymorphism semelhante a traits
  • O sistema de tipos fault tolerant foi projetado levando em conta velocidade, possibilidade de paralelização e verificação incremental, tendo suporte a IDE como objetivo central

Builds e execução rápidos

  • Moonbit mira ser uma linguagem rápida em toda a stack, incluindo tanto desempenho de desenvolvimento quanto desempenho em runtime
  • Usa representações intermediárias (IR) em múltiplos níveis para otimização de programa inteiro
    • Segue uma abordagem de melhorar o layout de memória para reduzir cache misses
    • Fornece melhor contexto para análise de fluxo de dados e de controle
    • Considera que compreende a estrutura do programa de forma mais abrangente do que a maioria das arquiteturas existentes de link-time optimization, permitindo otimizações eficazes
    • Consegue encontrar e remover redundâncias de alto nível que não são visíveis em níveis mais baixos
  • Para desempenho de build rápido, importante para recursos de IDE, permite análise semântica paralela por função
    • Diferentemente de ReScript e Rust, permite semantic analysis paralela por função
    • Afirma poder executar reanálise incremental na mesma granularidade para lidar com grandes monorepos e oferecer tempos de resposta na casa dos milissegundos

Saída Wasm pequena

  • Moonbit foi projetado tendo em mente dead code elimination eficaz
  • Exclui recursos da linguagem que dificultam essa análise, e a biblioteca padrão também é estruturada para facilitar a eliminação de código morto
  • Busca reduzir significativamente o tamanho final do código por meio de otimização de programa inteiro
    • Considera que a redução no tamanho do código leva a melhor segurança e menor superfície de vulnerabilidades
    • Afirma garantir inicialização rápida em ambientes de computação serverless

Recursos e ferramentas para usabilidade

  • Moonbit oferece gerenciamento automático de memória, diferenciando-se de Rust
  • Afirma evitar elementos perigosos como ponteiros ou left value, ao contrário de Go
  • Oferece recursos seguros para programação orientada a dados
    • algebraic data types
    • ad-hoc polymorphisms
    • pattern match
  • Também tem como objetivo atuar como plataforma além de linguagem, oferecendo um conjunto de ferramentas mesmo em estágio inicial
    • ferramenta de build rápida
    • gerenciador de pacotes
    • compilador
    • IDE
    • Cloud IDE sem contêiner, acessível de qualquer lugar apenas com um navegador
    • Essa Cloud IDE também oferece recursos offline e, segundo eles, se diferencia das Cloud IDEs existentes

Diferenças vistas pelo exemplo de Fibonacci

  • O exemplo de Fibonacci compara a implementação da função fib em três linguagens: MoonBit, Go e Rust
  • Segundo o benchmark, MoonBit mostra diferenças em inferência de tipos, tamanho do código, desempenho e usabilidade
    • Inferência de tipos local: MoonBit infere o tipo da função local aux
    • Tamanho Wasm pequeno: MoonBit gera a menor saída Wasm
    • Desempenho: é mais rápido que Go e semelhante ao Rust
    • Usabilidade: oferece suporte a closures recursivas como Go, algo que seria muito difícil de implementar em Rust
    • Oferece suporte a exhaustive pattern match como Rust, sendo considerado muito mais poderoso que o switch case de Go

Estado atual e roadmap

  • Moonbit é um alvo em rápida evolução, mas atualmente oferece pontos de entrada utilizáveis
  • O desenvolvimento de toolchains de linguagem antes levava de vários anos até 10 anos, mas a experiência acumulada e uma equipe dedicada formada desde o início teriam simplificado o desenvolvimento
  • Espera-se alcançar beta status até o fim do 2º trimestre de 2024
    • beta status significa estabilidade relativa, poucos bugs e uma FFI robusta para interagir com hosts Wasm
  • O código-fonte deve ser aberto depois que atingir qualidade beta
  • Os planos estratégicos incluem integração com Wasm GC para Wasm 2.0 e um GC próprio para Wasm 1.0, alinhados às Wasm proposals

Canais da comunidade

1 comentários

 
GN⁺ 2023-08-20
Opiniões no Hacker News
  • Sou o líder deste projeto. Dá para experimentar agora mesmo no IDE online https://try.moonbitlang.com e executar com F5
    A documentação está em https://github.com/moonbitlang/moonbit-docs, e o compilador será aberto ao público quando chegar ao estado beta. A previsão é o fim do 2º trimestre de 2024

    • Estas são as perguntas que verifico primeiro ao ver uma nova linguagem de programação: como se escreve código assíncrono, se há recursos menos mainstream como efeitos algébricos (algebraic effects), contextos/capacidades (contexts/capabilities) e tipos lineares (linear types), se o sistema de tipos é sólido e se exige type casts, se oferece suporte a interfaces/traits/protocolos e quão ricos são os generics
      Por exemplo, quero verificar se há anotações explícitas de variância em parâmetros de tipo, restrições de limite inferior/superior, tipos de ordem superior (higher-kinded types), se o foco está mais em subtipagem estrutural ou nominal, e se há tipos de dados algébricos e tipos de dados algébricos generalizados
      Referências: https://v2.ocaml.org/manual/effects.html, https://docs.hhvm.com/hack/contexts-and-capabilities/introdu..., https://austral-lang.org/linear-types
    • Acho que muita gente vai querer saber sobre licença, preço e controle do projeto. Divulgar isso agora pode ser desfavorável para a estratégia comercial, mas sigilo e incerteza podem esfriar o interesse
    • A documentação em https://moonbitlang.com/docs/syntax/ é difícil de ler por causa da cor do texto e da cor de fundo
    • Fico me perguntando se uma palavra-chave dedicada fn é mesmo necessária. Não sei qual é a diferença fundamental entre func e fn
    • Fico me perguntando se é preciso distinguir func de fn, e se a seta -> para indicar o retorno em assinaturas de função é mesmo necessária
      A sintaxe de novo tipo é struct User, mas, nesse caso, acho que type User struct, como em Go, seria melhor. Assim também daria para criar tipos de função para variáveis fn, como type AssignUser func(name: String, id: Int) -> Int
      Também me pergunto se : ajuda o lexer ou o parser. Gostaria de perguntar se não seria possível escrever func(name String) em vez de func(name: String) em assinaturas de função, e se declarações de tipo poderiam ser mut elems List[int] em vez de mut elems: List[Int]. É uma implicância pequena, mas, no geral, gostei
  • O site compara com Rust e Go, mas, para mim, a comparação com AssemblyScript parece fazer mais sentido. AssemblyScript também é nativo para WASM, e é parecido no fato de o ecossistema ainda ser pequeno
    Só que, ao contrário de Moonbit, é uma linguagem familiar para quem já usou TypeScript, então fico curioso sobre por que usar Moonbit em vez de AssemblyScript

    • Porque Moonbit é uma linguagem moderna, enquanto AssemblyScript herda erros do passado. Por exemplo, Moonbit oferece suporte a pattern matching e a maioria dos elementos da linguagem é expressão
      AssemblyScript não tem pattern matching e é composto principalmente por statements. Moonbit tem tipos de dados algébricos; não sei bem se AssemblyScript tem algo assim. Pode haver outras diferenças de runtime, mas, olhando só o site, é difícil julgar
    • Parece muito mais próximo de Grain do que de AssemblyScript: https://grain-lang.org/
    • Acho que a comparação com Rust e Go acontece porque ambos são populares e têm suporte a WASM de primeira classe, mas concordo que deveria ser comparado com AssemblyScript
  • Usar a palavra-chave func para definições de funções no nível superior e fn para definições de funções aninhadas não é bom. Independentemente do contexto específico, deveriam padronizar em uma das duas

    • Talvez seja porque funções aninhadas são closures. Diferentemente de declarações no nível superior, elas podem omitir nome e tipo e capturar valores, então não é raro linguagens terem uma sintaxe separada para closures/lambdas
      Se isso é realmente necessário ou uma boa escolha de design é outra questão, mas há muitos precedentes
    • Vejo como um design elegante, pois permite definições de função mais curtas e legíveis para funções aninhadas. fn permite omitir nome e tipo, e a palavra-chave curta mostra que a própria definição da função também pode ficar mais curta
  • Estou animado com o surgimento de uma linguagem moderna com garbage collection voltada para WASM. A comparação mais próxima provavelmente é Grain: https://grain-lang.org/

    • Dizem que o compilador do Grain foi escrito em ReasonML, não em OCaml puro. Acho meio cômico ver essas tecnologias de nicho se empilhando sem cerimônia
  • “O desenvolvimento de um toolchain de linguagem completo costumava levar de vários anos até uma década, mas foi simplificado graças à experiência acumulada e a uma equipe dedicada e excelente formada desde o início do Moonbit. Espera-se que o Moonbit chegue ao status beta até o fim do 2º trimestre de 2024, o que significa uma etapa relativamente estável, com poucos bugs e uma FFI robusta para interagir com hosts Wasm. Ao atingir qualidade beta, o código-fonte será aberto. Estrategicamente, em linha com as propostas do Wasm, estão planejadas a integração do Wasm GC para Wasm 2.0 e um GC próprio para Wasm 1.0”, diz o texto
    Por isso, por enquanto, https://github.com/moonbitlang/ está vazio

  • Pelos comentários aqui, parece que o Moonbit tem coleta de lixo. Mas, se o binário do resultado de Fibonacci tem 253 bytes, provavelmente o GC não está incluído
    Fico curioso para saber se ele usa o GC nativo proposto para WASM, ou se o sistema de build é inteligente o bastante para perceber que o GC não é necessário aqui e removê-lo

    • Ao clicar com o botão direito no arquivo e escolher o penúltimo menu, Compile to Wat, dá para ver diretamente o texto WASM
      Na saída do exemplo de Fibonacci aparecem apenas a importação print_i32, definições de memória e funções, e a exportação de _start; não parece haver um runtime de GC anexado
    • Provavelmente ele omite isso de forma inteligente. Afinal, tamanho de código é um dos objetivos deles
  • Lembra o Grain. Como é outra linguagem de programação com Wasm em primeiro lugar, seria bom adicionar o Grain como referência de comparação
    https://grain-lang.org/

  • O link About Team leva a uma página edu.cn em chinês. Parece um projeto universitário, mas não tenho certeza. A página Join Us também está em chinês, e o exemplo da página inicial parece exigir JavaScript do baidu.com

    • Mesmo com o plugin umatrix ativado, a demo ainda funciona. Os scripts necessários vêm de unpkg e msecnd(domínio da Microsoft), e o Baidu não é necessário
  • Em Go, Fibonacci não seria implementado assim

    • Não gosto de Go, mas é preciso reconhecer que esse benchmark não faz sentido. Se você usa chamadas de cauda em uma linguagem que não oferece otimização de chamada de cauda, é claro que o resultado será ruim
      Parece que foi mais fácil jogar alguns números ali do que comparar implementações idiomáticas e discutir os trade-offs em detalhes. Mesmo sendo só um teaser simples da linguagem, seria bom incluir uma observação sobre TCO para não induzir as pessoas ao erro
    • Usar WASM e Go em um exemplo forçado e não mencionar TinyGo não parece muito honesto
    • Em Rust também não se implementaria assim. É um benchmark bem ruim. Pela minha experiência, a causa provavelmente é a ausência de recursão de cauda e a instrução switch, que em Go pode ser lenta
      Ainda assim, como teaser para apresentar o Moonbit, está ok
  • Fico curioso se este projeto tem relação com a Meta. Hongbo Zhang, o criador, trabalhou na Meta em projetos open source de linguagens de programação como ReasonML e Flow e, segundo o LinkedIn, ainda trabalha na Meta