[Soci SLIP] Da grande farò il programmatore

Lucio Crusca lucio a sulweb.org
Mar 19 Mar 2013 16:30:24 CET


Tento di iniziare con questo post una raccolta di suggerimenti per gli 
aspiranti programmatori e per quelli alle prime armi. Magari qualcun altro 
aggiunge cose interessanti o fa domande, e magari alla fine ne viene fuori un 
bell'articolo per il sito, o una serata, un corso, chissà. 

Sono informazioni che derivano dalla mia esperienza personale, cercherò di 
essere il più possibile "unbiased" (imparziale) e di dare informazioni utili 
indipendenti dalla particolare tecnologia o piattaforma scelta. Molte delle 
cose che scrivo qui sono in realtà prese in prestito da internet, poco o nulla 
è frutto di mie invezioni personali. Anche se prese in prestito, se le riporto 
qui significa che le ho trovate personalmente utili nella pratica.

L'ordine in cui espongo i suggerimenti è puramente casuale, così come mi 
vengono in mente.

1. Se un software esiste, qualcuno lo ha scritto e non è quindi opera di 
marziani. Se qualcuno lo ha scritto, posso fare altrettanto io. Questo è ciò 
che ha spinto la mia curiosità fin da quando avevo 12 anni, davanti al mio 
primo computer. Non pensate che i vari software che vedete in giro siano opera 
di gente fuori dal comune. È vero che noi programmatori per la maggior parte 
siamo strani, ma non siamo più dotati di tutti gli altri. La chiave è la 
curiosità, la voglia di scoprire come si fa.

2. A meno che non siate stati assunti nel team di ricerca e sviluppo di 
qualche multinazionale che si occupa di nanotecnologie, normalmente i problemi 
che incontrate durante la stesura dei vostri programmi sono già stati risolti 
da qualcun altro. Ciò ha almeno tre conseguenze:

2.1 il lavoro del programmatore all'80% si riduce al copia&incolla (a patto di 
aver capito cosa stiamo copiando)

2.2 se un nostro programma non funziona, qualcun altro ha già incontrato lo 
stesso problema e trovato la soluzione e spesso l'ha pubblicata su internet

2.3 esistono liberirie (ovvero pezzi di programmi già fatti) che servono a 
risolvere tutte le esigenze comuni a tutti i programmi. A noi programmatori 
dovrebbe restare solo il compito di scrivere il codice per le esigenze 
specifiche del nostro programma. Tradotto in parole più concrete, se per 
esempio vi trovate a scrivere del codice che serve a mettere in ordine 
alfabetico un elenco, di sicuro state scrivendo roba inutile, perché da 
qualche parte esiste già una libreria che lo fa e funziona meglio del codice 
che potremmo scrivere noi.

3. Se esiste una libreria che, se la usassi, risolverebbe un pezzo di quanto 
voglio implementare, conviene di più imparare ad usare quella libreria ed 
usarla, piuttosto che scrivere da me il codice necessario a risolvere quel 
particolare problema per evitare il tempo necessario ad imparare la libreria. 

4. (conosciuta come prima regola delle ottimizzazioni). Le ottimizzazioni non 
si fanno. Nota a margine: le ottimizzazioni sono quei processi di modifica del 
codice già scritto e funzionante, orientati a renderlo più veloce o meno esoso 
in termini di memoria richiesta, mantenendolo sempre funzionante. *

5. (conosciuta come seconda regola delle ottimizzazioni, solo per 
programmatori esperti). Le ottimizzazioni non si fanno. *

6. qualsiasi linguaggio va bene. Non importa se l'amico esperto vi dice che il 
linguaggio che usa lui e meglio o più semplice o più veloce o più figo in 
qualsiasi senso. Ogni programmatore è tanto più produttivo quanto meglio 
conosce lo strumento che usa, quindi se vi piace un linguaggio, studiatevi 
quello, studiatevi quali liberie ci sono per quel linguaggio e a cosa servono 
e siete a cavallo.

7. La 6 è falsa. O meglio, è vera, ma ci sono linguaggi più adatti a risolvere 
certi problemi e linguaggi più adatti a risolverne altri. Resta vero che ogni 
problema è teoricamente e praticamente risolvibile con qualsiasi linguaggio di 
programmazione. Se però usiamo un cacciavite per piantare un chiodo, per 
quanto sia possibile, rischiamo di metterci troppo tempo e di faci male. In 
ogni caso queste precauzioni sono da prendere solo per separare classi 
macroscopiche di problemi e relativi linguaggi. Esempio: se voglio programmare 
microcontrollori (arduino per dirne uno), non sceglierò mai Java, ma neppure 
Ruby nè PHP. Per quanto sia teoricamente possibile usare questi tre anche per 
programmare microcontrollori, non è ottimale. Allo stesso modo se voglio 
creare una web application, non sceglierò il linguaggio C nè il Fortran: anche 
qui sarebbe possibile, ma sub-ottimale.

