Olá colegas.
Há pouco tempo, imprimimos o
livro de Odersky, Spoon e Wenners sobre o Scala 2.12. Afinal, o Scala 3 ainda está longe.
O autor do artigo de hoje é Adam Worski, co-fundador da SoftwareMill e desenvolvedor experiente da Scala. Ele obteve um resumo interessante dos pontos fortes da moderna linguagem Scala, que chamamos a sua atenção.
Após uma
palestra plenária de Martin Odersky no ScalaDays, onde ele esboçou os planos para o Scala 3 e uma
palestra plenária de John de Goes na conferência Scalapeño sobre o futuro do
Scala , discussões animadas continuam na
comunidade Scala . Além das discussões dessas apresentações plenárias, inúmeras discussões acontecem no twitter, nas comunidades Slack e no reddit (veja, por exemplo,
1 ,
2 ).
Essa é a questão!Tudo isso é muito interessante e informativo para especialistas que já trabalham no ecossistema Scala. No entanto, grande parte da controvérsia está relacionada às várias falhas intuitivamente perceptíveis ou reais de Scala como idioma. Esses momentos podem assustar as pessoas “de fora”, levando-as a perguntar: “Por que devo usar Scala?”, “E se esse for um beco sem saída?”, “O Scala 3 repetirá o sucesso do Python 3?” etc. Como na maioria das discussões, os pontos mais fracos e mais emocionais são uma atenção fascinante, e esse debate não é exceção.
Então, vamos
dar um passo atrás : por que você precisaria do Scala? Quais são os motivos técnicos e comerciais para trabalhar com esse idioma?
Área de Assunto do ProjetoPara começar, o idioma Scala é especialmente bom para determinadas áreas de estudo (mas não para todos!). O ativo mais importante da Scala é sua
flexibilidade na definição de abstrações . À sua disposição - vários "tijolos" simples para isso; às vezes, definir uma abstração não é mais difícil do que usar uma classe, métodos e expressões lambda. Às vezes, você precisa usar um parâmetro implícito ou método de extensão; em casos raros, resta apenas recorrer a comandos de macro. No entanto,
existem opções .
Assim, Scala é perfeito para você se você precisar
navegar em uma área de assunto complexa . Por exemplo, podemos falar sobre programação distribuída ou competitiva. A simultaneidade é muito difícil e o Scala tem várias bibliotecas que simplificam essa tarefa criando abstrações. Existem duas abordagens principais para isso: baseada em ator, implementada usando
Akka , e no espírito do FP, apresentado por
Monix /
cats-effect e
Scalaz /
ZIO (se você quiser ler mais sobre a comparação dessas ferramentas - escrevi uma
série de artigos sobre este tópico )
No entanto, é claro, podemos falar sobre outras áreas. Os recursos da Scala também nos permitem levar a modelagem de aplicativos de negócios típicos para o próximo nível. Mas, neste caso, estamos falando sobre a complexidade de uma ordem diferente. No caso de sistemas distribuídos, somos confrontados com complexidade técnica. Ao programar a lógica de negócios em aplicativos, já estamos falando sobre a complexidade da área de assunto em si. Por exemplo, o livro de Debasish Ghosh, “
Modelagem de Domínio Funcional e Reativo ”, explica como combinar DDD com programação funcional e reativa.
Dificuldade de linguagemNota: ao falar sobre Scala, todo mundo gosta de enfatizar a amplitude de possibilidades dessa linguagem, enfatizando que, justamente por causa dessa versatilidade, essa linguagem é tão complexa. Isto não é inteiramente verdade.
Como mencionado acima, Scala tem um número de construções básicas a partir das quais abstrações podem ser construídas. No entanto, todos eles podem ser
combinados entre si, devido aos quais o idioma adquire essa flexibilidade. A maioria dos projetos inovadores que você pode encontrar se resume a uma ou outra combinação de tipos de ordem superior, parâmetros implícitos e subtipagem.
Assim, com um número relativamente pequeno de recursos básicos (o tamanho da gramática Scala é mais simples que o Kotlin, Java ou Swift!) - o que, por sua vez, facilita o aprendizado - as opções de combinação são muito mais numerosas.
A escolha é muito ampla? Eu acho que não. O programador, como profissional competente e responsável, é mais do que capaz de escolher a melhor opção para resolver um problema específico. Para mais informações, consulte o artigo "
Simple Scala Stack ".
Java apenas melhorFala-se muito agora que
Kotlin substituiu Scala como "como Java, só que melhor". Mas acredito que
é Scala, e não Kotlin , que ainda merece esse título. Há duas razões principais para isso:
Primeiro, a
imutabilidade em Scala é fundamental . Isso se deve à natureza do Scala como tal: escrever código nele é conveniente principalmente com a ajuda de dados imutáveis. Esses dados incluem, em particular:
val
(como unidades da primeira classe), classes de
case
, funções de ordem superior, etc. Mas o ponto é como a biblioteca de idiomas Scala padrão é projetada e escrita; todas as estruturas de dados usadas por padrão são imutáveis. Graças à imutabilidade, várias coisas são simplificadas, especialmente em nosso mundo de alta competição, onde esses idiomas vencem, onde a imutabilidade é preferida.
Em segundo lugar, o Scala suporta
construtores de tipos, tipos de ordem superior e tipos de classe (declarados implicitamente), o que simplifica bastante o trabalho com tipos de embalagem / contêiner, por exemplo,
Promise
,
Future
ou
Task
. Esses invólucros prevalecem ao programar em um estilo assíncrono ou reativo, e a presença de construções de linguagem que simplificam o trabalho, digamos, com uma base de código em que
Future
é usado ativamente, é outro argumento a favor do Scala.
O que são tipos de classe? O papel deles é aproximadamente o mesmo dos padrões de design em Java; no entanto, eles são mais flexíveis e fáceis de usar assim que você entende firmemente o significado deles. Existem alguns guias excelentes sobre isso, como
1 ,
2 .
E os construtores de tipo? Esses são tipos como
Future
ou
Option
, servindo como "contêineres" ou "invólucros" para outros tipos. Portanto, você pode ter
Option[String]
ou
Future[Int]
. Tipos de pedidos mais altos permitem escrever código que abstrai qualquer invólucro. Veja por exemplo.
1 ,
2 .
De repente você está se perguntando, por que recorrer ao
Future
/
Task
? O ponto não é apenas que a maioria dos cálculos "reativos" de alto desempenho com atrasos mínimos é realizada usando E / S assíncrona, para a qual apenas esses projetos são simplesmente solicitados. Outras razões são apresentadas nesta
discussão no reddit e no meu artigo “
Por que se preocupar com wrappers? "
Trabalhar em um ambiente predominantemente inalterado, bem como a capacidade de lidar convenientemente com construções como
Future
,
Promise
ou
Task
(e abstraí-las!) Transforma radicalmente seu código. À primeira vista, isso pode não ser óbvio: se você tiver experiência com Java ou Ruby, não poderá perceber esses aspectos do Scala imediatamente. Mas, mesmo do ponto de vista educacional, é útil entender como a abordagem "funcional" funciona e, mais importante, por que ela pode se tornar uma
alternativa muito digna .
Naturalmente, o Scala e o Kotlin têm várias vantagens comuns sobre o Java, por exemplo:
- Sintaxe mais compacta
- Código menos estereotipado
- Um sistema do tipo mais rico
- Falta de lastro de linguagem
Ao mesmo tempo, os dois idiomas fornecem acesso ao ecossistema de bibliotecas e estruturas da JVM.
Quanto mais rico o sistema de tipos (no Scala é mais rico que no Kotlin e no Kotlin - mais rico que no Java), mais trabalho de verificação é realizado pelo compilador, e não pela pessoa. É para isso que os computadores foram criados: para realizar tarefas repetitivas e rotineiras e chatas. Verificar a aplicabilidade dos tipos é definitivamente apenas uma dessas tarefas.
Ao mesmo tempo, um sistema de tipo avançado é útil não apenas ao
escrever código , mas também, em uma extensão muito maior, ao
ler código . Quando é fácil navegar na base de código, entender o que está fazendo e, além disso, não é assustador (ou não tão assustador) realizar sua
refatoração , isso caracteriza o idioma de maneira muito positiva do ponto de vista técnico e aplicado.
FP vs OOPOutra questão frequentemente levantada em tais discussões é se a linguagem Scala deve continuar a aderir à síntese de POO e PF, ou se deve desenvolver-se por um caminho puramente funcional. Sou um
defensor da síntese , principalmente porque FP e OOP, na minha opinião, não são abordagens alternativas, mas se complementam.
O FP está
programando usando funções , embora nenhuma, mas referencialmente transparente (veja esta
resposta para reddit em um tópico anterior, onde a transparência referencial é perfeitamente explicada). No POO, a comunicação com objetos é organizada usando "mensagens" ou, em nossa terminologia, chamadas para métodos virtuais. Não há uma única razão pela qual essas duas abordagens não possam coexistir, e Scala já demonstrou isso!
Em um
tweet sobre as virtudes do Scala, John de Goes menciona alguns recursos de OOP que são úteis em uma abordagem puramente funcional, em particular
módulos de primeira classe (obtidos pela composição de objetos),
sintaxe de pontos (métodos de chamada em objetos) e
instâncias de classes / tipos como construções de primeira classe . Todos esses são elementos de uma combinação bem-sucedida de dois paradigmas. Talvez mais alguns estejam ao virar da esquina?
O projeto "síntese" ainda não está concluído; definitivamente há um campo para discussão aqui. Um aspecto incompleto é a sintaxe proposta para métodos de extensão, que deve substituir conversões implícitas muito mais confusas. Outra é otimizar a sintaxe das classes de tipos;
A sugestão feita há um tempo é claramente grosseira e não cobre alguns dos usos mais comuns das mônadas em Scala. Algumas sugestões são melhores, outras requerem refinamento, mas é bom que elas sejam recebidas e que sejam realizadas discussões sobre elas; graças a eles, a linguagem vive e, finalmente, a melhor solução é fixada nela.
Scala 3Scala 3 será lançado em dois anos. Aparecerão várias possibilidades interessantes, em particular tipos opacos, parâmetros de características, uma nova abordagem de metaprogramação, tipos de união e & interseção, tipos de funções implícitas - estes são apenas alguns exemplos. Obviamente, existe uma preocupação (bem fundamentada) sobre a migração.
Já se sabe que uma ferramenta especial será introduzida para
a migração automática de código do Scala 2 para o Scala 3 usando o
scalafix . Como Scala é uma linguagem de tipo estaticamente, essa tarefa pode ser resolvida em larga escala e é muito mais simples do que, por exemplo, em Python. Mas, é claro, não há mágica aqui: mesmo que essa ferramenta forneça 99% de cobertura correta do código, 1% dos casos mais problemáticos ainda permanecerão. Como você não pode contar com mágica, a migração desses fragmentos precisará ser feita manualmente.
Esses são os custos de trabalhar com uma linguagem em desenvolvimento ativo: você obtém as oportunidades mais recentes, mas algumas delas não são tão boas e precisam ser aprimoradas. Mesmo assim, as mudanças propostas não são revolucionárias. O idioma do Scala 3 é muito semelhante ao Scala 2, não são esperadas grandes mudanças de paradigma.
É encorajador que a equipe Scala leve a sério a migração. Enquanto a migração anterior entre versões mais antigas do Scala (por exemplo, de 2,8 para 2,9) era bastante onerosa, as migrações recentes foram muito melhores. Existem três partes principais envolvidas: EPFL,
ScalaCenter e
Lightbend, todos eles (geralmente juntos) trabalham para facilitar a migração. Por exemplo, existe uma ferramenta
MIMA compatível com binário, e inúmeras novas bibliotecas são constantemente criadas na comunidade para garantir um trabalho conveniente com as novas versões do Scala.
Por fim, a ferramenta TASTY ainda inacabada (que, portanto, ainda não pode ser avaliada) deve garantir o uso de arquivos binários do Scala 2 ao Scala 3.
Então, por que usar Scala?Então, quais são os motivos para parar na Scala, se você considerar esse idioma do ponto de vista comercial? Todas as vantagens técnicas acima são diretamente úteis para os negócios. Quando você tem um idioma no qual pode escrever código complexo com menos bugs, recebe um atraso mínimo em termos e usuários satisfeitos. Se você começar a escrever aplicativos competitivos poderosos e praticamente antiderrapantes para o Scala, para os quais são fornecidas ferramentas especiais no Scala, isso será um sério benefício para sua empresa.
Além disso, não se esqueça do
Spark , a plataforma líder em
análise de dados distribuídos . O Scala é usado não apenas para implementar o Spark como tal, mas também para definir os próprios cálculos. Aqui está outra abstração orientada à ciência de dados que oculta um modelo computacional complexo.
SumárioClaro, existem problemas em Scala, mas onde eles não estão? O motivo do otimismo é que muitas pessoas que usam o Scala diariamente estão trabalhando ativamente para
melhorar as ferramentas , bibliotecas e a própria linguagem. Posso presumir que eles continuam trabalhando com o Scala precisamente porque, com todas as deficiências disponíveis, nenhum idioma é tão adequado para a área de estudo.
O Scala permite que você desenvolva seu próprio estilo de programação, independentemente da linguagem que você costumava ser: Java, Ruby ou apenas tente você mesmo em programação. Não existe uma abordagem única para o Scala; a abordagem mais
imperativa da Akka ou a abordagem mais
funcional de Cats and Scalaz.
É aqui que o problema pode ser visto: há frações na comunidade Scala que aderem à abordagem OOP / AF “reativa”, “sintética” e FA pura. No entanto, de fato, essa é uma enorme vantagem. Devido a essa diversidade, estão sendo realizadas discussões, muitas opiniões diferentes são expressas sob diferentes pontos de vista. Por sua vez, você pode aprender perfeitamente como resolver problemas fora do padrão e enriquecer suas próprias ferramentas.
Qualquer que seja o caminho escolhido em Scala, você será apoiado por uma impressionante comunidade de colegas envolvidos no desenvolvimento de bibliotecas e estruturas; essas pessoas estão sempre prontas para ajudar e discutir idéias emergentes.