17 pontos por xguru 2022-11-04 | 4 comentários | Compartilhar no WhatsApp
Publicidade
  • O repositório Android da Meta é um enorme monorepo que inclui Facebook, Instagram, Messenger, Quest e outros
  • Atualmente, ele já contém mais de 10 milhões de linhas de código em Kotlin

Por que migrar para Kotlin

  • Além da popularidade, havia vantagens importantes
    • Nullability: NPE era um problema comum na Meta, então várias medidas foram tomadas, mas o tratamento nativo de nullability do Kotlin é muito mais robusto e fácil de usar
    • Programação funcional: as funções inline e expressões lambda do Kotlin permitem aplicar um estilo de FP sem perda de desempenho em tempo de execução
    • Código mais curto
    • DSL / Type-safe Builder
  • Claro, também havia algumas desvantagens que não podiam ser ignoradas
    • Introduzir outra linguagem significa manter por bastante tempo uma base de código mista
    • Embora Kotlin seja popular, ainda existe uma diferença em relação ao Java nesse aspecto. Por isso há menos ferramentas, e muitas ferramentas de Kotlin precisam considerar a interoperabilidade entre Kotlin e Java, o que torna a implementação mais complexa
  • A maior preocupação era o tempo de build. Desde o início, já se sabia que o tempo de build do Kotlin poderia ser mais lento que o do Java. Builds lentos prejudicam a experiência do desenvolvedor
Publicidade

Como abordaram a migração

  • A migração para Kotlin foi surpreendentemente simples e, ao mesmo tempo, muito complexa
  • Havia o J2K (Java To Kotlin Converter), o que ajudava, mas ainda assim era complexo
    • O J2K nem sempre é preciso, e a interoperabilidade entre Java e Kotlin cria alguns casos extremos
  • Havia duas opções para a migração
    • Escrever apenas o código novo em Kotlin e manter a maior parte do código em Java
      • A vantagem é dar menos trabalho, mas o uso misto das duas linguagens faz com que o Kotlin use platform types, o que pode gerar null pointer dereference e causar crashes.
        Além disso, também havia problemas como o fato de não ser possível marcar parâmetros de tipo como Nullable em Java (até recentemente), e o fato de as regras de overload do Kotlin considerarem se null é permitido, enquanto as regras de overload do Java não consideram isso
    • Tentar converter todo o código interno para Kotlin

Como fizeram a migração

  • Consideraram as duas opções e decidiram ter como meta converter todo o código para Kotlin
    • No começo foi um pouco lento, mas depois de resolver alguns blockers, tornou-se possível converter em grande escala
    • Hoje, cada um dos apps Android do Facebook, Messenger e Instagram contém 1 milhão de linhas de código em Kotlin, e a taxa de conversão continua aumentando gradualmente
    • Atualmente, toda a base de código Android tem 10 milhões de linhas de código em Kotlin

Unblocking

  • Alguns problemas surgiram logo no início da conversão
    • Foi necessário atualizar o Redex por causa de padrões de bytecode
    • Algumas bibliotecas internas faziam transformação de bytecode por questões de desempenho, e isso não funcionava com Kotlin
    • Se houver muitas otimizações internas, problemas parecidos podem surgir
  • Também apareceram problemas nas ferramentas existentes
    • Como não havia syntax highlighting de Kotlin em code review/wiki etc., o Pygments foi atualizado
    • O Ktfmt, formatador de Kotlin, foi desenvolvido separadamente

Acelerando a migração

  • As ferramentas já estavam prontas, então o código podia ser convertido para Kotlin
  • Mas cada migração ainda exigia muito código boilerplate feito manualmente
  • O J2K é uma ferramenta genérica, então não entende o código em si. Por isso, muito trabalho manual ainda era necessário
    • Por exemplo, regras de teste do JUnit
  • Então o J2K foi colocado no meio de um pipeline de 3 etapas
    • Primeiro, pegavam um pacote Java e o preparavam para a conversão para Kotlin. Isso incluía correções de bugs e conversões necessárias para ferramentas internas
    • Depois, executavam automaticamente o J2K por script
    • Por fim, faziam o pós-processamento dos novos arquivos Kotlin. Essa era a etapa mais importante. Refatorações automáticas/linters etc. eram executados em modo headless
  • A automação não resolve todos os problemas, mas os casos mais comuns foram priorizados

O que aprenderam com a migração para Kotlin

  • O código ficou mais curto
  • O desempenho de execução foi mantido
  • O tamanho do build não foi um problema
  • O problema do aumento no tempo de build foi resolvido com KSP (Kotlin Symbol Processing API)
Publicidade

4 comentários

 
sungeuns 2022-11-04

Obrigado por compartilhar este ótimo texto. Pessoalmente, quando comecei a usar Kotlin, gostei porque ele tinha muitos pontos mais convenientes do que Java, e cheguei a pensar que, daqui para frente, Kotlin se tornaria o padrão. Mas, depois de usar por um tempo, percebi que ainda há muitos aspectos em que Java parece melhor.

  • Acho que, como linguagem em si, Kotlin é definitivamente mais conveniente
  • Comparado ao ecossistema do Java e à grande quantidade de material para troubleshooting, Kotlin ainda tem algumas carências.
  • Dependendo da versão do JDK ou do Kotlin, há vários bugs e problemas que você não enfrentaria se usasse apenas Java.
    Acho que no Android tudo bem migrar para Kotlin, mas em outros ambientes (como Spring...) , se a estabilidade for importante, Java ainda parece ser a melhor escolha.
 
roxie 2022-11-05

Você poderia compartilhar apenas um exemplo de estabilidade? Ainda tenho pouca experiência, então ainda não me deparei com casos assim e estou muito curioso.

 
ganadist 2022-11-06

Talvez porque a JetBrains esteja soltando releases sem parar, mas, surpreendentemente, há muitas correções de bugs do compilador.
https://github.com/JetBrains/kotlin/releases/tag/v1.7.20

Também acontece com certa frequência de o próprio compilador quebrar (isso, pelo menos, ainda é antes da distribuição, então tudo bem), e às vezes os artefatos gerados também incluem bugs.

Além disso, no caso do Android, o otimizador de bytecode R8 também depende da versão do Kotlin.
Isso porque existe uma funcionalidade de otimização exclusiva para código Kotlin, mas não há uma documentação oficial com uma tabela de compatibilidade para isso (Android Gradle Plugin : Kotlin Version)..
Por isso, é preciso ter cuidado ao mudar a versão do Kotlin em projetos Android;;;

Relatório de bug relacionado: https://issuetracker.google.com/issues/207397158

 
roxie 2022-11-06

Obrigado. Existe um mundo profundo e vasto, hein..