Il tutorial di Python è... difficile?!?

Ho tradotto in Italiano il tutorial ufficiale di Python. E mi sono reso conto con una certa sorpresa che... è maledettamente difficile, per un principiante! O forse è proprio Python a essere difficile, come non mi stanco di dire. Andiamo con ordine.

Prima di tutto, perché questa traduzione? Il fatto è che sto raccogliendo delle idee e dei materiali per un corso (che non farò mai, di questo passo) e chiaramente il tutorial ufficiale è una tappa obbligatoria. Sapevo che esisteva una vecchissima traduzione su Python.it, ma adesso è stata rimossa perché ormai superata. Ho deciso di farne una nuova perché tradurre è un ottimo modo per capire: ti costringe davvero a seguire riga per riga il ragionamento, a verificare se hai capito davvero, a dubitare e controllare e correggere le tue idee insieme al testo che hai sotto gli occhi.

Il vantaggio di questa nuova traduzione è che, a differenza di quella vecchia, è aggiornabile: prima di tutto, il sorgente è ospitato su GitHub, in modo che chiunque possa intervenire o continuare il lavoro anche se io dovessi lasciar perdere un giorno. Poi, la traduzione è fatta direttamente sui sorgenti della repository di Python: in questo modo è facile verificare quando un nuovo commit viene aggiunto all'originale e tradurre la parte corrispondente in Italiano, mantenedo le versioni sempre in sincrono. Di più: esistono (attualmente) tre versioni leggermente diverse della traduzione: quella "stabile" per Python 3.8, quella in "pre-release" per Python 3.9 e quella "di sviluppo" corripondente al master branch della repository di Python. Ciascuna di queste versioni può ricevere aggiornamenti indipendenti nell'originale.
Infine, oggi la tecnologia permette di gestire tutto questo in modo molto più semplice e potente: ReadTheDocs compila automaticamente i sorgenti Sphinx, ricavando non solo la versione in Html, ma anche quella in Pdf e in Epub. L'uso di Intersphinx permette di preservare i link alla documentazione, in modo che si possa usare il tutorial tradotto in modo identico all'originale. La manutenzione di tutto lo stack è praticamente automatica.

Comincia dal tutorial, dice...

Ma torniamo al tutorial in sé. Devo ammettere che ne avevo una conoscenza superficiale: sicuramente l'ho letto molto tempo fa, ed ero tornato su certi argomenti anche più di recente, ma nel frattempo sono state aggiunge intere nuove sezioni, molte cose sono cambiate. Il compito di tradurlo mi ha costretto a rileggerlo con attenzione con gli occhi del principiante... e devo dire che non è stata un'esperienza piacevolissima, ecco.
Innumerevoli volte, sui forum italiani e inglesi, puoi trovare il consiglio standard: vuoi imparare Python? Comincia dal tutorial. È anche un modo per filtrare le richieste: se non hai letto neanche il tutorial, non venire qui a chiedere come funziona una lista. Ed è giusto così, ci mancherebbe. Il tutorial esiste già, è gratis: leggerlo è il minimo richiesto. S'intende che il principiante resta sempre, immancabilmente, insoddisfatto da questo consiglio. Quello che vuole è la ricettina pronta da copiare: non vuole davvero capire come funziona una lista, vuole che qualcuno gli dica quello che deve fare con una lista per risolvere il suo problema del momento.

Ma supponiamo invece che davvero il principiante fiducioso si metta di buona lena a leggere il tutorial di Python. La verità è che potrebbe essere un esperienza sgradevole in molti punti. Come minimo, si può dire che il tutorial di Python sia molto più difficile di qualsiasi cosa noi oggi intendiamo come "tutorial". Questo non vuol dire che un principiante non ce la può fare: ma la curva di apprendimento è straordinariamente ripida per gli standard a cui siamo abituati. Anche senza scendere al livello di molti tutorial su YouTube (lo so... lo so: eppure è a questo che il principiante pensa quando si parla di tutorial), prendiamo Django come esempio di eccellenza. Il tutorial di Django, o anche quello delle Django Girls (disponibile perfino in Italiano), è un modello: prende un caso d'uso abbastanza interessante, lo sviluppa dal principio, semplifica senza banalizzare e rimanda alla documentazione specifica per gli approfondimenti. Si può argomentare che Django è una tecnologia limitata, per la quale è facile trovare un caso d'uso abbastanza rappresentativo. Ma ci sono anche altri modelli possibili per fare un tutorial.

Un tutorial o una demo?

