Porque é que Kotlin é fantástico, mas vai ficar com Java na mesma
Marcin Perlikowski
Programador Java sénior
Se é um programador Java, é provável que tenha pelo menos alguma experiência com outras linguagens de programação. Alguns de nós começaram a sua aventura de programação com outra linguagem como C/C++, JavaScript, C#, Python ou talvez mesmo algo como Pascal ou Basic. Alguns, porém, começaram com Java e nunca prestaram muita atenção a outras linguagens, lembrando-se desagradavelmente da única vez em que precisaram de codificar rapidamente algo no frontend.
Independentemente do grupo a que pertença, há uma razão para ficar com Java. E não o estou a culpar. Tem, sem dúvida, o ecossistema mais desenvolvido, universal e completo de todo o mundo. empresa mundo. A linguagem tem um conjunto de capacidades bem adaptado, algures na zona certa entre demasiado e demasiado pouco. E estão a ser adicionadas novas funcionalidades de forma lenta mas constante, mantendo-a actualizada em relação às novas tendências no mundo da programação.
Conhece Lombok Mas? Se não conhece, recomendo vivamente que experimente. Se gostas, então tenho algo para ti. Uma língua totalmente nova, que pelas suas caraterísticas torna o Lombok obsoleto. Chama-se Kotlin.
Kotlin? Está a falar da linguagem Android?
O Kotlin no Android foi abençoado pela própria Google ao ponto de se tornar a linguagem de facto de eleição para a plataforma. Não é nisso que me vou focar neste artigo, mas o Android é de facto o local onde conheci o Kotlin pela primeira vez.
O meu colega de trabalho estava a desenvolver uma aplicação para uma projetopor conta própria. No entanto, os prazos estavam a aproximar-se rapidamente, pelo que fui incumbido de o ajudar a cumpri-los. Deixem-me agora recuar no tempo até esse momento. E... YUCK! Porque é que ele está a usar uma linguagem estranha que soa a marca de ketchup!? Tem um aspeto horrível!
Porque é que se escreve "fun" antes de cada função? Como se eu já não soubesse o que é. Além disso, já estou a ter diversão com Java de qualquer forma. E onde está o tipo de retorno? No fim? Estás doido? O que é isso, estás a atribuir algo a uma função? Não faz sentido nenhum! Parece-se tudo com Java com passos extra! Espera, onde é que está a classe a que este método pertence? Onde é que o escondeste, seu ketchup, Java desculpa imitadora de uma linguagem de programação? Oh, não. Oh não, não o fizeste. ISSO É UMA FUNÇÃO GLOBAL? É isso, estou farto, vou chamar a polícia.
Alerta de spoiler: não chamei a polícia. Quer gostasse ou não, tive de ajustar a minha mentalidade centrada em Java para me adaptar a outra linguagem. Mas não será assim tão mau, certo? Continua a ser uma linguagem JVM, é apenas uma linguagem diferente Java. Talvez até com algumas funcionalidades extra fixes? Relutantemente, comecei a trabalhar no projeto.
Java com passos extra
Se Java é tão bom, porque é que não existe Java 2? Brincadeiras à parte, foi o que pensei para mim mesmo. Vou fingir que o Kotlin é o Java 2. Tem uma sintaxe nova e tudo, mas só preciso de aprender o suficiente para terminar o projeto. Enganei-me redondamente.
Depois de a experimentar durante apenas um ou dois dias, apercebi-me rapidamente de que tanto o Kotlin como o Java não são assim tão elásticos. Tentar dobrá-los um contra o outro acaba inevitavelmente com um deles partindo-se ao meio. Tornou-se óbvio que Kotlin é uma coisa por si só, e o facto de funcionar numa JVM não significa quase nada do ponto de vista do programador. (Em uma nota lateral, ele também pode transpilar para JavaScriptou ser compilado para um binário nativo).
Plano B, então. Na verdade, conhecer a linguagem. Ler os documentos pela primeira vez causa alguns arrepios na espinha de um programador Java experiente. Por exemplo: - contexto global de nível superior anteriormente mencionado - parâmetros e tipos de retorno de funções especificados no final
fun sum(a: Int, b: Int): Int {
return a + b
}
o corpo da função pode ser uma expressão (utilizando o sinal de igualdade)
fun sum(a: Int, b: Int) = a + b
A declaração if pode fornecer um resultado
val y = if (x == 1) {
"um"
} else if (x == 2) {
"dois"
} else {
"outro"
}
Ok, só preciso de me habituar a isso. Apenas uma sintaxe diferente. O que mais tem a oferecer, senhor Kotlin?
value?.method() // executar se não for nulo
Oh ok, livrar-se de se (valor == nulo)um ponto para ti. Que mais tens?
fun check(list: List, alternative: Boolean) = when {
list is LinkedList -> print("linked")
alternativa -> print("alternativa")
list.size > 50 -> print("big")
else -> print("outro")
}
Hmm, fixe, pode ser útil para evitar bloqueios, mas continua a parecer um truque.
object SingularObject: Counter() {
var a = 14
fun test() = if (a > 10) "mais" else "menos"
}
Ok, essa parece realmente útil, eu gosto! Por outro lado, também posso criar um singleton em Java. Talvez não seja tão elegante, mas não é nada de novo. Tens alguns ases na manga? Tipo, um verdadeiro golpe pesado?
var s: String = null // não compila, tipo não nulo
Imagine uma base de código, onde não precisa de se preocupar com a segurança de nulos. Imagine ter como certo que cada referência contém de facto algo significativo. Imagine ter a certeza de que todos os problemas relacionados com nulos são resolvidos antecipadamente. Não imagine mais. Todas as referências em Kotlin não são anuláveis por defeito. Se quiser torná-las anuláveis, tem de conscientemente tomar essa decisão, e explicitamente declará-lo no código:
var s: String? = null
Compreendo que, nesta altura, possa estar cético em relação a esta ideia. Está habituado a referências anuláveis. Mantém isso na sua cabeça enquanto codifica. Aprendeu onde precisa de ter cuidado. Exatamente o que penso. Vindo de JavaNo início, pareceu-me estranho, de facto. Tipo, qual é o objetivo? Não vai fazer desaparecer por magia todos os problemas relacionados. Terei de acrescentar "?" em todo o lado, o que me parece uma tarefa árdua.
Mas eu decidi mergulhar fundo na língua, não foi? Vamos fazer à sua maneira, senhor Kotlin. Comecei a fazer um esforço para eliminar o maior número possível de variáveis, campos e parâmetros anuláveis. Passo a passo, aprendi a utilizar as caraterísticas da linguagem que facilitavam a eliminação de referências anuláveis, por exemplo, o operador "?." de chamada segura, o operador "?:" de elvis, as propriedades delegadas, o método "let", entre outros.
Com o passar do tempo, consegui que algumas classes só contivessem campos e parâmetros de métodos não nulos. Basicamente, eu sabia que se uma classe fosse instanciada com sucesso, eu poderia quase esquecer a nulidade nos corpos dos métodos. Era uma felicidade. Com o tempo, fui apreciando isso cada vez mais. No entanto, no final das contas, eu não pensava nisso como uma caraterística matadora, Java ainda se sentia em casa. Até que...
O regresso
O projeto estava a aproximar-se do fim. Comecei a conhecer Kotlin cada vez mais e, com esse conhecimento, o código tornou-se cada vez mais organizado, legível e conciso. Era possível ver as melhorias a olho nu no histórico de commits. Mas finalmente chegou a altura. Com memórias inesperadamente boas da nova linguagem, era altura de dizer adeus e voltar à doce zona de conforto do Java. Ou assim pensava eu.
Conhece aquela sensação de começar a apreciar algo no preciso momento em que se vai embora? Quando não nos apercebemos do quanto dependemos de algo até já não o podermos usar? Este foi o melhor exemplo dessa sensação que provavelmente já experimentei na minha vida.
Quando voltei a escrever o código em JavaQuase fiquei aterrorizado com a falta de algumas funcionalidades. Era como se o meu cérebro, subconscientemente, tivesse adaptado erradamente as funcionalidades de Kotlin para Java. Passei por situações em que comecei a implementar algo, apenas para perceber que não funcionaria nesta linguagem. Na melhor das hipóteses, eu poderia escrevê-lo como Kotlin, mas seria volumoso, ilegível e/ou exigiria muito boilerplate.
A segurança nula foi, obviamente, a caraterística de que mais senti falta. Mas fiquei surpreendido com a quantidade de coisas mais pequenas que se tornaram naturais para mim: parâmetros nomeados, propriedades em vez de getters e setters, "==" como igual e "===" como igualdade referencial, "this" qualificado, funções de extensão, parâmetro lambda singular implícito, "_" para parâmetros lambda não utilizados, classes de dados, funções de âmbito, outras funções stdlib de Kotlin, operadores e muito mais. E a forma como tudo se encaixa perfeitamente. Em comparação, Java parecia... primitivo.
Na verdade, senti-me tão mal que comecei a considerar mudar para Kotlin. Teoricamente, é totalmente interoperável com Java, basta adicionar suporte a Kotlin a um projeto existente e começar a escrever novas classes. O lado Kotlin sabe como "falar" com Java, e o lado Java nem sequer sabe que está a "falar" com outra linguagem. E após a compilação para bytecode, não faz realmente qualquer diferença para a JVM.
Verificação da realidade
Então, de que estão à espera? Se a linguagem é tão boa como dizem, usem-na! Mas talvez não em projectos existentes, pois sei que deve ser interoperável, mas misturar duas linguagens diferentes desta forma parece-me feio.
Ok, então para novos módulos - Kotlin é isso. Ou será que não? Está a trabalhar num módulo equipa. É preciso consultá-los e convencê-los da grandeza desta nova língua. O quê? Eles não gostam? Parece que não querem esforçar-se para a aprender. Mas não os podes culpar, também estavas cético no início.
O gestor de projectos! Sim! Ele certamente compreenderá o grande valor que Kotlin trará à nossa equipa. Oh, a grandeza que virá! -Não -Espere, porquê? -A equipa não o sabe. -Eles vão aprender! -Não querem aprender. -Pode fazê-las! -Não precisam de aprender. -É verdade, mas pensa nas possibilidades! -Sim, e se pensasses primeiro nos problemas?
A lenda diz que existe um projeto. Um projeto que é grande e complexo, mas bem escrito em todas as partes. Um projeto, onde todos os programadores estão em uníssono sobre as soluções utilizadas. Onde as novas funcionalidades fluem suavemente dos teclados dos programadores. Onde os bugs são raros e fáceis de corrigir.
Já viu um projeto como este? Eu não vi. Alguns chegaram perto, mas a maioria deles é uma grande confusão de código legado. E se não o são, provavelmente tornar-se-ão uma a dada altura no futuro. Agora imagine-se a acrescentar outra linguagem à mistura. Introduz novas formas de cometer erros. Exige que os programadores saibam o que estão a fazer. É um risco, para dizer o mínimo.
Agora, considere também a rotação dos programadores. As pessoas vão e vêm. Vai obrigar cada novo programador a aprender uma linguagem completamente nova? Não, isso é contraproducente. Vai contratar programadores de Kotlin para começar? Boa sorte com isso, contratar um bom programador Java já é difícil o suficiente.
As pessoas tentaram. Tenho de dizer que não concordo com a maioria das alegações desse artigo. Há algumas críticas válidas, mas acho que eles não usaram Kotlin o suficiente para realmente entender "o jeito Kotlin". Muitos dos comentadores desse artigo parecem pensar da mesma forma.
Mas isso não importa. Aposto que isto também aconteceria no seu projeto. "Experimentei, não gostei". Não os vai obrigar a dedicar mais tempo ao projeto. Não os vai obrigar a tentar de novo. Não os vai obrigar a dar outra oportunidade. E, de um ponto de vista prático, eles podem ter razão. Java é tão popular, que usar qualquer outra coisa na JVM parece redundante.
Porquê então este artigo?
Acabaste de gastar uma quantidade considerável de tempo a escrever um artigo que parece não ter um objetivo. Porque é que eu havia de tentar aprender uma língua, se diz que é inútil?
Bem, eu não acho que seja inútil. Continuo a achar que Kotlin é ótimo. Continuo a querer usá-lo (e já o faço nos meus projectos privados). Se pudesse, mudava para ele e esquecia as limitações do Java. Mas a realidade atual diz que não posso. E eu quero tentar mudar isso.
A minha intenção para si, caro leitor, é pelo menos considerar a possibilidade de sair da aconchegante zona de conforto de Java. Porque talvez, apenas talvez, você ame Kotlin tanto quanto eu. E se gostar, será mais um desenvolvedor conhecedor de Kotlin na mercado.