venerdì 5 settembre 2008

“There is no worse danger for a teacher than to teach words instead of things”

Siamo tutti concordi nell'affermare che il C++ (assieme all'Haskell, un linguaggio funzionale di ultima generazione, molto elegante) sia uno dei linguaggi più difficili da imparare, e da padroneggiare in maniera decente. Pochi dicono, però che il C++ è anche un linguaggio estremamente difficile da insegnare. Come tutti gli insegnanti di un linguaggio di programmazione, anche io, poco dopo l'inizio di un tipico corso di C++ mi sono trovato al fatidico punto di presentare il classico “Hello World”:

// Program Hello World
// File main.cpp
//
// To build use: g++ -o HelloWorld main.cpp

#include <iostream>
using namespace std;

int main(int argc, char *argv[])
{
cout << "Hello, World!" << endl;
return 0;
}

Già presentare un codice “semplice” come questo ad una classe di neofiti presenta delle enormi difficoltà. Da dove partire?
Qui le vie da seguire sono sostanzialmente due. La prima è quella di dire che molti degli oggetti presenti in queste 13 righe di codice verranno introdotti più avanti nel corso. La seconda è quella di spiegare ogni singolo oggetto che compone questo piccolo programma. Supponendo che si sia già spiegato cosa sia un Compilatore ed un Linker, e quale sia la differenza tra un programma interpretato ed uno compilato, bisognerebbe allora partire a spiegare in concetto di Translation Unit per poter introdurre il significato della parola chiave #include (il solo parlare del preprocessore del C++ richiederebbe un corso a parte). Il prossimo passo sarebbe poi quello di spiegare cosa sia una libreria (come quella che contiene iostream) e quindi l'utilità del lavoro svolto dal Linker. Si passerebbe poi a parlare di namespaces, ma per fare questo bisognerebbe parlare anche di “scopo”. A questo punto inizieremmo a fare i primi passi in quel territorio immenso che sono le funzioni per parlare di quella particolare funzione “main” e spiegare cosa sia l'entry point di un programma. Quindi inizieremmo a parlare delle differenze semantiche e sintattiche tra dichiarazione e definizione, tra parametri ed argomenti, quali sono i sistemi di passaggio degli argomenti ad una funzione visti sia dal punto di vista del programmatore sia dal punto di vista del compilatore e quale è l'ordine di lettura usato da una funzione per analizzare i suoi parametri (non vogliamo spendere un po' di tempo a spiegare anche il concetto di variabile?).
Scegliendo questa seconda via dovremmo poi parlare di operatori e di quale sia il significato di overloading, quindi del perché io posso usare lo stesso simbolo grafico per dire al compilatore di eseguire un'operazione di shift a sinistra su una serie di bit oppure di indirizzare un certo dato su uno stream di output. Ma allora a questo punto bisogna anche dire cosa sia uno stream e che ruolo giocano questi oggetti nel sistema I/O del linguaggio C++. Rimane ancora qualcosa da spiegare per far capire ad un neofita il significato di queste 13 linee di codice?
Ogni insegnante segue la sua via. Avendo il tempo necessario, io preferisco sicuramente la seconda. Prendendo come riferimento la frase di Stroustrup del post precedente, io preferisco spendere almeno un paio di giorni di lezione ripercorrendo la storia e le idee che hanno portato allo sviluppo del C++.
Spiego a fondo l'enorme importanza di seguire strettamente lo standard ISO/IEC, perché solo chi conosce a fondo e con maestria lo standard, può trascendere lo standard. Di questi programmatori ne esistono molto pochi e forse veramente solo Stroustrup può permettersi e soprattutto può osare, di trascendere questo standard. Chiunque altro dimostrerebbe solo presunzione (nella migliore delle ipotesi...) o ignoranza del linguaggio (...nella peggiore). Seguire uno standard non è un freno alla creatività, anzi fornisce delle basi solide sulle quali adagiare i pensieri della nostra fantasia. Ricordiamoci che un linguaggio di programmazione, non è solo descrittivo e formale, ma è anche espressivo (quando gli ingegneri inizieranno ad accorgersi di questo?).
Scegliendo la prima delle due vie descritte qui sopra, mi sembrerebbe un po' di correre il rischio paventato nella frase di Marc Block che titola questo post. Una parola può cambiare l'universo se sostenuta dalla verità, ma è solo vuoto se non serve a trasferire o creare significato.

Luca Ciciriello

Nessun commento: