Tutti gli articoli

Il linguaggio che conosci conta ancora?

Ascolta l'articolo (sperimentale) · 09:46

00:00 / 09:46

Diversi flussi di codice fiochi, di forme diverse, che scorrono verso l'interno e convergono su un unico nodo ambra costante che resta acceso mentre i flussi cambiano intorno a lui

Hai passato anni a diventare bravo in un linguaggio. Ne hai imparato le regole, poi le abitudini, poi le piccole verità sgradevoli che si imparano solo mettendo in produzione cose scritte in quel linguaggio e guardandole rompersi. E adesso un modello scrive quel linguaggio fluentemente, e anche tutti gli altri, nel momento in cui glielo chiedi. Così arriva la domanda, in una qualche versione: continuo con quello che conosco o passo alla cosa verso cui si stanno spostando tutti? La paura che le sta sotto è più semplice della domanda. Gli anni hanno semplicemente smesso di contare?

Il linguaggio è due cose

C'è il linguaggio come battitura: la sintassi, la forma di un ciclo, dove vanno i punti e virgola. E c'è tutto quello che sta sotto: come gestisce la memoria, come gestisce due cose che succedono insieme, i modi di rompersi che appartengono a lui e a nessun altro, gli idiomi corretti e quelli che sembrano soltanto corretti, l'ecosistema e gli strumenti cresciuti intorno. L'AI ha reso economica la battitura. Il resto lo ha appena sfiorato, e c'è un motivo. Il resto non sta davvero nel testo. Vive nei sistemi in esecuzione e nella memoria di ciò che si è rotto, e un modello impara dal testo. Per questo la metà profonda non è solo sopravvissuta al cambiamento. È la metà che il cambiamento ha reso scarsa.

Guarda quali bug sono diventati più facili

Gli errori da cui la scioltezza superficiale proteggeva sono esattamente quelli che ora il modello evita e che il compilatore ha sempre intercettato: una parola chiave sbagliata, un pezzo di sintassi usato male, una chiamata a qualcosa che non esiste. Quello che resta sono gli sbagli che solo la profondità coglie: la falla di sicurezza che si legge come codice normale, la decisione di design sbagliata anche se ogni riga è a posto, il bug di concorrenza che non si vede su nessuna singola riga. L'AI ha ripulito gli errori economici e ha lasciato quelli costosi, e quelli economici erano l'unico tipo che la conoscenza superficiale abbia mai colto.

La profondità è un allarme che scatta da solo

C'è una sensazione che ogni sviluppatore esperto conosce. Nel linguaggio che conosci a fondo, il codice sbagliato fa scattare un allarme prima che tu sappia dire perché. Qualcosa nella sua forma non torna, così ti fermi e guardi. In un linguaggio che conosci solo a metà, quell'allarme non scatta mai. Il codice sembra plausibile, così lo accetti. Un modello produce codice plausibile per costruzione, pagina dopo pagina. I test intercettano una parte di quello che non va, e puoi puntare un secondo modello contro il primo, ma una suite verifica solo i fallimenti che qualcuno ha pensato di scrivere, e modelli addestrati sullo stesso codice condividono gli stessi punti ciechi. Alla fine la cosa che sta tra il plausibile e il corretto è un lettore il cui allarme funziona ancora. Quel lettore è qualcuno che conosce il linguaggio a fondo. Non c'è scorciatoia verso l'allarme.

Cambia per un motivo, non per un umore

I costi del cambiare si dividono nello stesso modo in cui si divide il linguaggio. Puoi scrivere codice dall'aria plausibile in un linguaggio nuovo lo stesso pomeriggio, e quella parte una volta richiedeva mesi. Gli idiomi, il runtime, il modo in cui questo particolare linguaggio fallisce, poco di tutto questo si trasferisce tra linguaggi estranei tra loro. Tra parenti stretti, linguaggi che condividono un modello di esecuzione, ne passa di più, ed è l'unica vera scorciatoia che esista. Il resto va comunque guadagnato. Quello che si trasferisce per intero è la parte che non ha mai riguardato il linguaggio: come scomponi un problema e come ragioni su un sistema.

Quindi cambia quando c'è un motivo vero, un dominio che lo esige, un lavoro che vuoi, un problema per cui il linguaggio è stato costruito, e non perché il rumore si è fatto forte. Alcuni domini decidono il linguaggio al posto tuo. Il lavoro real-time ed embedded non può permettersi un garbage collector che si ferma nel momento sbagliato, così i linguaggi di sistema possiedono quel terreno, e il browser è il browser; in entrambi i casi il linguaggio fa le veci di un modello di esecuzione che devi tenere in testa, e nessuna scioltezza da parte di un modello cambia quello che farà l'hardware. Il machine learning appartiene a Python per un motivo diverso, l'ecosistema, e l'effetto è lo stesso.

Prendi la mossa specifica su cui la gente si tormenta, restare su C++ o prendere in mano Rust. Discussa come quale linguaggio vince, non ha una risposta pulita e la discussione non finisce mai. Vista attraverso la profondità, c'è meno da discutere. Se conosci bene C++, gran parte di quello che Rust ti chiede, ragionare a fondo su ownership e lifetimes, è un peso che portavi già, solo che adesso il compilatore lo porta insieme a te. È più vicino a salire di livello che a ricominciare da zero. E la versione adulta della mossa di solito non è affatto un cambio netto, ma conoscere abbastanza di entrambi per lavorare dove ciascuno ha il suo posto. L'errore era trattarla come un aut aut.

Il mercato ha voce in capitolo

