Java è semplice? (Spoiler: No)

Java è semplice, una cosa che si sente spesso, specialmente nelle università italiane che per qualche ragione sono in fissa con l’object orientation, ma non voglio parlare di questo.
Voglio portare un’esempio per me significativo, implementare l’intersezione tra insiemi in java, utilizzando le classi standard di java, quindi java.collection.Set e java.collection.HashSet, ed i generics di java 1.5.
La prima cosa da fare è scegliere la firma del metodo

public <T> Set<T> intersection(Set<T> s1, Set<T> s2) {
    ....
}

Questa in linea di massima potrebbe sembrare ok però ha un design flaw, è troppo restrittiva, ci sono combinazioni di Set sui quali si dovrebbe poter fare un’intersezione ma il metodo non accetta i parametri.
Se prendiamo Set<Number> s1 = {1, 2.0, 3.14159} e Set<Double> s2 = {3.14159, 2.0} (non è possibile inizilizzare insiemi con questa sintassi, però scrivere proper java richiede troppo testo) non vengono accettati dal metodo con la firma proposta, però teoricamente è del tutto possibile fare l’intersezione di questi due insiemi, di fatti è {3.14159, 2.0}.
Ecco un’altra proposta:

public <T> Set<T> intersection(Set<T> s1, Set<? extends T> s2) {
    ....
}

Questa già ha dei vantaggi in più, ora il controesempio di prima con Number e Double funziona, ma c’è ancora qualcosa che sfugge, ecco un’altro controesempio:
Set<Number> s1 = {1, 2.0, 3.14159} e Set<Object> s2 = {"c > c++ == true", 3.14159, false}, l’intersezione tra questi due insiemi è del tutto possibile (il singleton { 3.14159 }), ma il metodo non lo accetta.
Saltando direttamente alla conclusione, vi mostro direttamente la scelta migliore e anche l’implementazione (se poi qualcuno è interessato si può continuare la discussione su tutti i dettagli ed altre possibili firme):

public <T> Set<T> intersection(Set<? extends T> s1, Set<?> s2) {
    Set<T> result = new HashSet<>();
    for (Object o : s2) {
        if (s1.contains(o)) {
            result.add(o);
        }
    }
    return result;
}

Ora perchè fare tutto questo discorso?
Per mostrare quanto anche solo la scelta della firma di un metodo può essere complicata in java, in altre parole java non è semplice, ma ci viene detto che lo è, di solito da persone che non si sporcano le mani con il codice da anni.
Una piccola euristica che mi piace seguire è “Non fidarti di chi non si mette in gioco”.
Non sono qui per dire che java è un cattivo linguaggio, chiariamoci lo penso e posso argomentare a riguardo, ma è un buon esempio per mostare quanto sono complicate le astrazioni ed i luoghi comuni anche in informatica.

1 Like

Il problema e’ che spesso viene detto senza contesto e niente e’ facile o difficile ed aggiungo che molte volte insegnano o perseguono un dato linguaggio, piuttosto che altro, per moda, comodita o peggio per intrallazi economici !!!

Il titolo potrebbe essere " * e’ semplice ? "

Si, questo seguire la moda è quello che mi da fastidio, ribadisco che questo non si tramuta in java bad, è un buon esempio (dal mio punto di vista), è un linguaggio complesso ma allo stesso tempo è tra i più utilizzati in italia, specialmente negli ambienti publici (comuni, bandi, aziende sanitarie, etc), per come la vedo è anche uno dei motivi per cui molti software italiano non è un granche.

1 Like

Aggiungo la mia!

Io personalmente credo che Java, come anche Python ad esempio, siano considerati “facili” per l’elevato livello di astrazione e per il numero di librerie disponibili. In Java ci sono decine e decine di tipi di dato, strutture e metodi tutti già pronti all’uso. In Python su PyPI c’è una libreria per fare ogni cosa.
Questo approccio porta le persone a considerare che, quale sia il loro obiettivo, troveranno la libreria giusta per farlo: non serve capire cosa fa, quanto è efficiente o i possibili problemi nell’utilizzo. Basta capire come farla funzionare e via.

E questo da un falso senso di semplicità, spostando l’attenzione dall’imparare come programmare all’imparare come si usano le librerie. Il che poi porta a casi del tipo (estremizzo):

“Mi fai la somma di questo array in Python?”
“Certo: array.sum()
“Me la fai con un for loop?”
“Ehhhh…”

Senza contare il fatto che, come mostravi tu, la scelta è talmente ampia che il problema diventa anche scegliere cosa usare. Molti alla fine si orientano sulla più popolare o quella meglio documentata, ancora una volta senza ricercarne/capirne i dettagli.

