Perché Kotlin è fantastico, ma voi resterete comunque con Java
Marcin Perlikowski
Sviluppatore Java senior
Se siete sviluppatori Java, è probabile che abbiate almeno una certa esperienza con altri linguaggi di programmazione. Alcuni di noi hanno iniziato la loro avventura di programmazione con un altro linguaggio come C/C++, JavaScript, C#, Python o forse anche qualcosa come Pascal o Basic. Alcuni, invece, hanno iniziato con Java e non hanno mai prestato troppa attenzione ad altri linguaggi, ricordando spiacevolmente l'unica volta in cui hanno avuto bisogno di codificare rapidamente qualcosa sul lato frontend.
Indipendentemente dal gruppo a cui si appartiene, c'è un motivo per cui si rimane con Java. E non vi sto dando la colpa. Ha probabilmente l'ecosistema più sviluppato, universale e completo di tutto il mondo. impresa mondo. Il linguaggio ha un insieme di funzionalità ben personalizzate, a metà strada tra il troppo e il troppo poco. Inoltre, vengono aggiunte lentamente ma costantemente nuove funzionalità, che lo mantengono per lo più aggiornato con le nuove tendenze del mondo della programmazione.
Sapete che Lombok Ma? Se non lo fate, vi consiglio di provarlo. Se vi piace, ho qualcosa da farvi provare. Un linguaggio completamente nuovo, che per le sue caratteristiche rende il Lombok obsoleto. Si chiama Kotlin.
Kotlin? Intendi il linguaggio di Android?
Kotlin su Android è stato benedetto da Google stesso al punto da diventare il linguaggio de-facto di scelta per la piattaforma. Non è questo l'argomento su cui mi concentrerò in questo articolo, ma Android è effettivamente il luogo in cui ho incontrato Kotlin per la prima volta.
Il mio collega di lavoro stava sviluppando un'applicazione per un'allora corrente progettoda solo. Le scadenze, però, si stavano avvicinando rapidamente, così sono stato delegato ad aiutarlo a rispettarle. Ora mi trasferisco indietro nel tempo fino a quel momento. E... bleah! Perché sta usando una lingua strana che sembra un marca di ketchup!? Ha un aspetto orribile!
Perché c'è scritto "fun" prima di ogni funzione? Come se non sapessi già cos'è. Inoltre, sto già avendo divertimento con Java in ogni caso. E dov'è il tipo di ritorno? Alla fine? Sei impazzito? Cos'è, stai assegnando qualcosa a una funzione? Non ha alcun senso! Sembra proprio che Java con passaggi extra! Aspetta, dov'è la classe a cui appartiene questo metodo? Dove l'hai nascosto, razza di ketchup, Java imitare la scusa di un linguaggio di programmazione? Oh, no. Oh no, non l'hai fatto. È UNA FUNZIONE GLOBALE? Basta, ho finito, chiamo la polizia.
Attenzione: non ho chiamato le forze dell'ordine. Che mi piaccia o no, ho dovuto modificare la mia mentalità Java-centrica per adattarmi a un altro linguaggio. Ma non sarà poi così male, giusto? È ancora un linguaggio JVM, sicuramente è solo un linguaggio diverso. Java. Magari anche con qualche funzione aggiuntiva? Con riluttanza, ho iniziato a lavorare al progetto.
Java con passaggi aggiuntivi
Se Java è così grande, perché non esiste Java 2? A parte gli scherzi, è quello che ho pensato tra me e me. Farò finta che Kotlin sia Java 2. Nuova sintassi e tutto il resto, ma devo solo impararne abbastanza per finire il progetto. Ragazzi, mi sbagliavo.
Dopo averla provata per un giorno o due, mi sono subito reso conto che sia Kotlin sia Java non sono così elastici. Se si cerca di piegarli l'uno verso l'altro, uno dei due si spezza inevitabilmente a metà. È diventato ovvio che Kotlin è una cosa a sé stante e il fatto che funzioni su una JVM non significa quasi nulla dal punto di vista del programmatore. (Una nota a margine: è anche in grado di eseguire il transpile su JavaScripto essere compilato in un binario nativo).
Allora il piano B. In realtà, imparate a conoscere il linguaggio. Leggere i documenti per la prima volta fa venire i brividi a un programmatore Java esperto. Per esempio: - il già citato contesto di primo livello, alias globale - e i tipi di ritorno delle funzioni specificati alla fine
fun somma(a: Int, b: Int): Int {
restituisce a + b
}
il corpo della funzione può essere un'espressione (utilizzando il segno di uguaglianza)
fun sum(a: Int, b: Int) = a + b
L'istruzione if può fornire un risultato
val y = if (x == 1) {
"uno"
} else if (x == 2) {
"due"
} else {
"altro"
}
Ok, devo solo abituarmi. Solo una sintassi diversa. Cos'altro hai da offrire, mister Kotlin?
valore?.metodo() // esegue se non è nullo
Oh ok, sbarazzarsi di se (valore == null), un punto per te. Che altro hai?
fun check(list: List, alternative: Boolean) = when {
list è LinkedList -> print("linked")
alternativa -> print("alternativa")
list.size > 50 -> print("grande")
else -> print("altro")
}
Bello, potrebbe essere utile per evitare i blocchi, ma sembra comunque un espediente.
oggetto SingularObject: Counter() {
var a = 14
fun test() = if (a > 10) "more" else "less"
}
Ok, questo sembra davvero utile, mi piace! D'altra parte, posso creare un singleton anche in Java. Forse non sarà così elegante, ma non è una novità. Qualche asso nella manica? Tipo, veri e propri assi nella manica?
var s: String = null // non si compila, tipo non-null
Immaginate una base di codice in cui non ci si debba preoccupare della sicurezza dei null. Immaginate di dare per scontato che ogni riferimento contenga effettivamente qualcosa di significativo. Immaginate di essere sicuri che ogni problema legato ai null sia stato affrontato in anticipo. Non immaginate più. Tutti i riferimenti in Kotlin non sono nullable per impostazione predefinita. Se si desidera renderli nullable, occorre consapevolmente prendere questa decisione e esplicitamente dichiararlo nella codice:
var s: String? = null
Capisco che a questo punto possiate essere scettici su questa idea. Siete abituati ai riferimenti annullabili. Lo tenete a mente durante la codifica. Avete imparato dove è necessario fare attenzione. Esattamente il mio pensiero. Provenendo da JavaAll'inizio mi è sembrato strano. Come a dire: che senso ha? Non farà magicamente sparire tutti i problemi correlati. Dovrò aggiungere "?" dappertutto, mi sembra un lavoro faticoso.
Ma ho deciso di immergermi nella lingua, non è vero? Facciamo a modo suo, signore Kotlin. Ho iniziato a sforzarmi di eliminare il maggior numero possibile di variabili, campi e parametri nulli. Passo dopo passo, ho imparato a usare le caratteristiche del linguaggio che rendevano più facile eliminare i riferimenti nulli, come ad esempio l'operatore safe call "?.", l'operatore elvis "?:", le proprietà delegate, il metodo "let" e altro ancora.
Con il passare del tempo, sono riuscito a far sì che alcune classi contenessero solo campi e parametri dei metodi non nulli. In pratica, sapevo che se una classe veniva istanziata con successo, potevo quasi dimenticarmi della nullità nei corpi dei metodi. Era una beatitudine. Con il tempo, l'ho apprezzato sempre di più. In ultima analisi, però, non l'ho considerata una caratteristica fondamentale, Java si sentiva ancora a casa. Fino a quando...
Il ritorno
Il progetto si stava avvicinando alla fine. Ho imparato a conoscere sempre meglio Kotlin e, grazie a questa conoscenza, il codice è diventato sempre più ordinato, leggibile e conciso. I miglioramenti si potevano vedere a occhio nudo nella cronologia dei commit. Finalmente, però, è arrivato il momento. Con un ricordo inaspettatamente bello del nuovo linguaggio, è arrivato il momento di dire addio e tornare alla dolce zona di comfort di Java. O almeno così pensavo.
Avete presente la sensazione che si prova quando si inizia ad apprezzare qualcosa proprio nel momento in cui non c'è più? Quando non ci si rende conto di quanto si fa affidamento su qualcosa finché non la si può più usare? È stato il miglior esempio di questa sensazione che abbia mai provato in vita mia.
Quando sono tornato a scrivere il codice in JavaEro quasi terrorizzato dalla mancanza di alcune funzionalità. Era come se il mio cervello, inconsciamente, avesse erroneamente adattato le caratteristiche di Kotlin a Java. Ho vissuto situazioni in cui ho iniziato a implementare qualcosa, per poi rendermi conto che non avrebbe funzionato in questo linguaggio. Nel migliore dei casi potrei scriverlo in modo simile a Kotlin, ma sarebbe ingombrante, illeggibile e/o richiederebbe troppo boilerplate.
La sicurezza dei null è stata ovviamente la caratteristica che mi è mancata di più. Ma sono rimasto sorpreso da quante piccole cose sono diventate naturali per me: parametri con nome, proprietà invece di getter e setter, "==" come uguale e "===" come uguaglianza referenziale, "this" qualificato, funzioni di estensione, parametro lambda singolare implicito, "_" per i parametri lambda non utilizzati, classi di dati, funzioni di scope, altre funzioni stdlib di Kotlin, operatori e altro ancora. E il modo in cui tutto questo si incastra piacevolmente. In confronto, Java sembrava... primitivo.
Mi sono sentito così male che ho iniziato a prendere in considerazione l'idea di passare completamente a Kotlin. In teoria, è completamente interoperabile con Java, si può semplicemente aggiungere il supporto Kotlin a un progetto esistente e iniziare a scrivere nuove classi. Il lato Kotlin sa come "parlare" con Java, mentre il lato Java non sa nemmeno che sta "parlando" con un altro linguaggio. E dopo la compilazione in bytecode, non fa alcuna differenza per la JVM.
Controllo della realtà
Quindi cosa state aspettando? Se il linguaggio è buono come dite, usatelo! Forse non nei progetti esistenti, però, so che dovrebbe essere interoperabile, ma mischiare due lingue diverse in questo modo sembra brutto.
Ok, quindi per i nuovi moduli - Kotlin sia. O forse no? Si sta lavorando in un squadra. Dovete consultarli e convincerli della grandezza di questa nuova lingua. Cosa? Non gli piace? Sembra che non vogliano fare lo sforzo di impararla. Non potete biasimarli, anche voi eravate scettici all'inizio.
Il project manager! Sì! Sicuramente capirà il grande valore che Kotlin apporterebbe al nostro team. Oh, la grandezza che verrà! -No -Aspetta, perché? -La squadra non lo sa. -Impareranno! -Non vogliono imparare. -Potete farli voi! -Non hanno bisogno di imparare. -È vero, ma pensate alle possibilità! -Sì, e se pensassi prima ai problemi?
La leggenda dice che esiste un progetto. Un progetto grande e complesso, ma ben scritto in ogni sua parte. Un progetto in cui tutti gli sviluppatori sono all'unisono sulle soluzioni utilizzate. Dove le nuove funzionalità fluiscono senza problemi dalle tastiere dei programmatori. Dove i bug sono rari e facili da risolvere.
Avete mai visto un progetto del genere? Io no. Alcuni ci sono andati vicino, ma la maggior parte di essi sono un grande pasticcio di codice legacy. E se non lo sono, probabilmente lo diventeranno in futuro. Ora immaginate di inserire un altro linguaggio nel mix. Introduce nuovi modi per commettere errori. Richiede che gli sviluppatori sappiano cosa stanno facendo. È un rischio, a dir poco.
Considerate anche la rotazione degli sviluppatori. Le persone vanno e vengono. Volete che ogni nuovo sviluppatore impari un linguaggio completamente nuovo? No, è controproducente. Assumerete innanzitutto sviluppatori Kotlin? Buona fortuna, assumere un buon sviluppatore Java è già abbastanza difficile.
Le persone ci hanno provato. Devo dire che non sono d'accordo con la maggior parte delle affermazioni contenute nell'articolo. Ci sono alcune critiche valide, ma credo che non abbiano usato abbastanza Kotlin per capire effettivamente "il modo Kotlin". Molti commentatori di quell'articolo sembrano pensarla allo stesso modo.
Ma questo non ha importanza. Scommetto che questo accadrebbe anche nel vostro progetto. "L'ho provato, non mi è piaciuto". Non li costringerete a dedicarci più tempo. Non li costringerete a riprovare. Non li costringerete a dare un'altra possibilità. E da un punto di vista pratico, potrebbero avere ragione. Java è così popolare che l'uso di qualsiasi altra cosa sulla JVM sembra ridondante.
Perché allora questo articolo?
Hai appena speso una notevole quantità di tempo per scrivere un articolo che sembra non avere un senso. Perché dovrei provare a imparare una lingua, se lei dice che è comunque inutile?
Beh, non credo che sia inutile. Penso ancora che Kotlin sia fantastico. Voglio ancora usarlo (e lo faccio per i miei progetti privati). Se potessi, passerei ad esso e mi dimenticherei delle limitazioni di Java. Ma la realtà attuale dice che non posso. E voglio provare a cambiare questa situazione.
La mia intenzione per te, caro lettore, è di considerare almeno la possibilità di uscire dall'accogliente zona di comfort di Java. Perché forse, e dico forse, amerete Kotlin quanto me. E se così fosse, ci sarebbe un altro sviluppatore con conoscenza di Kotlin sulla mercato.