C'è un motivo in più per cambiare, ed è il meno romantico: la porta. Quanto conta l'etichetta sulla tua esperienza dipende da come guadagni. Costruisci un prodotto tuo e nessuno di quelli che lo comprano chiede in cosa è scritto. Aiuta gli altri a costruire il loro, consulenza, freelance, lavoro in agenzia, e lavori dentro il loro stack, quindi il tuo deve essere abbastanza vicino da farti ingaggiare. E nell'assunzione pura e semplice, l'etichetta può decidere tutto prima che un umano legga il tuo nome. Il filtro vuole anni di un framework specifico, e la profondità in un linguaggio adiacente non ti porta al colloquio.

Il mercato ha anche le sue stagioni. I linguaggi si gonfiano e si sgonfiano nella domanda su cicli che con il merito hanno poco a che fare, e uno stack che ha riempito un decennio di annunci di lavoro può ammutolire mentre uno che non hai mai toccato compare su ogni offerta. Non è un motivo per inseguire ogni stagione. È un motivo per sapere a quale gioco stai giocando. Se il tuo reddito passa dagli stack degli altri, tieni almeno un linguaggio che il mercato vuole in questa stagione, e usa la macchina per ciò in cui adesso è brava, portarti in fretta al plausibile in uno stack nuovo, mentre tu fai la parte che lei non può fare: costruire abbastanza profondità da difendere il codice al colloquio e dopo l'assunzione. La casella spuntata apre la porta, e la profondità è quello che ti tiene dentro.

Dove la profondità paga e dove no

Niente di tutto questo rende inutile l'ampiezza. Un secondo linguaggio, soprattutto uno che pensa in modo diverso dal primo, affina il modo in cui vedi il primo, e l'AI rende economico il dilettarsi, così girovagare ormai non costa quasi niente. Quello che ha perso valore è l'ampiezza come mucchio di sintassi, cinque linguaggi che sai battere e nessuno che sai difendere.

E la profondità non paga ovunque. Per uno script usa e getta, un po' di colla, un prototipo che cancellerai venerdì, il modello livella il campo e il linguaggio conta a malapena. La profondità si guadagna il posto nel codice che vive: il sistema maturo dove performance o sicurezza contano davvero, il codice che starai ancora mantenendo tra tre anni.

La parte scomoda è che le ripetizioni che costruivano la profondità arrivavano gratis con il lavoro, e adesso non più. Scrivevi i cicli da solo, incappavi nei bug economici, li sistemavi, e la profondità si accumulava come effetto collaterale. Quella parte adesso la fa la macchina, quindi le ripetizioni vanno scelte apposta. Fai il debug del codice generato invece di rigenerarlo. Leggi il diff come lo leggerebbe un reviewer. Rompi qualcosa di proposito per vedere come fallisce. La profondità prima ti capitava; adesso deve essere una decisione.

È un punto più vecchio che riaffiora: la produzione meccanica di codice non è mai stata ciò per cui venivi pagato, e adesso è la parte che fa una macchina. Quello che resta è il giudizio, e il giudizio nella programmazione non è indipendente dal linguaggio come ci piace fingere. In gran parte vive dentro un singolo runtime, imparato per la via lenta, costruendo cose al suo interno ed essendo lì quando fallivano.

Quindi gli anni hanno contato. La parte che ha perso valore non è mai stata quella che contava. La sintassi che hai memorizzato adesso vale meno, e non è mai valsa molto. Il modello del linguaggio che ti sei costruito sotto, abbastanza profondo da capire quando il codice generato ti sta mentendo, vale più di quanto sia mai valso. Impara un linguaggio abbastanza bene da poterne fare la review.

Le domande a cui questo articolo risponde

  • Resto sul linguaggio che conosco o passo a quello verso cui si stanno spostando tutti?

    Cambia quando c'è un motivo vero, un dominio che lo esige, un lavoro che vuoi, un problema per cui il linguaggio è stato costruito, e non perché il rumore si è fatto forte. Alcuni domini decidono al posto tuo: il lavoro real-time ed embedded non può permettersi un garbage collector che si ferma nel momento sbagliato, il browser è il browser, e il machine learning appartiene a Python per l'ecosistema. Se il tuo reddito passa dagli stack degli altri, consulenza o assunzione pura e semplice, tieni almeno un linguaggio che il mercato vuole in questa stagione, perché l'etichetta può decidere tutto prima che un umano legga il tuo nome.

  • Non basta far controllare il codice di un modello a un altro modello?

    No, perché modelli addestrati sullo stesso codice condividono gli stessi punti ciechi, e una suite di test verifica solo i fallimenti che qualcuno ha pensato di scrivere. Un modello produce codice plausibile per costruzione, pagina dopo pagina, e tra il plausibile e il corretto sta un lettore il cui allarme scatta ancora quando la forma del codice non torna. Quel lettore è qualcuno che conosce il linguaggio a fondo, e non c'è scorciatoia verso l'allarme.

  • Conosco bene C++. Passare a Rust vuol dire ricominciare da zero?

    È più vicino a salire di livello che a ricominciare da zero. Gran parte di quello che Rust ti chiede, ragionare a fondo su ownership e lifetimes, è un peso che uno sviluppatore C++ portava già, solo che adesso il compilatore lo porta insieme a te. La versione adulta della mossa di solito non è affatto un cambio netto, ma conoscere abbastanza di entrambi per lavorare dove ciascuno ha il suo posto, e l'errore è trattarla come un aut aut.

  • Come costruisco profondità adesso che la macchina scrive il codice di routine?

    Scegliendo le ripetizioni apposta, perché non arrivano più gratis con il lavoro. Scrivevi i cicli da solo, incappavi nei bug economici e li sistemavi, e la profondità si accumulava come effetto collaterale. Fai il debug del codice generato invece di rigenerarlo, leggi il diff come lo leggerebbe un reviewer, e rompi qualcosa di proposito per vedere come fallisce.