Newsgroup: it.comp.lang.c++
Titolo: Conversione implicita verso bool?

Sto scrivendo una classe che incapsula il concetto di "frazione", con i 
relativi operatori aritmetici e logici; mi e' sorto pero' un dubbio: e' 
una buona prassi includere un operatore di conversione a bool?
Ci sono dei buoni motivi sia da una parte che dall'altra:
- i tipi predefiniti forniscono tale operatore, quindi inserirlo 
rispetterebbe il principio di "minima sorpresa".
- in ogni caso una frazione NON-E' un bool, quindi una conversione 
implicita potrebbe portare ad errori accidentali. Inoltre tale 
conversione porterebbe ad una perdita di informazione (e questa non mi 
pare una bella cosa).
- IMHO la conversione int->bool (e le altre equivalenti per gli altri 
tipi built-in) e' sovrausata e porta a scrivere codice meno leggibile: 
sara' perche' provengo da molti anni di pascal, ma reputo molto piu' 
leggibile:
        if (num!=0)
piuttosto che:
        if (num)
L'unico caso in cui utilizzo la forma qua sopra e' quando ho a che fare 
con puntatori o valori bool.
Che ne pensate?
ciao Anto
-- 
Antonio Cuni, 19 anni, studente
Brainbench C++ Master: 4.6, higher than 98% of all previous test takers.
C Language: 3.32, higher than 79% of all previous test takers.
Guida C/C++ di Programmazione.it: 
http://cpp.programmazione.it

         if (num)
mah, sarà che lavoro in c++ da poco, e che provenivo direttamente dal basic,
ma trovo più leggibile la seconda... forse è meno facile da comprendere per
chi non ha gran confidenza, ma dopo è molto più comoda....
--
DGP85
May the Force be with you!

        if (num)
Io lo uso sempre e non solo in C++ e lo trovo molto leggibile, più del
num != 0.
-- 
                    Marco Barisione (ICQ 84277092)
Se sei interessato alla creazione di it.comp.lang (per i linguaggi di
programmazione senza un gruppo apposito e per i confronti fra i
linguaggi) partecipa alla discussione sul manifesto su it.news.gruppi.

        if (num)
Concordo.
-- 
The Follet

 num != 0.
ovviamente dipende dal contesto. Se uso "num" come valore booleano 
allora e' piu' leggibile la seconda, sarebbe meglio usare direttamente 
il tipo bool.
Se num e' un intero puo' essere che tu non voglia controllare il suo 
valore di verita', ma proprio il valore intero; ad esempio:
int dividi (int a, int b)
{
  if (b == 0)
    throw "Division by zero";
  return a/b;
}
IMHO e' molto piu' chiaro che non
        if (b)
non credi? Che poi tutti noi sappiamo che entrambe sono equivalenti e' 
un altro discorso, pero' la leggibilita' e' un'altra cosa.
ciao anto


 Concordo.
 
quindi mi suggerisci di *non* includere la conversione verso bool?


 non credi? Che poi tutti noi sappiamo che entrambe sono equivalenti e'
equivalenti?
spe, forse il sonno fa i suoi effetti, ma if (b) è esattamente il contrario
di if(b==0)

        if (num)
Personalmente preferisco la seconda per i confronti fra variabili bool
e la prima se si tratta di numerici(quindi la penso esattamente come
te) ma anche in questo caso la cosa non é ne meno leggibile ne errata,
una volta che si comprende che il risultato di un confronto é sempre
un espressione booleana.
Il Ghenio
-----
These are my parting words to you:
those who give up are doomed!
-----

 una buona prassi includere un operatore di conversione a bool?
Io non la metterei.
Ciao,
Nicola

 Che ne pensate?
Io tornerei true se il numeratore è diverso da 0. Altrimenti ritorno 
false. E' la cosa più logica e più simile a ciò che già esiste.
-- 
Luc.

 ciao Anto
Saluti, 
Fabio
-- 
Posted from 
flopiano.mm.eutelsat.org
 [194.214.173.28] 
via Mailgate.ORG Server - 
http://www.Mailgate.ORG

 Io non la metterei.
alla fine non l'ho messa. Date che grosso modo meta' delle risposte 
dicevano in un modo e meta' nell'altro alla fine ho fatto di testa mia 
:-)))