8. I commenti nel codice sono obbligatori. Non importa quanto mi sembra ovvio 
quello che sto scrivendo nel mio linguaggio di programmazione preferito. Fra 
tre mesi sarà arabo anche per me che andrò a rileggerlo, anche se l'ho scritto 
io ed anche se l'ho scritto nel modo più ovvio possibile. È quindi necessario 
mettere dei commenti in italiano vicino al codice che sto scrivendo per dire 
*perché* scrivo quel particolare codice. Esempio di commento ben scritto:

  // verifico se l'utente è stato riconosciuto
  if (mUser != null)

Esempio di commento mal scritto e sostanzialmente inutile:

  // verifico se la variabile mUser è diversa da null
  if (mUser != null)

Se prevedete che in futuro il vostro codice possa esser letto da persone non 
italiane (tipico se sviluppate codice con licenza libera), conviene scrivere i 
commenti in inglese invece che in italiano.

9. Il computer non sbaglia mai. Le librerie che usate idem. Potrebbero essere 
bacate, certo, ma se siete aspiranti programmatori ed un vostro programma non 
funziona, la probabilità che a sbagliare siate voi è del 99,9999%, mentre la 
probabilità che si tratti di un baco della libreria è 0,00005%.  Il gap del 
restante 0,00005% riguarda il caso in cui di nuovo stiate sbagliando voi, e 
serve a convincervi di questo fatto quando il primo 99,9999% non è bastato. Se 
invece siete programmatori esperti, magicamente le percentuali riportate sopra 
non cambiano ed il discorso è identico...

10. Gli strumenti che usate per sviluppare software (compilatore, debugger, 
insomma tutto l'ambiente di sviluppo) normalmente vi dicono dove state 
sbagliando, ed in parte anche il perché. Ricordatevi di leggere e capire tutta 
la segnalazione di errore, prima di trarre conclusioni e prima di mettervi a 
cercare soluzioni al buio. Se non sapete che pesci pigliare, trascrivete 
l'errore su google togliendo i riferimenti specifici ai numeri di riga o ai 
nomi delle variabili del vostro codice.

11. Se non sapete cosa sia un debugger, imparatelo di pari passo a tutto il 
resto, perché vi salverà la vita.

*) La regola delle ottimizzazioni è frutto di varie considerazioni fatte dai 
programmatori di tutto il mondo. Desidero spendere qualche parola in più su 
questa, un po' per darle un perché ed un po' perché la tentazione di 
ottimizzare il codice è sempre forte, sperando di migliorarlo con poca fatica.

Da una parte le ottimizzazioni non fanno risparmiare quantità significative di 
tempo o di memoria, dall'altra il rischio è di ottenere un codice sì 
ottimizzato, ma non più funzionante perché applicando le ottimizzazioni spesso 
non ci si accorge che la versione ottimizzata del codice non è equivalente, 
nelle funzioni svolte, a quella non ottimizzata. Nella migliore delle ipotesi 
ci accorgiamo subito del danno, annulliamo le modifiche apportate con 
l'ottimizzazione ed avremo solo perso tempo. Nella peggiore, non ci accorgiamo 
del danno, perché magari il malfunzionamento che abbiamo introdotto non si 
manifesta sempre e se ne accorgeranno poi gli utenti del software. Se il 
software funziona, ma è lento o richiede troppa memoria, la soluzione è 
cambiare il computer. 

Ovviamente questo non vuole essere un incentivo a scrivere software 
irragionevolmente lenti o affamati di memoria, ma è una regola che si applica 
ai software già scritti e funzionanti. Se invece scrivete ex-novo, dedicate il 
tempo necessario a valutare la scrittura di un software che non richieda 
cariolate di moduli RAM e di CPU per funzionare. 

Anche in questo caso, però, è necessario distinguere le ottimizzazioni dagli 
algoritmi più o meno efficienti. Gli algoritmi sono procedimenti che risolvono 
problemi. Le ottimizzazioni sono solo limature che non fanno cambiare il 
procedimento (l'algoritmo).

Esempio pratico: supponiamo di dover prezzare e mettere davanti alle altre 
mille piantine di primule di un vivaio, le quali attualmente sono sparse e 
mischiate in mezzo a piante di altri tipi. Posso passare a prezzarle tutte e 
mille e poi ripassare a prenderle per metterle davanti. Sarei però più 
efficiente facendo il contrario, ovvero prima mettendole tutte davanti e poi 
prezzandole tutte. Questa è una scelta di algoritmo più efficiente e deve essere 
presa in considerazione in fase di progettazione e scrittura di nuovo codice.

L'ottimizzazione invece corrisponderebbe a ritagliare di misura la carta 
trasparente per impacchettare le piantine quando le vendo, in modo da non 
sprecarne, invece di utilizzare incartamenti universali per piantine di vario 
tipo, magari un po' abbondanti. Nel primo caso risparmio materiale, nel 
secondo risparmio tempo. Mentre chi gestisce un vivaio può scegliere l'una o 
l'altra, chi programma dovrebbe scegliere sempre la seconda, perché i bytes 
risparmiati con le ottimizzazioni non gistificano minimamente il tempo 
necessario a ritagliare correttamente il codice (i bytes costano circa zero, 
il tempo di un programmatore costa carissimo in confronto ai bytes, tanto che 
quei soldi li diano al programmatore quanto che siano semplicemente soldi 
persi a causa di ritardi sulla consegna).





Maggiori informazioni sulla lista Soci