Tutti gli articoli

Restare bloccati è il punto

Ascolta l'articolo (sperimentale) · 11:50

00:00 / 11:50

Un percorso in un campo di codice salta due muri su archi fantasma e si aggroviglia al terzo, dentro un bagliore ambrato cerchiato di verde, uscendo più luminoso dall'altro lato

Ho imparato a programmare negli anni in cui restare bloccati era l'unica opzione. Una build che non compilava e un messaggio di errore che non indicava niente di utile. Un concetto che non ne voleva sapere di entrarmi in testa, per quante volte rileggessi la stessa pagina. Non che fossi solo con il problema. Per sbloccarsi c'era tutta una scala: rileggere la documentazione, più lentamente. Tirare giù dallo scaffale il libro consumato. Scavare in un progetto più vecchio che aveva risolto qualcosa di affine. Chiedere al collega della scrivania accanto, e se il muro sopravviveva a tutto questo, scrivere il problema con cura e pubblicarlo su un forum, poi aspettare, a volte per giorni, che rispondesse uno sconosciuto con le cicatrici giuste.

Oggi scrivo codice ogni giorno con due modelli al fianco, e l'intera scala è crollata in un unico piolo. Incollo l'errore e la risposta arriva prima che io abbia finito di formulare la mia ipotesi. È un'accelerazione reale, e quello scambio lo accetto tutte le volte. Ma ho passato più di un decennio a salire a mano la vecchia scala, e riesco a sentire con una certa precisione cosa smette di accadere in quel momento. Qualcosa girava nella mia testa tra un piolo e l'altro, e ora non ha nemmeno l'occasione di partire. Ho indicato quel qualcosa in articoli precedenti, sempre di sfuggita. Merita uno sguardo completo.

A cosa servivano le ore da bloccato

Restare bloccato non è mai stato tempo morto. Era lo stato in cui la mia immagine della macchina si correggeva più in fretta.

Ecco cosa succede dentro un bug che non ha senso. Hai in testa un'immagine di come funziona il sistema, e il sistema ha appena fatto qualcosa che la tua immagine dice essere impossibile. Allora fai esperimenti. Formuli un'ipotesi, la metti alla prova, la guardi fallire, correggi. Ogni tentativo fallito esclude un altro modo in cui la macchina potrebbe funzionare. Quando finalmente trovi il fix, il fix è quasi un dettaglio. Quello che hai fatto davvero è stato trovare il punto esatto in cui la tua immagine era sbagliata, e ridisegnarla.

Anche dentro il bug migliore, buona parte del tempo se ne va in giri a vuoto, in cose ribattute, in ovvietà ricontrollate. L'apprendimento vive nei momenti in cui un'ipotesi incontra la macchina e muore. Ma quei momenti non arrivano se non sei rimasto nella stanza per tutto il resto.

È per questo che ricordo ancora, a distanza di anni, il bug che si è mangiato una settimana, e non riesco a richiamare alla memoria una sola feature andata liscia. La feature liscia non ha mai toccato la mia immagine del sistema. Il bug l'ha ridisegnata.

I concetti che non ne vogliono sapere di entrare funzionano allo stesso modo. Ci giri intorno, provi un'inquadratura, la guardi crollare, ne provi un'altra. Quando l'idea finalmente atterra, atterra dentro una struttura che i tuoi tentativi falliti hanno costruito, ed è per questo che resta. Anche la lettura, la documentazione e la review correggono un'immagine, e io mi appoggio a tutte e tre. Ma una correzione tiene solo dove un tentativo le ha preparato il posto. La spiegazione che ricevi prima di aver faticato scivola via. La stessa spiegazione dopo venti minuti di ipotesi fallite atterra, e resta.

La vecchia scala era lenta, e quella lentezza non era tutta spreco. Per chiedere al collega o al forum dovevi prima comprimere il problema in una domanda a cui qualcun altro potesse rispondere, e la compressione da sola ne risolveva la metà. Chiunque abbia mai finito di scrivere un resoconto accurato e l'abbia cancellato senza pubblicarlo, con la risposta improvvisamente in mano, conosce l'effetto. Nemmeno il libro ti consegnava una risposta nuda e cruda; ti costringeva a leggere il capitolo che le stava intorno, ed è nel capitolo che i tre bug successivi venivano prevenuti. E mentre aspettavi una risposta, i tuoi esperimenti continuavano a girare, perché aspettare a mani vuote era insopportabile. L'aiuto esisteva a ogni piolo. Solo che arrivava abbastanza lentamente da lasciarti continuare a pensare nel frattempo.

La rimozione è silenziosa

Adesso metti un modello nel loop. La build si rompe, incolli l'errore, il fix arriva, vai avanti. Misurato in output è meglio su tutta la linea, e non fingerò il contrario. Il problema è che aspetto ha lo scambio visto da dentro. Niente in quel momento lo segnala. Il diff è identico a quello che avresti scritto dopo tre ore di fatica. La cronologia dei commit di chi capisce il sistema e di chi ha appaltato ogni muro è esattamente la stessa, fino al giorno in cui non lo è più.

Perché il codice non è mai stato il prodotto di quelle tre ore. Il prodotto era l'immagine corretta, e il codice era la sua ricevuta. Prendi la scorciatoia e la ricevuta la ottieni comunque, mentre l'immagine resta sbagliata in un modo che nessuna test suite farà emergere. Chi impara senza mai bloccarsi non è su una strada più veloce verso la stessa destinazione. È su una strada veloce verso un'altra, capace di produrre con scioltezza software di cui possiede un'immagine lacunosa, e le lacune si vedono solo il giorno in cui l'AI al suo fianco sbaglia e niente dentro di lui se ne accorge.

La versione nostalgica è sbagliata

Molto di ciò su cui sono rimasto bloccato non mi ha insegnato niente che valesse quelle ore. La caccia al punto e virgola mancante. La build rotta per un incidente d'ambiente che nessuno avrebbe potuto prevedere. Il flag non documentato, il mismatch di versioni, il pomeriggio perso dietro a uno strumento che era semplicemente fatto male. Quei muri mi hanno insegnato un po' di folklore del tooling, e il folklore del tooling è esattamente il carico che le macchine oggi trasportano meglio di quanto abbia mai fatto io. Dissolvere all'istante quel tipo di muro è ciò per cui gli strumenti esistono.

Le ore da bloccato che mi hanno costruito erano di un altro tipo, e distinguere i due tipi è l'intero articolo. Erano le ore in cui l'ostacolo era la mia stessa immagine sbagliata. Il sistema seguiva le proprie regole, la mia idea di quelle regole no, e la fatica era il processo con cui lo scoprivo. Un tipo era una tassa. L'altro era una retta universitaria.

Puoi distinguerli prima che arrivi la risposta, non solo dopo. Chiediti se il muro sta dentro il problema o accanto. Un mismatch di versioni sta accanto al problema: risolverlo non cambia niente di come scriverai il prossimo programma. Una funzione che restituisce un valore che la tua immagine dice essere impossibile sta dentro: risolverla cambia quello che sai. Nel dubbio, tratta il muro come se stesse dentro per venti minuti e guarda se la tua comprensione si muove.

Scegliere dove restare bloccati

La competenza ha quindi cambiato forma. Prima era resistenza, perché bloccarsi era obbligatorio ovunque. Ora è facoltativo ovunque, il che lo trasforma in un budget, e la competenza è saperlo allocare.

Il mio lo spendo con criterio. Quando il lavoro di retrieval che faccio per gli ambiti legale e sanitario si comporta in un modo che mi sorprende, ci entro a mano, perché la sorpresa significa che la mia immagine del sistema è sbagliata, e quello è il tipo di blocco che paga. La sorpresa però è un segnale che ti guadagni. Scatta solo dove esiste un'immagine dettagliata che la realtà può contraddire, ed è per questo che il test per principianti di poco sopra chiede del muro, non della sensazione. Quando un agente a cui ho delegato inciampa in un punto che avrei potuto prevedere, lascio che sia il tooling ad assorbirlo, perché non è rimasto niente che quell'attrito possa insegnarmi. La pipeline di delega che ho costruito esiste esattamente per potermi liberare dei muri da cui ho già imparato tutto. Quelli da cui non ho ancora imparato li scalo ancora da solo, di proposito, più lentamente di quanto potrei.

Delega senza sensi di colpa. Lo sviluppatore che si vergogna vagamente ogni volta che il modello lo sblocca ha l'inquadratura sbagliata, come se la virtù abitasse nell'attrito in sé. Non ci ha mai abitato. L'attrito è sempre stato solo il mezzo per arrivare all'immagine. Spendilo dove la tua immagine è ancora lacunosa.

E spenderlo non è sentimentalismo, è economia. Man mano che generare codice diventa a buon mercato, il lavoro che mantiene il suo prezzo è distinguere l'output giusto da quello sbagliato, e quel giudizio è fatto di immagini corrette. L'abitudine, poi, si trasferisce. Ogni bug che costringe un'ipotesi a confrontarsi con un sistema in esecuzione è una ripetizione dello stesso gesto che più tardi intercetta un suggerimento sbagliato in codice che non hai mai visto. Arriva un'affermazione sicura di sé, e qualcosa in te sa che va messa alla prova.

Se stai imparando adesso

Bloccati di proposito, e bloccati in piccolo. Scegli problemi dimensionati in modo che bloccarsi significhi venti minuti di pensiero vero, non un weekend perso. Quello che vuoi è un contatto frequente con la tua immagine sbagliata, in pezzi abbastanza piccoli da poterci lavorare fino in fondo.

Prima il tentativo, sempre. Scrivi la tua versione rotta, formula la tua ipotesi sul bug, poi fai entrare l'AI, e falla entrare come il tutor che rivede il tuo tentativo, non come l'autista che ti porta oltre il problema. Chiedile dove ha fallito il tuo ragionamento, non solo qual è la risposta. Discutici. La correzione del tutor atterra esattamente perché il tuo tentativo ha costruito il posto in cui incastrarsi. Salta il tentativo e le stesse frasi non insegnano niente.

Poi mettiti alla prova. Spegni l'AI e ricostruisci la cosa, e mentre la ricostruisci, di' perché ogni parte è lì, come se avessi accanto un collega che te lo chiede. La sola ricostruzione si può falsificare a memoria, ricordando i tasti che hai visto premere. Il perché no. Se sopravvivono entrambi, le ore da bloccato hanno fatto il loro lavoro e la comprensione è tua. Se non sopravvivono, hai in mano la ricevuta di un apprendimento mai avvenuto, ed è meglio scoprirlo adesso, su qualcosa di piccolo, che dentro un sistema con il tuo nome sopra.

Le macchine ti offriranno un'uscita da ogni muro per il resto della tua carriera, e il più delle volte dovresti prenderla. Molti muri sono rumore, e ripulire il rumore è ciò per cui gli strumenti esistono. I muri giusti sono dove si costruisce la tua immagine della macchina. Impara a distinguerli, rifiuta l'uscita davanti a quelli, e lascia che il muro faccia il suo lavoro. Restare bloccati davanti ai muri giusti è il punto.

Le domande a cui questo articolo risponde

  • Restare bloccati insegna davvero qualcosa o è solo tempo perso?

    È lo stato in cui la tua immagine della macchina si corregge più in fretta. Hai un'immagine di come funziona il sistema, il sistema fa qualcosa che quell'immagine dice essere impossibile, e formuli ipotesi finché una incontra la macchina e muore. È per questo che il bug che si è mangiato una settimana è ancora lì anni dopo e la feature andata liscia no: la feature liscia non ha mai toccato l'immagine, il bug l'ha ridisegnata.

  • Non è solo nostalgia per i tempi in cui si faceva tutto a mano?

    No, e la versione nostalgica dell'argomento è sbagliata. Molti muri di allora non insegnavano niente che valesse quelle ore: il punto e virgola mancante, il mismatch di versioni, il flag non documentato, il pomeriggio perso dietro a uno strumento semplicemente fatto male. Quelli insegnavano folklore del tooling, che è esattamente il carico che oggi le macchine trasportano meglio, e dissolvere all'istante quel tipo di muro è ciò per cui gli strumenti esistono.

  • Come capisco quali problemi risolvere da solo e quali passare all'AI?

    Chiediti se il muro sta dentro il problema o accanto. Un mismatch di versioni sta accanto, perché risolverlo non cambia niente di come scriverai il prossimo programma. Una funzione che restituisce un valore che la tua immagine dice essere impossibile sta dentro, perché risolverla cambia quello che sai. Nel dubbio, tratta il muro come se stesse dentro per venti minuti e guarda se la tua comprensione si muove.

  • Come si usa l'AI mentre si impara a programmare senza diventarne dipendenti?

    Bloccati di proposito e bloccati in piccolo, su problemi dimensionati in modo che bloccarsi significhi venti minuti di pensiero vero e non un weekend perso. Prima il tentativo, poi fai entrare l'AI come il tutor che rivede il tuo tentativo e non come l'autista che ti porta oltre il problema, e chiedile dove ha fallito il tuo ragionamento invece che solo qual è la risposta. Poi spegnila e ricostruisci la cosa dicendo perché ogni parte è lì, perché la sola ricostruzione si può falsificare a memoria ricordando i tasti che hai visto premere e il perché no.