Newsgroup: it.comp.lang.c++
Titolo: C++ senza puntatori?

Ho una domanda molto "filosofica" da porvi: secondo voi e' possibile
ottenere un linguaggio che dia il controllo a basso livello che da il
C++ senza utilizzare i puntatori?
Cerco di spiegarmi meglio: in C++ i tipi puntatore sono tipi veri e
propri, per i quali le uniche operazioni possibili sono il
dereferencing, l'assegnazione e il test di uguaglianza (in realta' in
C/C++ esiste anche l'aritmetica dei puntatori, ma questa puo' essere
emulata utilizzando il casting e sizeof).
Quello che mi interessa sapere e' se e' possibile eliminare
l'operazione di dereferencing in qualche modo, in quanto reputo sia
questa la principale causa di errore quando si ha a che fare con
puntatori.
Nota che l'approccio che usano Java, Python, ed in generale quasi
tutti i linguaggi moderni che non badano troppo all'efficienza, non va
bene: in questi linguaggi ogni variabile e' in realta un reference, e
quindi non si possono ad esempio avere membri di una classe che non
siano reference.
Invece un approccio naive che mi e' venuto in mente e' quello di
estendere i reference del C++: in C++ un reference e' solo un alias
per un oggetto, e non presenta nessuna operazione aggiuntiva rispetto
al tipo dell'oggetto stesso.
In realta' pero' un reference e' implementato come un puntatore
autodereferenziante; quindi e' abbastanza naturale pensare di
estendere i reference con
1) una operazione di assegnamento, che chiameremo binding (utilizzando
   ad esempio l'operatore ":>").
2) una operazione per il test di identita' (utilizzando ad esempio
   l'operatore "is").
Un esempio di quello che si potrebbe fare e' il seguente:
------------------------------------------------------------------------
int x = 10;
int y = 10;
int& rx :> x;  // binda rx a x
int& ry :> y;  // binda ry a y
rx == ry;      // true
rx is ry;      // false
rx = 20;       // assegna 20 a cio' a cui punta rx, cioe' x
x == y;        // false
rx :> ry;      // rebinda rx a quello a cui punta ry
rx is ry;      // true
------------------------------------------------------------------------
Uno dei problemi che salta subito all'occhio dato questo approccio e'
che non e' possibile avere piu' di un livello di dereferencing (in
pratica non possiamo avere un reference che faccia le veci di un
int**). 
Questo pero' non dovrebbe essere un problema se si modifica un po' la
semantica della chiamata a funzioni; ad esempio se le funzioni
avessero la possibilita' di avere piu' di un valore di ritorno, non
servirebbe piu' passare un "puntatore a puntatore" per fare in modo
che il chiamato possa modificare un binding del chiamante.
Un problema ben piu' grave e' che avendo ora 2 operazioni di
assegnamento, non si possono piu' avere tipi generici che possano
essere istanziati sia con tipi reference che con tipi non-reference.
Ad esempio:
----------------------------------------------------------------------
template <class Value> class Node
{
  Value val;
  Node *next;
  ...
  Node(Value v)
  {
    val = v;  // funziona solo se Value e un non-ref!
    ...
  }
  ...
}
Node<int> node(10);  // OK
int x = 10;
Node<int&> node(x);  // Errore: l'assegnamento in Node::Node avrebbe
                     // dovuto essere un binding!
----------------------------------------------------------------------
Intuitivamente sono giunto alla conclusione che se si vuole la
genericita' e il "controllo" che da' il C++, l'unica alternativa
elegante sia quella di avere dei tipi "puntatore" con un'appropriata
operazione di dereferencing.
Percaso qualcuno di voi sa indicarmi una possibile soluzione al
problema? Mi vanno benissimo anche link a documenti dove lo si tratta
(anzi, l'ideale sarebbe che qualcuno mi citasse un linguaggio che
faccia gia' quanto ho detto :-)
Ringrazio in anticipo per ogni aiuto che vorrete darmi, ciao 
-- 
Diego    | Per le repliche elimina dal mio indirizzo le 
Dainese  | `x' e inverti le due parole intorno alla `@'

 ha scritto nel messaggio
news:x7d7p4p...@benten.tomobiki.it...