La verità è che quello di Python è più uno showcase o una demo di un tutorial vero e proprio. Mette insieme decine di argomenti in un tour-de-force velocissimo, in cui nove volte su dieci ci si deve limitare a una breve descrizione e un esempio. Ma soprattutto manca di prospettiva, peccato capitale per un tutorial: non si capisce quando un argomento è essenziale e quando invece non c'è fretta di impararlo.
Alcune sezioni, come l'eccellente spiegazione sugli scope e namespace, sembrano messe lì in mancanza di un posto migliore nella documentazione. Altre sono chiaramente delle FAQ che non dovrebbero stare in un tutorial.
Altre ancora sono evidentemente delle integrazioni perché qualcuno avrà pensato, perché no, di documentare anche nel tutorial una feature aggiunta di recente. Così però si perde di vista la funzione essenziale del tutorial, quella di orientare il principiante. Non solo: con lo stesso criterio, talvolta invece a nessuno è venuto in mente di includere una feature nel tutorial. Solo che poi passano gli anni e quella feature diventa popolare, addirittura idiomatica: e finisce così che altre parti del tutorial vi fanno riferimento implicito, dimenticandosi che quella feature non è mai stata presentata.
Così si può arrivare a disastri spettacolari come quando, parlando di file, quasi di sfuggita si dice che "è buona pratica usare with (...). In questo modo il file verrà sempre chiuso al termine delle operazioni (...)". Peccato solo che da nessuna parte si possa trovare una spiegazione dei context manager. Così il tutorial si limita a raccomandare l'uso di with con i file, senza spiegare perché funziona in quel modo: un esempio da manuale di cargo cult programming.
Un altro esempio del genere è la mancanza di una spiegazione esplicita dei booleani, forse perché prima di Python 2.3 non esistevano. Se ne sente la mancanza in paragrafi come quello in cui si spiegano le condizioni degli if, dando per scontato che il lettore sappia già che cosa vuol dire che un valore è "vero" o "falso".
Un altro esempio ancora, manca una spiegazione di che cosa è il tipo di dati "bytes": a dire il vero qui penso che la ragione sia semplicemente che tutti lo danno per scontato. In ogni caso, il problema è che poi bisogna arrampicarsi sugli specchi quando si cerca di spiegare i metodi tell() e seek() di un file.
Alcune assenze, poi, sono veramente difficili da spiegare. Parlando di ereditarietà e di ereditarietà multipla, ogni paragrafo praticamente implora che ci sia una spiegazione di super(), e invece misteriosamente super() non viene mai spiegato.

Un altro problema è che la logica della demo è per molti aspetti opposta a quella del tutorial. Le sezioni di una demo vanno lette quasi simultaneamente, con molti richiami incrociati. Un tutorial dovrebbe procedere gradualmente: se un argomento richiede la conoscenza di cose più avanzate, o vi si rinuncia del tutto; oppure si anticipa l'indispensabile e si rimanda a futuri approfondimenti. Invece il tutorial di Python è pieno di anticipazioni implicite e collegamenti che mancano. Forse l'esempio più clamoroso è il capitolo sulle eccezioni, che per ragioni misteriose è collocato prima di quello sulle classi. La cosa buffa è che non c'è nessuna particolare ragione per questo ordine: sembra proprio una svista che si perpetua dalla notte dei tempi. Il guaio però è che quando si parla di eccezioni personalizzate senza aver chiaro come funzionano le classi... si va a sbattere forte.

Chi è il principiante, qui?

Ma forse l'aspetto che mi ha colpito di più mentre traducevo il tutorial sono gli innumerevoli passaggi in cui si dà per scontato che il lettore sia già "uno di noi". Non appena introduce le stringhe, non si fa problemi a dire che "i caratteri speciali sono resi con il backslash di escape": non riesce neanche a concepire un lettore che non sappia già che cosa vuol dire "escape" e perché si deve fare; un lettore che non abbia già fatto quel tipo di operazione in altri contesti.
Ci sono dozzine di piccoli name-dropping di questo tipo; e sono irritanti proprio come può esserlo qualsiasi name-dropping che in una conversazione ti fa sentire "fuori dal giro".  Ma è proprio questo il punto: il tutorial presuppone che il lettore faccia in qualche modo già parte di un giro. Talvolta immagina che possa avere qualche familiarità con C++ o Pascal (!); occasionalmente salta fuori un riferimento a una funzione C. Nell'insieme, non c'è niente di irreparabile, beninteso. Tuttavia è evidente che "il principiante" del tutorial di Python non è esattamente quello a cui pensiamo noi.

Soprattutto, il tutorial dà per scontato che il lettore abbia una radicata consuetudine con la shell Unix. Il punto di vista della shell Unix è talmente invasivo da produrre effetti quasi comici. Il capitolo introduttivo è già di una difficoltà allarmante, mentre dettaglia tutti i modi in cui si può usare Python dalla riga di comando e descrive il supporto per GNU Readline (!). Per chiarire il concetto, a GNU Readline (!) è dedicata anche un'appendice. Parlare di moduli eseguiti come script richiede solo poche righe, perché non c'è dubbio che i lettori sono già perfettamente a loro agio a eseguire programmi dalla riga di comando. Naturalmente non può mancare una descrizione separata di sys.argv e argparse.
Ma personalmente il punto che mi ha fatto più ridere è quando presenta sys e la prima cosa che si sente in dovere di descrivere è... come cambiare il prompt della shell con sys.ps1 e sys.ps2! Voglio dire, è davvero un'informazione essenziale da includere in un tutorial. E nell'esempio relativo non si fa neppure mancare lo sberleffo a Windows, che fa tanto guerrigliero Linux anni '90.

