1 pontos por GN⁺ 2025-10-17 | 1 comentários | Compartilhar no WhatsApp
  • A versão Elixir 1.19 permite detectar mais bugs com mais rapidez por meio do fortalecimento do sistema de tipos e de melhorias no desempenho de compilação
  • A inferência de tipos foi expandida para funções anônimas e protocolos, permitindo uma validação automática mais ampla mesmo sem anotações de tipo do usuário
  • Em projetos grandes, oferece velocidade de compilação até 4 vezes maior, incluindo compilação paralela e otimização do carregamento de código
  • Também foram reforçados o ecossistema e a transparência da cadeia de suprimentos, com suporte ao Erlang/OTP 28 e adoção da certificação OpenChain
  • Além disso, inclui vários recursos como melhorias no parsing de opções, mais capacidades de depuração no ExUnit e melhor acessibilidade à documentação baseada em shell

Principais melhorias do Elixir 1.19

Melhorias no sistema de tipos

Inferência de tipos em todos os componentes

  • Type inference (inferência de tipos) é um recurso que determina automaticamente o tipo de expressões em tempo de compilação
  • Antes, a ideia era oferecer suporte à inferência de tipos principalmente em padrões, guards e valores de retorno, mas nesta release foi introduzida a inferência de tipos para todos os componentes (exceto guards)
  • Como a inferência considera também chamadas a funções dentro do módulo e funções da biblioteca padrão do Elixir, funções que antes eram inferidas como dynamic() -> boolean() agora podem ser inferidas de forma mais precisa, como integer() -> boolean()
  • A inferência de tipos envolve vários trade-offs, como velocidade de compilação, expressividade, compilação incremental e clareza de erros; no futuro, também deverá incluir inferência de tipos em guards e informações de tipos de dependências
  • Quando uma assinatura de tipo é explicitamente declarada em uma função, isso passa a funcionar como verificação de tipo explícita, e não inferência, permitindo apenas os tipos compatíveis com a anotação do usuário

Verificação de tipos em despacho e implementação de protocolos

  • O Elixir agora aplica verificação de tipos em chamadas e implementações de protocolos
  • Por exemplo, ao passar para interpolação de string um tipo que não implementa o protocolo String.Chars, o compilador emite uma mensagem de aviso
  • Em comprehensions for, também é emitido um aviso ao passar como gerador um tipo que não satisfaz o protocolo Enumerable
  • Essas verificações de tipo ajudam a evitar mais bugs em tempo de compilação

Inferência e verificação de tipos para funções anônimas

  • O Elixir 1.19 oferece suporte a inferência de tipos e verificação de tipos para funções anônimas
  • Por exemplo, se uma função anônima espera um tipo %{} e recebe um tipo incorreto como "hello", isso pode ser detectado imediatamente como aviso em tempo de compilação
  • A inferência de tipos também se aplica a function captures (&String.to_integer/1 etc.), ampliando o alcance da validação automática de tipos

Referências e parceiros

  • Esse sistema de tipos foi desenvolvido em parceria entre a CNRS e a Remote
  • Fresha, *Starfish* *, Dashbit e outras apoiaram o projeto

Compilação mais rápida em projetos grandes

Melhoria no gargalo de carregamento de código

  • Antes, os módulos eram carregados imediatamente após a definição, mas nesta release isso mudou para uma estratégia de lazy loading (carregamento sob demanda)
  • Com isso, a carga sobre o code server foi reduzida e o desempenho da compilação paralela melhorou, aumentando em mais de 2 vezes a velocidade de compilação de projetos grandes
  • Dois pontos principais de atenção
    • Ao criar processos separados durante a compilação para acessar módulos do mesmo projeto, o carregamento pode não ocorrer; para contornar isso, use Kernel.ParallelCompiler.pmap/2 ou Code.ensure_compiled!/1
    • Ao chamar módulos do mesmo projeto dentro do callback @on_load, pode haver erro; se necessário, use a opção @compile {:autoload, true}
  • Em ambos os casos, antes podiam ocorrer erros de compilação não determinísticos, mas com essa melhoria passa a haver um ambiente de compilação determinístico (reproduzível)

Compilação paralela de dependências

  • Com a variável de ambiente MIX_OS_DEPS_COMPILE_PARTITION_COUNT, passou a haver suporte à compilação paralela de dependências
  • Como múltiplos processos do sistema operacional são usados ao mesmo tempo para compilar dependências em paralelo, o desempenho de compilação pode melhorar em até 4 vezes, dependendo do tamanho do projeto e do número de núcleos da CPU
  • Experimentalmente, definir um valor em torno de metade do total de núcleos tende a ser eficaz para o uso de recursos
  • Como a paralelização pode aumentar o uso de memória, é preciso cautela ao aplicá-la em CI ou servidores de build