questione e' una frazione valida.
Non mi sembra una buona idea in quanto non č ciņ che si aspetta,
poiché "if (num)" non dą nessun errore di compilazione ci si
apetterebbe che si comporti come se num fosse un numero normale.




Perché? Se creo un nuovo tipo di dato numerico vorrei che si
comportasse nel modo più simile possibile a quelli built-in.


 comportasse nel modo più simile possibile a quelli built-in.
Ovvero? Puoi definire la conversione in bool in modi diversi,
rappresentando ad esempio il valore false come:
- Il numeratore vale zero (per analogia con gli int)
- Il denominatore vale zero (non e' una frazione valida)
- Il rapporto tra numeratore e denominatore vale zero (in modo che si
  comporti piu' o meno come i tipi floating point)
Come vedi non esiste una conversione "naturale".
Ciao,
Nicola

 apetterebbe che si comporti come se num fosse un numero normale.
Perche' dovrebbe dare un errore di compilazione ?
La validita' di un oggetto non e' definita a compile time, ma 
dipende dal suo stato, che normalmente cambia a run time.
Di solito per oggetti non primitivi, l'operatore bool viene definito
per indicare se lo stato dell'oggetto e' "buono" (es. per gli streams)
Certo se si considera l'oggetto "frazione" come un tipo primitivo,
il fatto di avere un operatore bool che vale "true" anche quando 
la frazione vale zero, potrebbe creare una "sorpresa".
Tuttavia, dato che gli oggetti "frazione" possono trovarsi in uno
stato inconsistente, potrebbe essere opportuno usare l'operatore bool
per verificarne lo stato.
Es.
        double f( Fraction frac ) throw BadFractionException
        {
                if ( ! frac )  throw BadFractionException();
                ...
        }
L'alternativa sarebbe aggiungere un metodo esplicito
        if ( ! frac.is_valid() ) throw ...
sicuramente meno "sorprendente" ma anche meno compatto e forse meno
uniforme, nel caso in cui l'operatore bool venga usato diffusamente anche
in altre classi del progetto per testare la validita' degli oggetti.


seconda per compattezza (e velocità).
Non c'e' nessun motivo per ritenere la seconda forma piu'
compatta e/o piu' veloce della prima.
-- 
The Follet

  comporti piu' o meno come i tipi floating point)
0 == 0 quindi false.


per verificarne lo stato.
Forse a questo punto sarebbe meglio non includere la conversione a
bool.
Non so, č una questione di gusti personali io tenderei ad usare "if
(num)" per vedere se č uguale o diverso da 0, forse a questo punto ha
ragione Nicola Musatti ed č meglio non includere la conversione a
bool.


comportasse nel modo piů simile possibile a quelli built-in.
Secondo me, non ha molto senso una conversione di una
frazione verso il tipo booleano.
Non c'e' un rapporto intuitivo tra un numero sotto forma di
frazione e un valore booleano true/false.
IMHO, tutto dipende dal contesto e dalla logica che vuoi
attribuire in quel contesto alla frazione.
-- 
The Follet

 compatta e/o piu' veloce della prima.
if (num!=0)  ---> 11 caratteri
if (num)     --->  8 caratteri
A me sembra più compatto (il sorgente, ovviamente)
8)
-- 
Luc.

 0 == 0 quindi false.
Nota che questo caso e' un estensione del precedente, a differenza del
quale si avrebbe valore false anche in quei casi in cui il risultato e'
zero per errore di approssimazione.
Ciao,
Nicola


Personalmente eviterei un operatore di conversione a bool.
Meglio definire gli operatori booleani fra la frazione ed un intero
(ossia num == k && den == 1 , supponendo la frazione ridotta ai
minimi termini).
In questo modo puoi scrivere if(num != 0).
Visto che ti piace di più sei a posto, tanto scrivere if(num) con
l'operatore di conversione a bool è equivalente sul piano delle prestazioni.
Ciao  Manlio Perillo

 questione e' una frazione valida.
pero' la tua tecnica farebbe un mix dei difetti di entrambi gli 
approcci: non rispetterebbe il principio di minima sorpresa (dato che 
si comporterebbe diversamente dai tipi built-in) e fornirebbe una 
conversione non voluta (dato che una frazione NON-E' un bool).
Cmq non potrei farlo neppure volendo, dato che se il denominatore e' 
uguale a 0 mi lancia una eccezione.


 uguale a 0 mi lancia una eccezione.
In realta' potresti lasciare la frazione cosi', e gestire diversamente
la conversione a intero piuttosto che a floating point. Nel caso
dell'intero potresti lanciare std::out_of_range, nel caso del floating
point (se sei su una piattaforma  che supporta seriamente lo standard
IEEE) potresti restituire l'infinito corrispondente.
Ciao,
Nicola

 una frazione NON-E' un bool
Neanche un int, un float ecc. è un bool ma la conversione viene fatta!
Non vedo proprio perchè non farla anche per una frazione che non è altro 
che un numero reale rappresentato dal rapporto di 2 numeri interi...
Se il rapporto da come risultato 0 allora il bool è falso. Questo è 
l'unico modo corretto.
-- 
Luc.

 prestazioni.
delle prestazioni non me ne sono preoccupato; l'obiettivo principale e' 
stato la chiarezza del codice.


Se il rapporto da come risultato 0 allora il bool è falso. 
E' questo il problema.  Come fai a stabilire che il
risultato e' 0 ?  Tieni presente che una frazione puo'
essere l'unico modo di rappresentare determinati numeri
reali in forma non approssimata (vedi 1/3, per esempio).
Un risultato reale, in una macchina, puo' essere
l'approssimazione di una frazione:
<CODE>
#include <iostream>
int main()
{
    double k = 1;
    bool b = k/10;
    int i;
    for (i = 1; b = (k /= 10); i++) ;
    std::cout << i << std::endl;
    std::cout << ((b) ? "true" : "false") << std::endl;
    std::cout << k << std::endl;
    char c;
    std::cin >> c;
    return 0;
}
</CODE>
In questo caso, sulla mia macchina, compilato con BC++B
ottengo i = 325, b = false e k = 0, ma k e'
l'approssimazione del risultato della frazione 1/10E325, che
NON E' zero.
Ho sbagliato qualcosa ?
-- 
The Follet

 una buona prassi includere un operatore di conversione a bool?
Dato che è un po' che sono assente mi sono perso la possibilità di
discutere la cosa in realtime. Quindi dopo una rapida scorsa al thread
vi dico la mia:
Se Rational non è convertibile in un altro tipo numerico allora non ha
senso l'operatore di conversione a bool. Se invece, come penso, è
possibile convertirlo in, diciamo, double, allora dovrebbe esserci anche
l'operatore di conversione a bool.
Il ragionamento non ha a che fare con i meriti e i demeriti delle due
sintassi
if ( r )
ovvero
if ( r!=0 )
ma semplicemente con il principio della minima sorpresa. Se il rational
è convertibile a double (e direi che questo ha senso) automagicamente la
sintassi
if ( r )
è accettata dal compilatore che eventualmente converte prima a double e
poi da double a bool.
A questo punto tanto vale che la cosa funzioni come ci si aspetta.
Secondo lo standard tutti i tipi aritmetici se convertiti a bool danno
false se valgono 0 e true altrimenti. Quindi persino un double che non è
un double valido (un NaN) converte a true.
Pertanto i Rational con denominatore 0 dovremmo consirerarli come i NaN
e non considerarli degli 0. Questo non è difficile perchè presumo che un
rational con denominatore 0 convertito a double dovrebbe essere appunto
un NaN. Il problema nasce con un rational il cui valore convertito a
double ... è troppo piccolo per essere rappresentato da un double
denormalizzato. In caso di conversione a double il risultato sarebbe
probabilmente un bello 0. Però il rational, fino a che è rational e non
è convertito a double, resta diverso da 0. Quindi ci si aspetta che
nella sintassi
if ( r )
questo dia true. Ma se questa sintassi si riduce ad una conversione a
double seguita da conversione a bool, il risultato è che otteniamo un
false. Per evitarlo io definirei un operatore di conversione a bool che
ritorna false se il numeratore è 0 e il denominatore è diverso da zero e
ritorna true in tutti gli altri casi.
--
Andrea Ferro
---------
Brainbench C++ Master. Scored higher than 97% of previous takers
Scores: Overall 4.46, Conceptual 5.0, Problem-Solving 5.0
More info 
http://www.brainbench.com/transcript.jsp?pid=2522556

 Ho sbagliato qualcosa ?
Ok, torno alla mia prima versione suggerita: se il numeratore è 0 il 
risultato è false. 
-- 
Luc.

 ritorna true in tutti gli altri casi.
E' tre giorni che tento di spiegarglierlo... 8)
-- 
Luc.


E' questo il punto. Una frazione puo' essere ricondotta al comportamento
di un intero, ovvero e' zero se il numeratore e' zero, oppure al
comportamento del numero reale, per quanto approssimato, che
rappresenta, ovvero vale zero se il rapporto *calcolato* vale zero (e
cosi' rispondo anche a The Follet).
Entrambe le ipotesi sono ugualmente valide, non esiste
un'interpretazione universale delle frazioni come booleani (anche
perche' anche quelle di int e float non sono universali: le ha inventate
Dennis Ritchie).
Ciao,
Nicola

 Dennis Ritchie).
In C++ esiste una interpretazione universale degli interi e dei floating
point come booleani. Indipendentemente da chi le ha inventate. Fa parte
dello standard!


 dello standard!
Ma questo non si estende ai tipi definiti dall'utente.
Ciao,
Nicola

Ciao, Antonio.
La verita' e' che la tua domanda non ha una risposta universale. I
costrutti che utiliziamo e creiamo ci servono a modellare aspetti della
realta'. Ogni modello non solo e' approssimato per definizione, ma e'
anche soggettivo, ovvero e' funzione dello scopo per cui e' realizzato.
Sta quindi a te individuare il giusto compromesso tra le ragionevoli
aspettative di chi usera' la tua classe, che come abbiamo visto non
saranno univoche, e l'approccio piu' pratico in funzione dello scopo per
il quale l'hai sviluppata.
Ciao,
Nicola

 Ma questo non si estende ai tipi definiti dall'utente.
No, ovvio. Ma anche il concetto di numeric_limits così come definito
dallo standard non si estende automaticamente ai tipi definiti
dall'utente.
Però direi che siamo partiti dall'idea di fare una classe che si
comporta il più possibile come se fosse un tipo intrinseco del
compilatore. Che qualche dettaglio non sia possibile (come sai i tipi
intrincechi sono gestiti diversamente dalle classi) è vero. Ma tutto
quello che si può fare(e che ci viene in mente, qualcosa può sempre
sfuggire) ha senso farlo. O no?


 Neanche un int, un float ecc. è un bool ma la conversione viene fatta!
la conversione viene fatta per compatibilita' con il C. Non sono nella 
testa di B.S., ma immagino che se non avesse avuto problemi di 
retro-compatibilita' la conversione int->bool non l'avrebbe messa. O, 
per lo meno, io non la avrei messa ;-).


 IEEE) potresti restituire l'infinito corrispondente.
