1/10: Dicas e truques para migração do Scala 3. Um 🧵. Importante e óbvio: leia atentamente o guia de migração e utilize o Scalafix para atualizações de sintaxe. Isso economizará hdocs.scala-lang.org/scala3/guides/…!
2/10: Não se apresse em substituir tudo pela nova sintaxe! Primeiro, compile seu código-base com a sintaxe antiga, mas usando o compilador Scala 3. A nova sintaxe tem suas próprias regras e pode causar erros confusos se você não estiver familiarizado, especialmente quando misturada com a sintaxe antiga.
3/10 Ao substituir parâmetros implícitos por `using`, lembre-se de que todas as passagens de parâmetros explícitas nos sites de chamada também precisam da palavra-chave `using`! getUserInfo(userId)(using Tracing.noop) // correto
4/10: Esquecer a palavra-chave `using` leva a erros enigmáticos. O compilador pode destacar uma parte completamente diferente do seu código, tornando a depuração frustrante. Eu realmente perdi muito tempo tentando descobrir o que estava acontecendo.
5/10: Aviso sobre circe: Ao migrar de derivação semiautomática como `deriveConfiguredCodec` para `Codec.derived`, tenha cuidado! `Decoder.derived` não aceita `Configuration` como parâmetro implícito — use `Decoder.derivedConfigured` em vez disso.
6/10: Você pode evitar completamente o problema do circe com a nova sintaxe derives: case class MyClass(...) derives ConfiguredCodec. Quase enviei um bug para o prod porque acreditava que Decoder.derived se comportaria da mesma forma. Graças a outro problema, consegui descobri-lo cedo o suficiente.
7/10: Usuários do Doobie: fiquem atentos às mensagens de erro gigantes sobre instâncias Get/Put ausentes. No meu caso, as classes AnyVal foram as culpadas — o compilador não conseguiu derivar instâncias como antes.
8/10: Solução para o problema doobie: converter classes AnyVal em tipos opacos e fornecer instâncias fornecidas no objeto complementar.
9/10: Enfrentei um desafio com código legado usando sintaxe de tupla sem forma (removida no Scala 3). Precisava de uma maneira de anexar elementos de tupla e convertê-los em classes de caso. Primeiro, tentei a sintaxe de tupla nativa do Scala 3, mas ela era incompatível com CaseClass.tupled.
10/10: Depois de testar extensões personalizadas para tuplas (que apresentavam riscos de falha em tempo de execução), descobri que a biblioteca Chimney era a melhor solução para costurar tuplas com valores adicionais. Bônus: até encontrei um bug na versão mais recente do Chimney!
Que dicas de migração você descobriu? Compartilhe abaixo! #Scala #Scala3
Bônus nº 1: Você pode substituir someContextualResource.flatMap { implicit tracing => ... } por someContextualResource.flatMap { case given TracingCtx => ... }. Não é perfeito, mas funciona, melhor do que misturar dados com implícitos no mesmo arquivo e base de código.