Suporte ao Erlang/OTP 28

  • O Elixir 1.19 oferece suporte oficial ao Erlang/OTP 28.1+
  • Devido a mudanças na representação de expressões regulares no Erlang/OTP 28, não é mais possível usar expressões regulares como valor padrão de structs
  • Na inicialização de structs, ainda é possível usar expressões regulares

Adoção da certificação OpenChain

  • Esta release é a primeira versão a iniciar a conformidade com o padrão OpenChain
  • Cada release inclui um SBoM (Source Bill of Materials) nos formatos CycloneDX 1.6/SPDX 2.3
  • Isso aumenta a transparência da cadeia de suprimentos em relação aos componentes e licenças da release, contribuindo para um controle mais rigoroso
  • Esse trabalho foi realizado por Jonatan Männchen, com apoio da Erlang Ecosystem Foundation

Outras melhorias

  • Foram adicionadas diversas melhorias em ferramentas e bibliotecas, incluindo parsing de opções, depuração e desempenho do ExUnit, e acessibilidade à documentação baseada em shell
  • Para notas de release mais detalhadas, consulte o CHANGELOG

1 comentários

 
GN⁺ 2025-10-17
Opiniões do Hacker News
  • Destaca que a forma como o Elixir está introduzindo gradualmente a verificação automática de tipos é um excelente exemplo de evolução de linguagem do qual outras linguagens de programação também poderiam aprender; há muitos casos em que mudanças grandes dividiram o ecossistema em dois, e é reconfortante que José tenha deixado claro desde 2018 que a linguagem em si já estava concluída; como a linguagem e o core não vão mais quebrar, isso transmite muita estabilidade; recomenda a palestra relacionada; ficou impressionado com a condução consistente e excelente

    • Os únicos casos de divisão de ecossistema por grandes mudanças em linguagens principais que lhe vêm à mente são Python 3 e Perl 6; como as mudanças nesses dois casos foram tão impactantes, isso faz com que outras mudanças em linguagens pareçam gigantes também
    • No Elixir, nunca há aquela sensação de estar sempre correndo atrás de upgrades de versão; você vai acompanhando as mudanças introduzidas e acaba querendo atualizar por causa de novos recursos úteis, sem a ansiedade ou o estresse de quando parecem estar te forçando a trocar de versão
    • Usa Elixir em produção desde 2017, e cada upgrade acabou sendo muito mais tranquilo do que esperava; na verdade, upgrades de Erlang/OTP muitas vezes foram mais complicados por questões de compatibilidade, então geralmente usa a versão mais recente do Elixir, mas espera mais um ou dois meses antes de atualizar o OTP, até que possíveis conflitos sejam resolvidos
    • O Elixir ainda deixa a desejar em alguns pontos e carece de conveniência, então precisa de orientações mais claras para alcançar certos objetivos e de maior estabilização do ecossistema; muitos pacotes estão abandonados ou têm documentação insuficiente, o que dificulta acompanhar o ritmo das mudanças no ecossistema Phoenix; também há muitos usuários que não querem LiveViews nem certos sistemas de componentes, e a barreira de entrada para compatibilidade com outras ferramentas e tecnologias é alta; no caso do Python 3, a transição do 2 para o 3 era realmente necessária e foi relativamente bem-sucedida graças a ferramentas automatizadas de migração, embora com muitos percalços; já no Ruby 3, a introdução de arquivos de tipos externos e a fragmentação das ferramentas acabou gerando mais confusão, somando-se a boilerplate, problemas de governança e até sequestro de gems, o que levou a uma experiência negativa e ao afastamento do Ruby; enfatiza que mesmo uma linguagem excelente pode ser arruinada por uma condução imatura, por isso cooperação madura, comunicação e boa gestão de mudanças são essenciais; acredita que mudanças no design da linguagem exigem experimentação prévia suficiente, cautela e comunicação antecipada com os usuários para minimizar confusão desnecessária; espera que Elixir/Phoenix/OTP se tornem ainda mais fáceis, poderosos, produtivos e performáticos, para que usuários variados possam adotá-los com confiança; recomenda recursos como Livebook e a trilha de Elixir no Exercism
  • O Elixir continua evoluindo de forma estável, lançando ótimos recursos e melhorias de forma consistente; a estrutura da linguagem é excelente e seus criadores continuam apontando na direção certa, o que é realmente impressionante; a única pena é não ter oportunidades de usar Elixir no dia a dia

    • Quis tanto usar Elixir que até saiu do emprego para abrir a própria empresa
  • Compartilha dados experimentais sobre a velocidade de compilação de dependências do Phoenix; em um app pequeno contendo apenas as dependências padrão do Phoenix, em um Mac M1 Max, os seguintes tempos de compilação foram medidos conforme o valor da variável de ambiente MIX_OS_DEPS_COMPILE_PARTITION_COUNT

    PARTITION_COUNT=1:  12.336초 (유저 32.30s, 시스템 7.23s, CPU 320%)
    PARTITION_COUNT=5:  6.970초 (유저 0.37s, 시스템 0.49s, CPU 12%)
    PARTITION_COUNT=10: 7.236초 (유저 0.38s, 시스템 0.50s, CPU 12%)
    

    O cache foi apagado entre cada teste com o comando rm -rf _build

    • Depois disso, parece que as execuções foram medidas já com cache aplicado; talvez a compilação nativa tenha ocorrido diretamente na pasta dep, sem deixar rastros em _build
    • Não entende por que os resultados de benchmark sobre esse recurso desta release estão recebendo downvotes, e pergunta se alguém poderia explicar nos comentários
  • Nos últimos meses passou a gostar muito de Gleam; também ficou feliz com a introdução do sistema de tipos no Elixir, mas antes isso era um dos principais fatores que dificultavam sua adoção do Elixir; gostaria de dar outra chance ao Elixir algum dia, mas teme que acabe sendo algo como o TypeScript no JavaScript, tipado só na aparência, enquanto muitas libs e pacotes continuam basicamente dinâmicos/any; pergunta se essa preocupação faz sentido ou não; o BEAM é realmente fantástico

    • O contexto é diferente do TypeScript; graças ao pattern matching, mesmo bases de código Elixir já existentes provavelmente permitem inferência de tipos em pelo menos uns 50%, e como o Elixir puro passa a oferecer tipos por padrão, o código que recebe manutenção deve se tipar rapidamente; pessoalmente não gosta de sistema de tipos e só usa JS, mas no Elixir a adoção de tipos parece natural; no TypeScript ela sobe de baixo para cima, enquanto no Elixir tende a se propagar naturalmente para baixo
    • O Gleam não consegue aproveitar perfeitamente os verdadeiros pontos fortes de OTP/BEAM; esse é um atrativo que só o Elixir oferece
    • O Elixir já tinha há muito tempo conceitos de tipos, como tipos primitivos, structs e destructuring baseado em shape, além de permitir verificação de tipos com ferramentas como Dialyzer e TypedStruct; não é uma linguagem absurdamente sem tipos como JavaScript
    • Gleam também é bom, mas no JVM existe o Kotlin, que é uma linguagem tipada com sintaxe semelhante à do Ruby e ainda pode fazer compile-to-JS
  • Elixir parece ser um dos ambientes mais promissores para desenvolvimento web; sempre que encontra organizações ou equipes que usam Elixir no trabalho real, tem a impressão de que o nível delas é acima da média; acha que, em ambientes onde desenvolvimento contínuo é necessário, o Elixir continua fornecendo direção e padrões

  • Apresenta que a release do Elixir passou a oferecer suporte a formatos de Source SBoM como CycloneDX 1.6+ e SPDX 2.3+; é muito valioso que a gestão de SBOM aconteça no nível da linguagem; infelizmente, a empresa atual não usa Elixir

  • Se alguém quiser contribuir para um projeto open source em Elixir usado de fato, um dos principais componentes do antigo Mozilla Hubs continua sendo desenvolvido em Elixir como projeto independente; veja Hubs Foundation/reticulum

  • Com base na biblioteca padrão do Elixir, é possível fazer inferência de tipos em tempo de compilação para situações específicas da aplicação, como converter tipos dinâmicos em booleanos ou inteiros em booleanos

  • Não tem experiência prática desenvolvendo em Elixir, mas é fã; antes gostava da praticidade e da beleza do Ruby, mas mudou de linguagem ao se interessar por sistemas de tipos; tanto Elixir quanto Ruby introduziram sistemas de tipos, mas hoje usa principalmente Kotlin, que sintaticamente parece um “Ruby tipado”

    • Kotlin é praticamente a sensação do jruby que a gente realmente queria
  • Está usando Soketi com o pusher sdk para lidar com broadcast de eventos; o app tem uma estrutura mista de endpoints em tempo real e endpoints REST, e a carga de processamento em tempo real não é tão alta, mas se necessário pensa em separar isso em Go; também pretende adicionar recursos de colaboração em breve, e está em dúvida se faz sentido adotar Phoenix nessa situação