Parlando di Windows, vi farà piacere sapere che il tutorial... non ne parla. I pochissimi accenni presenti sono evidentemente aggiunti in tempi successivi e servono solo alle indispensabili informazioni di servizio. Ma più in generale il tutorial non menziona mai, neppure una volta, la possibilità di fare programmi Python con interfaccia grafica. Per chi lo ha scritto, è evidente che tutto il mondo di Python e la mentalità dei suoi sviluppatori ruota intorno alla riga di comando.

Ma più ancora di tutto questo, mi ha colpito l'habitus mentale dell'hacker che trapela di continuo: in molti passaggi si vede che l'autore non si fa problemi a scrivere in modo molto tecnico e sintetico, sfidando il lettore a stargli dietro. Non lo fa apposta, davvero: è solo che bisogna capire che il tutorial è scritto da programmatori per programmatori, non da insegnanti per allievi.
Il passaggio più esilarante in assoluto è quando parla delle docstring. Sta spiegando una cosa assolutamente semplice e innocua, ovvero come bisogna formattare le docstring: e di colpo si tuffa in una vertiginosa descrizione tecnica di come si dovrebbe implementare un parser di docstring. Bisogna leggerlo per crederci.
Ma è proprio questo il punto. Per quanto a noi possa sembrare surreale, in realtà per un hacker questo è il modo più semplice di spiegare. Per descrivere le regole di formattazione di un testo, non c'è modo migliore di implementare il parser per quel testo. Questo è il modo che un programmatore userebbe per spiegarsi con un altro programmatore.
Un altro esempio di questo tipo è quando spiega il meccanismo di lookup dei nomi dei metodi, e alla fine propone: "(...) può essere utile dare un'occhiata all'implementazione".  Ma ci sono anche altri passaggi del genere, tutti notevoli.

Come nota di costume un po' malinconica, aggiungo che fanno anche parte di questa mentalità hacker i numerosi riferimenti agli sketch dei Monty Python di cui il tutorial è costellato. Il problema non è solo che appesantiscono inutilmente il codice degli esempi e ormai nessuno li capisce più, al punto che revisori successivi si sentono in dovere di spiegare in nota le allusioni. Il vero problema è che oggi, semplicemente, nessuno utilizza più questo tipo di ironia nelle documentazioni tecniche. È una cultura che proviene dell'ethos hacker degli anni '70 e '80, ed è irrimediabilmente legata ai programmatori che si sono fatti le ossa in quell'epoca, come Guido e i core developers originari di Python. Oggi, anche solo scrivere qualcosa come "the_answer = 42" richiede una nota per spiegare il riferimento.

Comincia dal tutorial, comunque.

E quindi? Dopo averlo tradotto, mi sentirei ancora di consigliare tutorial di Python ai principianti?

Certamente sì. Si tratta comunque di un corpus di informazioni molto importanti, e per lo più accessibili (nonostante i dubbi che ho espresso fin qui).
Piuttosto, mi sembra che il problema sia sempre quello: negli anni c'è stato uno slittamento semantico del concetto di "principiante". Il tutorial di Python ha ancora in mente i principianti di vent'anni fa. Oggi, nel mio libro io dò per scontato che chi si accosta a Python semplicemente non ha idea di come usare la shell, e dedico i primi due capitoli a chiarire i preliminari.

Nonostante tutto, credo che il tutorial di Python vada bene così com'è (al netto di un po' di correzioni che magari proporrò). Credo che forse ci sarebbe bisogno di affiancargli un altro tutorial ufficiale, più selettivo e costruito con cura, più moderno e con un approccio più didattico: un tutorial preliminare, diciamo.
Ritengo che i principianti, anche quelli di oggi, possano comunque imparare tantissimo dal tutorial: l'importante è non si aspettino un percorso facilitato.

Commenti

  1. Da principiante fiducioso dalla lena affievolita mi sono trovato nelle sue parole. Addirittura, io sono arrivato al tutorial -a proposito, grazie per la traduzione; perché uno l'inglese lo sa anche, ma frustrarsi in lingua madre è tutta un'altra cosa- sperando comprendere meglio quanto sto affrontando con difficoltà in un corso per principianti. Auguri!

    Interessante quanto scrive sullo slittamento semantico della parola tutorial. Nella lingua, però, è l'uso a fare la norma. Se si scrive un tutorial, è all'uso corrente del significato della parola tutorial che ci si deve riferire, altrimenti...

    Grazie ancora,
    Ugo

    RispondiElimina

Posta un commento

Post più popolari