il fatto e' che la mia classe, in realta', non rappresenta esattamente 
il concetto di "frazione", ma quello di "numero razionale"; ora, dato 
che 1/0 non e' un numero razionale, per la mia classe quello stato 
interno non ha senso.
Per quanto riguarda le conversioni, quella ad intero non e' neppure 
fornita, mentre quella verso double e' affidata ad un metodo, non ad un 
operatore.


 operatore.
Se non c'e' la conversione a double, allora ha anche senso non metterci
quella a bool (anzi: non ha senso mettercela se manca l'altra).
Che manchi una conversione a int mi può andare benissimo. Però si tratta
di filosofie. Se non metti la conversione a double e neppure a bool fai
una classe che è aritmetica ma non "parla" automaticamente con i
predefiniti. Quindi non definirei neppure la specializzazione per
numeric_limits. Viceversa se decidi di farla il più intercambiabile
possibile, metterei una conversione a double e specializzerei
numeric_limits. Però a questo punto metterei anche la conversione a bool
perchè tale conversione fatta automaticamente tramite la conversione a
double non si comporta come ci si potrebbe aspettare.


 anche l'operatore di conversione a bool.
e' possibile convertire Rational in double, ma attravero un metodo 
(to_double), non un operatore di conversione.
Ho scelto questo perche', in ogni caso, una conversione a double 
sarebbe nella maggioranza dei casi una conversione con perdita, quindi 
potrebbe sembrare fuorviante; per lo stesso motivo, alla fine, ho 
deciso di non includere neppure la conversione a bool (con buona pace 
di Luc che si e' dannato per farmi cambiare idea :-))).
A questo punto pero' si potrebbe aprire anche un subthread: escludendo 
gli ovvi motivi di retrocompatibilita', secondo voi ha senso la 
conversione implicita int->bool (stesso discoro per gli altri tipi 
numerici).
Quali i pregi? Quali i difetti?


 sfuggire) ha senso farlo. O no?
Io non sono partito da questo presupposto.
Il mio scopo principale era progettare una interfaccia il piu' 
possibile chiara, pulita ed elegante. A questo punto la domanda 
diventa: "E' piu' chiaro/pulito/elegante fare in modo che una classe si 
comporti come i tipi built-in oppure esporre solo i metodi che 
rappresentano nel modo migliore il concetto incapsulato dalla classe?"


 rappresentano nel modo migliore il concetto incapsulato dalla classe?"
La seconda direi che č comunque obbligatoria. Per la prima, questione di
filosofia e di gusti.
Come forse avrai notato fin dal mio primo post in questo thread ho detto
che SE non esiste la conversione a double ALLORA non ha neppure senso
chiedersi se permettere la conversione a bool. Viceversa SE esiste, la
conversione a bool č quasi necessaria (per il principio della minima
sorpresa).
Fra le due ... de gustibus ...


 Quali i pregi? Quali i difetti?
Dipende. Per come è gestito lo standard ha senso. Dal punto di vista
dello standard (che per inquadrare la cosa è abbastanza "functionality
oriented") i tipi predefiniti non sono semplicemente un elenco di tipi.
Sono in qualche modo classificati e organizzati secondo un concetto più
astratto (anche se, purtroppo, non in maniera OO). I tipi char, short,
int e long, con le loro varianti con e senza segno per un totale di 8
differenti tipi (nota: 9 perchè in termini di type system char è
distinto sia da signed char che da unsigned char, ma dal punto di vista
astratto char si comporta comunque come uno o l'altro quindi in termini
di astrazione matematica hai solo 8 combinazioni. Sempre che i sizeof di
char, short, int e long siano tutti differenti) sono in realtà tutti
raggruppati secondo l'astrazione di "integral types". Allo stesso modo
float, double e long double sono raggruppati sotto l'astrazione di
"floating point types". Tutti insieme sono considerati "arithmetic
types".
Questa metaclassificazione ha una ripercussione diretta. Poniamoci la
domanda: ha senso convertire da short a long? E da long a short? E da
unsigned a signed? E da signed a unsigned? E fra interi e floating
point? E da floating point a interi?
Ci sono due filosofie. Una è che le conversioni non si possono fare se
non esplicitamente (il fatto che non si possano fare con membri non
importa: di fatto un membro o una funzione non membro che prende come
parametro un oggetto sono la stessa cosa in questa prospettiva). Questa
è la prospettiva "data oriented" che ha fondamento matematico
nell'algebra (dove i numeri sono classificati in insiemi disgiunti e le
operazioni sono esplicitamente definite come mappaggi da un insieme ad
un altro). L'altra filosofia è quella "functionality oriented" che
invece considera tutti come numeri (con eventuali caratteristiche
peculiari) e definisce tutte le operazioni in termini di cosa
rappresentano in senso astratto. Il fondamento matematico ha come radice
l'aritmetica.
Nel primo contesto un numero va sempre considerato come parte di un
insieme. Il fatto che due insiemi possano intersecarsi (o essere uno
contenuto nell'altro) è comunque vero, ma un numero che appartiene a
entrambe gli insiemi è sempre considerato in un contesto specifico e
quindi si sa a priori se lo si sta considerando come appartenente a un
insieme o all'altro. Nel secondo
contesto un numero è un numero. E' una entità algebrica. Può avere o
meno una caratteristica.
Nel primo contesto 4 è un elemento sia dell'insieme dei numeri interi
che di quello dei numeri reali. La somma fra interi è una funzione che
mappa dall'insieme delle coppie di numeri interi all'insieme dei numeri
interi. La somma fra reali è una funzione che mappa dall'insieme delle
coppie di numeri reali all'insieme dei numeri reali. Si tratta di due
operazioni completamente distinte e che operano su insiemi completamente
distinti. Il fatto che l'insieme dei numeri interi sia completamente
contenuto (incluso) nell'insieme dei numeri reali non cambia
l'astrazione. Nel secondo contesto invece 4 è un numero così come lo è
2.7 o qualunque altro numero. Possiamo dire che 4 ha la caratteristica
di essere un numero intero mentre 2.7 non ha questa caratteristica. Ma
l'operazione di somma opera fra tutti i numeri secondo un certo
meccanismo più o meno "intuitivo" in termini di cosa rapresenta
l'operazione. E lo stesso per tutte le altre operazioni.
Ovviamente secondo la prima filosofia l'intero 4 e il reale 4 sono
distinti (o meglio: sono lo stesso oggetto ma in due contesti distinti).
Secondo la seconda filosofia 4 è un 4. Fine.
Tornando al C++ è evidentemente desiderabile che il linguaggio possa
supportare al meglio possibile entrambe le filosofie. Questo significa
permettere la conversione automatica in tutti i casi in cui questa ha un
senso/significato univoco. Se non è univoca serve una regola che
permette la conversione più corretta/sensata. Se questa regola non
esiste la conversione non deve avvenire. In realtà il C++ prende un
approccio misto fra le possibili soluzioni. L'idea è questa:
Il tipo int (doppia versione con e senza segno) è privilegiato come tipo
"fondamentale" nella famiglia degli interi. Il tipo double è
privilegiato come tipo fondamentale nella famiglia dei floating point.
In generale tutte le conversioni sono possibile se non ambigue. In caso
di ambiguità una conversione verso un tipo privilegiato che garantisce
la non perdita di informazione vale come regola di per risolvere
l'ambiguità.
Infatti lo standard chiama promozioni le conversioni verso uno dei tipi
privilegiati da un tipo per cui la conversione non perde informazione.
Chiama conversioni tutte le altre.
Una promozione è sempre automatica, se risolve l'ambiguità (fra una
conversione e una promozione si sceglie la promozione). Una conversione
è automatica solo se non è ambigua (fra due conversioni c'è ambiguità).
Tornando al bool (si potrebbe parlare anche di wchar_t, dei puntatori,
degli enum e dei bitfield, ma per ora non ci interessa) il booleano è
definito come un integral type. Ovvero fa parte della famiglia di char,
short, int etc. etc.
Un booleano si converte in un int per promozione. Si converte in un
qualunque altro tipo aritmetico per conversione (e viceversa: qualunque
tipo aritmetico può essere convertito in un altro tipo aritmetico per
conversione).
Le operazioni aritmetiche sono definite in maniera tale da poter agire
su tipi eterogenei inmaniera trasparente tranne che per questo aspetto:
operazioni fra interi non cambiano il tipo da intero a floating point ne
da signed a unsigned o viceversa e se gli operandi sono misti con e
senza segno, l'operazione avviene con segno.
Queste regole sono quelle più flessibili (non per forza più intuitive)
in un sistema a tipizzazione statica.
Diverso è l'approccio possibile in linguaggi che hanno tipizzazione
dinamica. In smalltalk per esempio la filosofia è al 99% "function
oriented". Qualunque operazione può essere eseguita su qualunque numero
e il risultato è quasi sempre quello migliore per quel caso. Se
dividiamo due interi il risultato è un intero o un razionale, a seconda
dei valori. Se eleviamo a potenza intera un intero il risultato è un
intero o un intero a precisione variabile a seconda del caso. L'1%
mancante è dovuto al fatto che un floating point non viene convertito
automaticamente in intero o in razionale anche se il valore lo
permetterebbe.
Detto questo, cosa fare per la classe Rational (o anche per la classe
vettore se lo si intende algebricamente, per esempio) dipende dalla
filosofia di chi la definisce. I tipi predefiniti prendono un approccio
misto con una certa tendenza alla visione "function oriented".


 misto con una certa tendenza alla visione "function oriented".
Questo saggio l'hai scritto tu a mezzanotte o è un taglia e incolla?
8)
-- 
Luc.

"Luc" <XXX...@katamail.comXXX> wrote in message
news:MPG.16545b0af...@news.enter.it...

L'ho scritto io in piena notte. Oggi non l'ho riletto ma non credo di
aver "pisciato fuori" di parecchio :-0


 aver "pisciato fuori" di parecchio :-0
Non intendevo quello... 8)
-- 
Luc.

 oriented".
ti ringrazio per l'esauriente spiegazione, che mi ha anche aiutato a 
capire meglio quello che in realta' mi frullava gia' in testa (per lo 
meno mi sono accorto di avere capito bene le lezioni di "Matematica 
Discreta" :-).
Alla fine propendo per la visione "data-oriented", che in effetti e' 
quello che mi serve per il mio programma. Semmai rimandero' a data da 
destinarsi il progetto di una classe piu' integrata con il resto del 
sistema.