Parlo da studente almeno, poi lavorativamente parlando immagino entrino in campo tantissimi altri fattori per cui Java è così utilizzato. Anche se ho come il sentore che uno dei motivi principali sia il fatto che Java è li da 30 anni e le codebases si sono un po’ (troppo) solidificate.

2 Likes

Concordo.

Bisogna sempre ricordare che noi esseri umani siamo, prima di tutto, esseri emotivi, e questo fatto porta con se svariati “pregi” e altrettanti “difetti”.

Un qualcosa che può essere pregio o difetto di noi esseri umani, che tra l’altro è molto banale da osservare, è che naturalmente ci piace ciò che è famigliare. Prima ancora di mettersi li a discutere fatti, siamo attratti da ciò che conosciamo già. Siamo anche attratti dallo spendere la quantità minima di risorse per ottenere ciò che vogliamo.

Queste due caratteristiche (più altre ovviamente), diventano un cocktail fatale quando si impara a programmare.

Perché vedermi l’implementazione degli algoritmi di sorting (che alla fine non è neanche cosi complessa), quando posso chiamare una funzione sort() già implementata ed ottimizzata in qualsiasi linguaggio di programmazione decente?

Questo fatto è pur comprensibile in industria, che li il tempo veramente è denaro, e le scadenze vanno rispettate. Ma diventa disastroso quando si applica questo stesso ragionamento all’università, o peggio ancora nei bootcamp.

Ora ok, magari all’università ti fanno vedere come implementare un quick sort ed un merge sort. Ma a livello di programmazione pratica, a livello di toolchain, di gestione di progetti grossi (> 5k righe di codice), cosa ti insegnano? Poco e niente, nella mia particolare esperienza (se qualcuno ha esperienze diverse scriva!).

E quindi si creano generazioni e generazioni di “programmatori” abituati fin troppo ad usare scatole nere. Vogliamo chiamare costoro programmatori perché altrimenti qualcuno si offende?

Ok, però poi la conseguenza la paghiamo tutti.

Abbiamo bisogno di un vocabolario più ricco e sfumato e di una alfabetizzazione digitale migliore per cogliere tutta questo.

Altro che storia della filosofia. Abbiamo bisogno di imparare e insegnare filosofia della tecnica, come pensare alle tecnologie, alle astrazioni, alle conseguenze della iper-specializzazione e alle conseguenze di creare una società sempre più competente, si, ma sempre più complessa.

5 Likes

Io non sono un programmatore ma uso programmi soprattutto quello fatto per la PA e’ una vera monnezza e con java e’ un delirio xche’ a volte non le tengono aggiornate e magari hai un’app che funziona con java X ed una con java Y quindi ti lascio solo immaginare il bordello nel dover poi gestire sta roba !!!

Trovo che quello che hai detto sia esattamente quello che sta succedendo ed aggiungo che facendo cosi si incorre, come gia successo (log4j), in falle mega critiche ed incolpando i produttori della specifica libreria che magari e’ un ragazzo che l’ha fatto solo per scopo didattico o altro.

1 Like

Hai ragione ma non troppo xche’ poi diventa abitudine ed invece di produrre rapidamente del buon software produci solo monnezza che poi ti serve il doppio del tempo per mantenere !!!

Ho generato un pò di discussione ahahha, ammetto di aver scritto in modo un pò provocatorio di proposito.
Detto questo per la diffusione di java è principalmente marketing, in questo talk vengono spiegate un paio di ragioni (come al solito non prendetele come la verità assoluta, lo speaker è chiaramente di parte però è interessante).
Il fatto di ho un problemacerco una libreria per che lo fa per me equivale a dire, non so fare nulla, solo collegare i pezzi, per l’esperienze che ho avuto questo porta ad a creare software che non si sa neanche come funziona è tutto magico ed inspiegabile (sulla lunga causa burnout degli sviluppatori, fonte non istat ma personale).

Questa è un’altra delle grande bugie di java, la retrocompatibilità, pure qui java non è semplice da gestire, ci sono troppi build tool (maven, gradle, altri che non ricordo) non ufficiali, troppe opinioni diversi su come usare il linguaggio e su cosa è considerato idiomatico.
Il risultato è che spesso il codice scritto non è portabile da una versione all’altra (guardate quanti ancora sono fissi su java 8), il caso più eclatante l’ho visto nell’azienda in cui mi trovo ora, siamo fermi a java 8, con un framework davvero brutto (eclipse jersey), non possiamo passare ad una versione più recente che si rompe tutto.
La cosa bella sapete quale è, per qualche errore di configurazione (o peggio bug a causa della reflection) non si possono usare delle feature di java 8, niente lambda function, niente method reference, gli streams funzionano un pò ma senza i primi due componeneti sono molto macchinosi da usare.

3 Likes