BT

Disseminando conhecimento e inovação em desenvolvimento de software corporativo.

Contribuir

Tópicos

Escolha a região

Início Notícias Mantendo o Scala (mais) Atual

Mantendo o Scala (mais) Atual

Favoritos

No final de novembro de 2011 teve início uma grande agitação no mundo Scala, causada pelo vazamento de um email da Yammer que gerou muitos questionamentos, pois indicava que a infraestrutura básica do Scala voltaria a ser o Java. Em seguida a Typesafe publicou uma resposta, agradecendo os comentários e aproveitou para abordar os planos para o futuro do Scala.

No topo das novidades temos o Scala IDE para Eclipse, cujo desenvolvimento vinha sendo feito desde o início por Miles Sabin [consultor de Scala da Chuusai], mas que agora é mantido pela Typesafe. A IDE mais recente pode ser usada com o JDK 5 ou JDK 6 e está na versão 2.0.0 (oficialmente liberado para a versão Eclipse 3.6 Helios, podendo também ser instalado no Eclipse 3.7 Indigo com algumas restrições de funcionalidade). Assim como outras bibliotecas pré-compiladas do Scala, o IDE possui diferentes pacotes para download, que são baseados na versão do Scala a ser usada. Há releases com suporte às versões 2.9.x ou 2.8.x.

Outras IDEs comerciais também fornecem suporte ao Scala. As recentes versões do JetBrains e IntelliJ IDE 11suportam o Scala na instalação padrão para ambas as edições: comercial e comunitária.

Em seu post "voltando ao trabalho", a Typesafe responde críticas específicas como as exigências na curva de aprendizado, tempo de compilação e desempenho. A empresa comenta que o Scala ainda é considerado um trabalho em andamento, e que embora o desempenho seja importante, existe o cuidado de se evitar otimizações prematuras enquanto a linguagem amadurece. Para a construção (build), recomenda-se o uso da Simple Build Tool (SBT), uma ferramenta que é executada em segundo plano e reduz o tempo de inicialização entre compilações. Por fim, em função do crescimento da comunidade em torno do Scala, o repositório de fontes da linguagem foi movido para o GitHub.

Entretanto, os comentários relacionados à compatibilidade binária geraram insatisfação. Embora a Typesafe possua um plano de assinatura, que garante suporte e manutenção comercial para o conjunto Scala e Typesafe Stack, não foram consideradas as necessidades da comunidade como um todo e de outros frameworks, ao contrário do feito em outras plataformas como Java, Python e Perl. Como alternativa, é oferecida uma aplicação proprietária chamada Migration Manager, que é capaz de determinar estaticamente se haveria variações em tempo de compilação entre diferentes builds. A ferramenta foi utilizada pela própria Typesafe para garantir que o Scala 2.9.1 manteve a compatibilidade retroativa com a versão 2.9.0. A empresa alega também que continua a fornecer todos os frameworks necessários para o desenvolvedor, tal como bibliotecas comuns de teste, IO e gerenciamento transacional em memória.

David Pollak, criador do conhecido framework web Lift, não acredita que este seja o foco correto, no entanto. Em seu post "A fragilidade de versão do Scala torna a adoção por empresas quase impossível", argumenta que as constantes mudanças no bytecode estariam prejudicando diretamente o crescimento do ecossistema do Scala fora do produto da Typesafe.

Uma característica do Scala é que seu compilador gera um bytecode frágil. Isto significa que todos os códigos em executáveis (JAR ou WAR) precisam ser compilados usando as mesmas versões de bibliotecas e compilador. Quando se está usando o Scala 2.9.1 em um projeto, é necessário fazer a compilação usando uma versão do Lift, além de todas as suas dependências que também foram compiladas nesta mesma versão. Por isso o Lift tem poucas dependências de bibliotecas.

A fragilidade de versão do Scala cria dois grandes custos para os complexos sistemas corporativos:

  • Todas as dependências precisam ser compiladas com a mesma versão do Scala e usando as mesmas versões das bibliotecas Scala, o que torna incrivelmente complexo e demorado gerar compilações quando há várias equipes;
  • Bibliotecas externas (como Lift) não podem ter múltiplas camadas de dependências, porque é necessário combinar exatamente a mesma versão da biblioteca e do Scala por todas as dependências.

David Pollak é um dos poucos que pode se embasar em cinco anos de envolvimento com a linguagem Scala e com a comunidade como um todo. A manutenção do projeto do framework Lift, através destes princípios orientadores, é uma excelente referência de como uma comunidade deve funcionar.

A fragilidade citada não é tão problemática com equipes de desenvolvimento pequenas ou quando uma única equipe na empresa está usando Scala. Durante uma migração de Java para Scala para um projeto iniciado do zero, o tempo/custo de trocar a versão é menor do que um dia de trabalho. Mas os problemas surgem rapidamente conforme o aumento do número de equipes:

Por exemplo, em uma organização com duas ou três equipes de desenvolvimento criando código Scala, pode-se definir conjuntamente a versão do Scala e das várias bibliotecas a serem usadas. Quando uma nova versão do Scala ou das bibliotecas estiver disponível, basta juntar algumas pessoas de cada equipe e decidir atualizá-la (ou não). Mas uma vez que se tem mais do que três equipes, o esforço de coordenação passa a ser significativo. Tentar juntar dez diferentes equipes para definir a versão do Scala, Lift, ScalaZ, Rogue, Dispatch e outras bibliotecas, começa a ter um custo bem expressivo.

Como um criador de biblioteca, a questão da fragilidade de versão significa que a nossa biblioteca não é tão boa quanto poderia ser e que não conseguimos servir a nossa comunidade da maneira que desejamos.

No artigo barreiras para a adoção do Scala, David Pollak já manifesta estas preocupações. Ele acredita que este problema não está recebendo a atenção devida e que um verificador proprietário de bytecode é mais um remendo do que uma solução.

O que fiz em relação a este problema? Ao longo dos anos, levantei este assunto privadamente e ele não foi solucionado. Tentei organizar um projeto para encaminhar parte deste assunto, mas não consegui massa crítica para levá-lo adiante.

Há mais de um ano, durante o ciclo de desenvolvimento da versão 2.8, foi formado o projeto "Fresh Scala". A ideia básica era ter a integração contínua, envolvendo a maior parte das bibliotecas Scala e liberar atualizações semanais, para que a comunidade e o ecossistema pudessem nos dar melhores retornos sobre as novas versões do Scala. Devido a falta de tempo dos voluntários, o sistema não foi implantado e aqui estamos, após um ano e meio, com o mesmo problema de fragilidade de versão no Scala.

A iniciativa do Fresh Scala não progrediu muito em um ano e meio, mas Josh Suereth, da Typesafe, assumiu a responsabilidade em seu post Scala Fresh 2.0. Nele é anunciado o Scala Fresh 2.0, uma recriação do projeto hospedado no GitHub:

O que aconteceu com o Scala Fresh? As pessoas podem não ter percebido, mas o Scala Fresh falhou, porque <b>eu</b> falhei com o Scala Fresh. Tive muito pouco tempo disponível, entre um emprego em tempo integral no Google, atuação como escritor e as crianças. Isto não deverá ser um problema no futuro, porém, graças à Typesafe estar levando a sério a compatibilidade binária.

Iniciei os trabalhos no que pode ser chamado de "Scala Fresh 2.0", um lugar onde as bibliotecas comunitárias serão construídas e publicadas sobre a última versão do Scala. Issoo será útil para dois propósitos:

  • Assegurar que futuras versões do Scala não quebrem a compatibilidade com as bibliotecas da comunidade;
  • Assegurar que as principais bibliotecas Scala estejam disponíveis para todas as versões maiores do Scala.

Josh Suereth também argumenta que a responsabilidade sobre a compatibilidade binária é do desenvolvedor da biblioteca, ao invés da plataforma:

Compatibilidade binária é um esforço da comunidade. Sei que a Typesafe está fazendo o possível com os seus recursos, e estou pessoalmente atuando como posso.

É possível escrever código em Java que não mantém a compatibilidade retroativa. Remover métodos públicos e alterar assinaturas de métodos são exemplos de causas de quebra de compatibilidade em qualquer linguagem. Por outro lado, o design de bibliotecas compatíveis retroativamente é algo que muitos desenvolvedores Java já fazem automaticamente, e ainda contam com ferramentas como o Verificador de Uso de APIs do PDE.

Se a evolução das bibliotecas Java é algo previsível (em virtude da implementação das classes estarem em um único arquivo), Josh Suereth destaca que é possível introduzir mudanças incompatíveis através dos Traits do Scala, já que são (na prática) uma junção de interface e implementação:

trait Foo {
    def foo = "foo"
}

trait Foo {
   // mantém a compatibilidade retroativa com o código acima
   def foo = "foo"
   def bar = "bar"
}

---

trait Bar {
   def foo = {
     " foo"
   }
}

trait Bar {
   // não mantém a compatibilidade.
   def foo = {
     bar + " foo"
   }
   def bar = "bar"
}

É possível ter mudanças de código compatíveis em nível de fonte (uma classe que tem o trait Bar, irá compilar em ambos os casos), mas clientes compilados usando a versão anterior do Bar não terão o método bar(), de modo que os clientes mais novos poderão tentar chamar um método que não possui implementação.

As principais bibliotecas do Scala sofrem constantemente com este problema. Por exemplo, a biblioteca de coleções é alterada a cada nova versão do Scala, e como a maioria das APIs usa esta biblioteca, há uma amarração com a versão do Scala usada para compilar o bytecode (e também com a versão das principais bibliotecas). Alguns já começaram a questionar se seria uma boa ideia ignorar o Scala como uma linguagem compilada, tratá-la como veículo para o desenvolvimento da versão 2.10 e deixar de lado, por enquanto, a compatibilidade entre versões. Se o desenvolvedor escolher seguir adiante com a nova versão, será necessário recompilar tudo para garantir o funcionamento correto.

Avalie esse artigo

Relevância
Estilo/Redação

Conteúdo educacional

BT