PDA

View Full Version : [qualsiasi]salti condizionali


RaouL_BennetH
02-04-2007, 14:35
Ciao a tutti :)

Mi sto sconfortando perchè non riesco ad organizzare in modo logico una serie di scelte che il programma dovrebbe fare in base a delle condizioni.

A prescindere dal tipo di linguaggio che sto utilizzando, ho difficoltà di questo tipo nel modo di pensare:


//devo prima verificare che determinati valori non siano nulli, per esempio:

if(valore1 != null)
{
//istruzione
}
if(valore2 != null)
{
//istruzione
}


Fin qui, tutto chiaro (come concetto)
Ora, però mi trovo ad affrontare una catena orrorifica di "if" dato che quando verifico il primo valore, poi devo anche verificare altri due `subvalori`, per es.:


if(valore1 != null && subvalue1 != null)
{
//istruzione
}
if(valore1 != null && subvalue2 != null)
{
//istruzione
}
if(valore1 != null && subvalue3 != null)
{
if(subvalue2 > subvalue1)
{
//istruzione
}
else if(subvalue5 <= subvalue1)
{
//istruzione
}
}

//etcetera...



Capisco da solo che è un modo orrendo di `pensare`.

Mi dareste una mano a migliorare?


Grazie mille :)


RaouL.

andbin
02-04-2007, 14:54
Ora, però mi trovo ad affrontare una catena orrorifica di "if" dato che quando verifico il primo valore, poi devo anche verificare altri due `subvalori`

Capisco da solo che è un modo orrendo di `pensare`.

Mi dareste una mano a migliorare?Beh, se è proprio quello che devi fare non è che ci siano molte altre strade .....
Al massimo visto che il test valore1 != null l'hai ripetuto più volte, potresti racchiudere tutto in un unico if (valore1 != null).

71104
02-04-2007, 15:06
ricorda che la validità dei parametri va verificata solo se provengono da fonti non fidate, come librerie esterne non del sistema operativo o dall'input dell'utente. mi sento di doverlo specificare perché al corso di programmazione 2 c'era una professoressa che diceva che i parametri delle funzioni vanno verificati SEMPRE (con anche il grassetto, o urlando a squarciagola se lo diceva a voce :asd: ), cosa palesemente falsa :Prrr:

RaouL_BennetH
02-04-2007, 15:16
Innanzitutto, grazie per le risposte :)

@ 71104: si tratta di input utente, quindi devo per forza di cose verificarne la validità :)

@ andbin: quindi dici che purtroppo non ho molte strade da seguire, ma credo che questo derivi dal fatto che non ho esposto troppo bene il problema :( Faccio un pò di `analisi` e poi sono sicuro che mi segnalerai al daily wtf :D

Mentre leggevo le vostre risposte, ho però pensato a:

e se usassi `switch\case` ?

andbin
02-04-2007, 15:23
Mentre leggevo le vostre risposte, ho però pensato a:

e se usassi `switch\case` ?Dipende da cosa devi testare. A seconda del linguaggio in genere lo switch è limitato a certi tipi di dati. Ad esempio in Java puoi usare solo byte/char/short/int (e i relativi wrapper) e gli enum, non certo stringhe o altri reference.

71104
02-04-2007, 20:12
Dipende da cosa devi testare. A seconda del linguaggio in genere lo switch è limitato a certi tipi di dati. Ad esempio in Java puoi usare solo byte/char/short/int (e i relativi wrapper) e gli enum, non certo stringhe o altri reference. anche boolean penso... ovvio però che non ha molto senso :D

switch (flag)
{
case true:
case false:
default: // lol?
}

andbin
02-04-2007, 20:21
anche boolean penso... No, in Java non è ammesso nello switch.

Fede_Reghe
02-04-2007, 20:23
Potresti fare uno switch sulle sub, ma non avrebbe molto senso... Ti conviene usare gli if come hai fatto...

P.S: non è necessaria la default: :sofico:

^TiGeRShArK^
03-04-2007, 00:23
public class ProvaIf {

public ProvaIf() {
String a = "";
String b = null;
String c = null;
String d = null;
if (a != null) {
try {
Class.forName("B" + b).newInstance();
Class.forName("C" + c).newInstance();
Class.forName("D" + d).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
}
}


public static void main(String[] args) {
ProvaIf p = new ProvaIf();
}
}


public class Bnull {

public Bnull() {
System.out.println("B null");
}
}


public class Cnull {

public Cnull() {
System.out.println("C null");
}
}


public class Dnull {

public Dnull() {
System.out.println("D null");
}
}

Ecco un esempio di come NON usare la reflection :asd:

RaouL_BennetH
03-04-2007, 11:02
:) Grazie a tutti per i suggerimenti, ma, tra poco dovrei aver finito l'horror code.

Quando lo termino, lo posto, in modo da essere sicuro di potervi far morire dal ridere per i prossimi 5 lustri :p

pisto
03-04-2007, 15:27
ma tipo fare una matrice/array di Method? (parlando di java)

PGI-Bis
03-04-2007, 16:09
Per sfruttare il collegamento dinamico deve prima ricondurre l'insieme di condizioni ad un identificatore. Un hashing, in pratica. Roba tipo:

actions.get(valore1, valore2, subValue1, subValue2, subValue3).execute();

Il "get" non deve essere definito tramite "if" o analoghi, se no è un barbatrucco.

Tutto sta nel trovare una funzione di hashing che riesca ad indentificare un'azione considerando non il valore assoluto dei parametri ma le loro disuguaglianze.

RaouL_BennetH
03-04-2007, 16:18
Ecco, adesso state cominciando a spaventarmi :p

71104
03-04-2007, 17:21
ma tipo fare una matrice/array di Method? (parlando di java) ma caro Andrea (:p:p:p), e come indici cos'hai intenzione di usare, i null? :D

pisto
03-04-2007, 17:43
ma caro Andrea (:p:p:p), e come indici cos'hai intenzione di usare, i null? :D

se è una battuta non l'ho capita:eh:

71104
03-04-2007, 18:56
se è una battuta non l'ho capita:eh: cosa usi come indici per accedere agli elementi della matrice?

PGI-Bis
03-04-2007, 18:59
Ecco, adesso state cominciando a spaventarmi :p

Non c'è nulla di cui spaventarsi :).

Supponiamo un caso semplice. Cioè usiamo Java :D.

Hai due riferimento, a e b. Vuoi fare qualcosa in corrispondenza delle condizioni:

a != null e b != null
a == null e b == null
a = null e b != null
a != null e b = null

Non è bizzarro pensare, come ha fatto pisto, di avere un array di 4 oggetti, diciamo 4 Runnable (lasciamo da parte la riflessione ma si potrebbe usare anche quella per rendere l'ambaradan ancora più generico). I 4 Runnable nell'array sono indicizzati. Tutto quello che devi fare è stabilire un qualche genere di funzione che data una coppia di riferimenti trasforma l'unione dei loro valori in un numero intero da 0 a 3.

Ad esempio (molto teoricamente e detto da uno per cui la matematica è uno stato d'animo :D):

int hash(Object valueA, Object valueB) {
int hashA = System.identityHashCode(valueA);
int hashB = System.identityHashCode(valueB);
hashA = (3 * hashA) / (2 * hashA);
hashB = (3 * hashB) / (2 * hashB);
return hashA + 2 * hashB;
}

Basandoti su una comprovata (e non quella) funzione di hash che faccia quanto su detto, puoi creare senza difficoltà una struttura tipo:

public class DecisionMap {
private static final class Condition {};
public static final Condition NULL = null;
public static final Condition NOT_NULL = new Condition();
private Runnable[] runners = new Runnable[4];

public void set(Runnable r, Condition valueA, Condition valueB) {
runners[hash(valueA, valueB)] = r;
}

public void decide(Object valueA, Object valueB) {
runners[hash(valueA, valueB)].run();
}

private int hash(Object a, Object b) {
int hashOne = System.identityHashCode(a);
int hashTwo = System.identityHashCode(b);
hashOne = (3 * hashOne) / (2 * hashOne + 1);
hashTwo = (3 * hashTwo) / (2 * hashTwo + 1);
return hashOne + 2 * hashTwo;
}
}

e usarla ad esempio:

public class Main {

public static void main(String[] args) {
class Printer implements Runnable {
private String text;
Printer(String text) { this.text = text; }
public void run() { System.out.println(text); }
}
DecisionMap map = new DecisionMap();
map.set(new Printer("null, null"),
DecisionMap.NULL,
DecisionMap.NULL);
map.set(new Printer("null, not null"),
DecisionMap.NULL,
DecisionMap.NOT_NULL);
map.set(new Printer("not null, not null"),
DecisionMap.NOT_NULL,
DecisionMap.NOT_NULL);
map.set(new Printer("not null, null"),
DecisionMap.NOT_NULL,
DecisionMap.NULL);

map.decide(null, "hello");
map.decide(2, null);
map.decide("hello", "world");
}
}

Tutto sta nel ricondurre caratteristiche note a valori noti ed eseguire poi un calcolo dall'esito... noto :D L'arte di sapersi spiegare :D.

Non so quanto sia conveniente a livello di conti fatti dal PC. Ma se ti stanno antipatici gli if penso che l'unica alternativa sia l'hashing.

lovaz
03-04-2007, 19:00
E perché non togliere tutti i controlli e poi
catch di NullPointerException?

Certo bisognerebbe vedere il codice...

:mc:

71104
03-04-2007, 19:48
@PGI-Bis: la versione con la matrice sarà anche più efficiente, ma obiettivamente quella con gli if occupa molte meno righe di codice... :|

RaouL_BennetH
03-04-2007, 19:50
Certo bisognerebbe vedere il codice...

:mc:

mmm.. mi sa di no ... mi vergogno :eh:

Però tenete presente che sono un principiante, quindi siate comprensivi....

Premessa:

tutto questo casino che sto cercando di fare (ma con il solo scopo di iniziare a crearmi dei problemi e vedere se riesco a risolvermeli) nasce dal fatto ho un oggetto `griglia` composto da:

entrata1, uscita1, entrata2, uscita2, totale, totaleSingolo, Ordinario, Festivo, Notturno, TotaleEuroGiornaliero:

Ora.. devo fare in modo che :

1) se entrata1 ed uscita1 non sono vuoti, la cella corrispondente nella colonna 'totale' mi faccia un calcolo

2) se entrata2 e uscita2 non sono vuoti (ma sono vuoti entrata1 e uscita1), la cella corrispondente a totale mi faccia un altro calcolo

3) e non sono vuote tutte e quattro, mi faccia un calcolo fra uscita2 e uscita1.

4) se sono vuote tutte e quattro, devo vagliare solo totaleSingolo.

Inoltre... se:

1) Ordinario = 1; totaleGiornaliero faccia "totale (o totaleSingolo) * 6

2) Festivo = 1; vuol dire che ne Ordinario ne Notturno sono uguali a 1, e quindi devo fare: totaleGiornaliero = (totale o totaleSingolo) * 12

etc....

E ancora, appena una cella perde il focus, devo:

fare il parsing del testo immesso dall'utente e validarlo
se non è valido formattarlo..

dopodichè, ecco a voi il mio horror code:



//il programma è scritto in C#, ma credo che non sia scritto come se fosse C#



private void TestMethod(DataGridViewCellEventArgs e)

DateTime dt1, dt2, dt3, dt4;
bool b1, b2, b3, b4;

if(griglia.Rows[e.RowIndex].Cells[2].Value != null)
{
for(int r = 3; r <= 12; r++)
{
griglia.Rows[e.RowIndex].Cells[r].ReadOnly = true;
}
}

if(griglia.Rows[e.RowIndex].Cells[entrata1].Value != null &&
griglia.Rows[e.RowIndex].Cells[uscita1].Value != null)
{
b1 = DateTime.TryParse(griglia.Rows[e.RowIndex].Cells[entrata1].Value, out dt1);

b2 = DateTime.TryParse(griglia.Rows[e.RowIndex].Cells[uscita1].Value, out dt2);

if( dt1 > dt2 )
{
TimeSpan ts = dt2.AddHours(24) - dt1;
griglia.Rows[e.RowIndex].Cells[totale].Value = ts.ToString();

if(griglia.Rows[e.RowIndes].Cells[Ordinario].Value != null)
{
griglia.Rows[e.RowIndex].Cells[totaleEuroGiornaliero].Value = (ts.Hours + (ts.Minutes / 60 )) * 6;

}
else if (griglia.Rows[e.RowIndex].Cells[Festivo].Value != null)
{
griglia.Rows[e.RowIndex].Cells[totaleEuroGiornaliero].Value = (ts.Hours + (ts.Minutes / 60)) * 12;
}

//e questo solo nel primo caso e nel primo sottocaso in cui dt2 è < di dt1
//immaginate cosa sono riuscito a combinare per tutti i casi.... :D

}



Oltre ad una profonda vergogna che mi impone di non continuare a postare il codice..... vi prego di farmi letteralmente a pezzi senza nessuna pietà :(


RaouL.

PGI-Bis
03-04-2007, 21:04
Non è che il codice sia poi tutta 'sta schifezza. L'alternativa è chiamare griglia g, righe rs, colonne c e valore v, così puoi dire grscv che non si capisce una fava ma fa tanto C++ :D.

Se Griglia è una Griglia, non sarebbe strano darle un metodo getValue(int row, int col).

if(griglia.getValue(e.rowIndex, entrata1) != null) {

Il succo resta quello ma almeno abbrevii un po'. Potresti anche separare la parte in cui decidi cosa fare da quella dove lo fai usando un metodo privato.

if(griglia.getValue(e.rowIndex, entrata1) != null) {
calcolaSommaDiBlaBla();
}
if(...) {
calcolaSommaDiBluBlu();
}
...
private void calcolaSommaDiBlaBla() { ... }
private void calcolaSommaDiBluBlu() { ... }

Si tratta comunque di mere questioni "estetiche".

pisto
03-04-2007, 23:21
cosa usi come indici per accedere agli elementi della matrice?
magari un'hash o un numero arbitrario che assegni ai parametri che non sono di tipo numerico.
in pratica quellòo che ha detto pgi-bis se ho capito bene (non ho letto fino in fondo il suo messaggio)

NetSpa
04-04-2007, 10:49
Potresti implementare il pattern "Null Object"

Vedi qui a questo link di cosa si tratta: http://www.cs.oberlin.edu/~jwalker/nullObjPattern/

é il primo link trovato al volo con google, ma cerca anche tu, potresti trovare documentazione migliore.

^TiGeRShArK^
04-04-2007, 15:31
ehmm..
non mi pare il suo caso quello.
Se ho capito bene dal link postato avrebbe comunque necessità di verificare che l'oggetto sia instanceof Nullable.
Invece con il metodo di pgi (o anche col mio orrido modo di usare la reflection :asd: ) non c'è bisogno di alcun if.
Sempre se ho capito qual'è l'intento del Null Object Pattern :p

lovaz
04-04-2007, 18:12
...
dopodichè, ecco a voi il mio horror code:
...

Insisto, perché non togliere i controlli per null?
Non conosco C#, con java verrebbe lanciata una NullPointerException,
che si può "neutralizzare".

O sono io che non afferro bene il concetto! :fagiano:

PGI-Bis
04-04-2007, 18:26
Usare un'eccezione come condizione è come salutare la compagna di un primo appuntamento con un cordiale "ciao cesso".

C'è un significato comunemente percepito che può essere diverso da quello intenzionale.

Nel caso delle eccezioni, tale significato è "questo non accadrà mai". Non è un caso se per ogni eccezione esiste una condizione.

lovaz
04-04-2007, 18:52
Beh, dipende, le eccezioni servono anche per risparmiare controlli.
Primo esempio che mi viene in mente, il costruttore:

public FileInputStream(File file)

può lanciare FileNotFoundException (o anche SecurityException, altro esempio).

Certamente, uno può controllare prima se il file esiste, se è una directory, ecc...

Oppure può fare il catch dell'eccezione - che comunque si deve fare, essendo checked.


Poi dipende dai gusti, a qualcuno piacciono gli if, ad altri no.
E dipende anche da cosa si vuole ottenere, sinceramente non so quale
soluzione sia più efficiente - immagino con gli if - per quanto riguarda l'eleganza, è un fatto soggettivo.

PGI-Bis
04-04-2007, 18:57
No, non dipende :D. Comunque uno è libero di fare come meglio crede.

lovaz
04-04-2007, 19:16
No, non dipende :D...
Scusa, ma questa è una tua opinione ;)

E' meglio una catena di 100 if per controllare i null o gestire
l'eccezione che può derivare? Dipende! :D

RaouL_BennetH
04-04-2007, 19:20
Apprezzo moltissimo il modo in cui questo 3d sta andando avanti, davvero :)

Da quasi tutti i vostri post, ho intuito e sto cercando di approfondire i diversi modi per ragionare su uno stesso problema, seguendo strade diverse (che ritengo sia una cosa stupenda)

Vorrei solo chiarirvi qualche dubbio in merito alle mie intenzioni e del perchè ho fatto come ho fatto :p

1) Ho usato gli 'if' perchè per la preparazione che ho attualmente, non avrei saputo usare altro.

2) Non sto ragionando in termini di eleganza perchè, essendo un principiante, credo che questi ragionamenti li potrò affrontare solo dopo qualche anno di esperienza (che ovviamente mi manca), o almeno, lo spero :)

3) Scrivendo però quell'infinita catena di if/else, mi è subito venuto il dubbio che la strada da me intrapresa, a livello di `logica` fosse ovviamente fallimentare, perchè per fare delle semplici operazioni, mi sono trovato a scrivere una valanga di righe di codice, e voi tutti mi insegnate che quando questo accade, probabilmente non si sta affrontando il problema nel modo corretto.

comunque, non prendetemi per scemo (o almeno se lo fate non palesatemelo :D ) ma sento di dovervi dire un enorme grazie per i contributi che date !

RaouL.

lovaz
04-04-2007, 19:33
Nessuno ti prende per scemo ;)

Comunque se vuoi sistemare quel codice dovresti fare un bel refactoring,
in modo da delegare a vari oggetti tutte le operazioni da fare.

In pratica "orientarlo agli oggetti"

PGI-Bis
04-04-2007, 19:33
Parlerei più di teoria che di opinione. "Opinione" è un esprimersi guidati dal sentimento. Considerare eccezioni e condizioni come fenomeni diversi è ciò che mi permette di motivare l'uso dell'uno e dell'altro, sfruttando i caratteri che le diversificano. Posso certamente teorizzare che siano entrambe cucchiaiate della stessa minestra ma così facendo riduco la scelta che faccio quando uso l'una o l'altra ad un immotivato vezzo personale. Che è lecito ma poco consono ad un'attività quantitativa come la programmazione.

lovaz
04-04-2007, 19:47
(sentimento?) Questo non è usare eccezioni come condizioni,
è usare eccezioni.

Parentesi: il javadoc di java.lang.Exception recita:
The class Exception and its subclasses are a form of Throwable that indicates conditions that a reasonable application might want to catch.
:D

... poco consono ad un'attività quantitativa come la programmazione.
Frase alquanto vaga... in cosa la programmazione è "quantitativa"?
E comunque la pragmatica è una parte importante della programmazione.
Se no staremmo tutti a programmare in assembler, non credi? ;)

^TiGeRShArK^
04-04-2007, 20:33
Usare un'eccezione come condizione è come salutare la compagna di un primo appuntamento con un cordiale "ciao cesso".

C'è un significato comunemente percepito che può essere diverso da quello intenzionale.

Nel caso delle eccezioni, tale significato è "questo non accadrà mai". Non è un caso se per ogni eccezione esiste una condizione.
concordo in toto :D
infatti sono io il primo a definire orrido il mio codice con le reflection che lanciava una ClassNotFoundException ogni qual volta tale oggetto non è null :D

^TiGeRShArK^
04-04-2007, 20:35
Beh, dipende, le eccezioni servono anche per risparmiare controlli.
Primo esempio che mi viene in mente, il costruttore:

public FileInputStream(File file)

può lanciare FileNotFoundException (o anche SecurityException, altro esempio).

Certamente, uno può controllare prima se il file esiste, se è una directory, ecc...

Oppure può fare il catch dell'eccezione - che comunque si deve fare, essendo checked.


Poi dipende dai gusti, a qualcuno piacciono gli if, ad altri no.
E dipende anche da cosa si vuole ottenere, sinceramente non so quale
soluzione sia più efficiente - immagino con gli if - per quanto riguarda l'eleganza, è un fatto soggettivo.

Può anche controllare se il file esiste, ma se mettiamo caso avviene un'avvenimento eccezionale, che ne so.. qualcuno cancella il file proprio tra il controllo che abbiamo fatto e il momento in cui lo leggiamo, allora viene lanciata l'eccezione.
Quello è il modo è corretto per usarle :p

EDIT: cmq io sono il primo ad essere pigro e a non usarle in maniera corretta :D

marco.r
04-04-2007, 21:35
Non c'è nulla di cui spaventarsi :).

Supponiamo un caso semplice. Cioè usiamo Java :D.

Hai due riferimento, a e b. Vuoi fare qualcosa in corrispondenza delle condizioni:

a != null e b != null
a == null e b == null
a = null e b != null
a != null e b = null

Non è bizzarro pensare, come ha fatto pisto, di avere un array di 4 oggetti, diciamo 4 Runnable (lasciamo da parte la riflessione ma si potrebbe usare anche quella per rendere l'ambaradan ancora più generico). I 4 Runnable nell'array sono indicizzati. Tutto quello che devi fare è stabilire un qualche genere di funzione che data una coppia di riferimenti trasforma l'unione dei loro valori in un numero intero da 0 a 3.

Ad esempio (molto teoricamente e detto da uno per cui la matematica è uno stato d'animo :D):

int hash(Object valueA, Object valueB) {
int hashA = System.identityHashCode(valueA);
int hashB = System.identityHashCode(valueB);
hashA = (3 * hashA) / (2 * hashA);
hashB = (3 * hashB) / (2 * hashB);
return hashA + 2 * hashB;
}

Basandoti su una comprovata (e non quella) funzione di hash che faccia quanto su detto, puoi creare senza difficoltà una struttura tipo:

public class DecisionMap {
private static final class Condition {};
public static final Condition NULL = null;
public static final Condition NOT_NULL = new Condition();
private Runnable[] runners = new Runnable[4];

public void set(Runnable r, Condition valueA, Condition valueB) {
runners[hash(valueA, valueB)] = r;
}

public void decide(Object valueA, Object valueB) {
runners[hash(valueA, valueB)].run();
}

private int hash(Object a, Object b) {
int hashOne = System.identityHashCode(a);
int hashTwo = System.identityHashCode(b);
hashOne = (3 * hashOne) / (2 * hashOne + 1);
hashTwo = (3 * hashTwo) / (2 * hashTwo + 1);
return hashOne + 2 * hashTwo;
}
}

e usarla ad esempio:

public class Main {

public static void main(String[] args) {
class Printer implements Runnable {
private String text;
Printer(String text) { this.text = text; }
public void run() { System.out.println(text); }
}
DecisionMap map = new DecisionMap();
map.set(new Printer("null, null"),
DecisionMap.NULL,
DecisionMap.NULL);
map.set(new Printer("null, not null"),
DecisionMap.NULL,
DecisionMap.NOT_NULL);
map.set(new Printer("not null, not null"),
DecisionMap.NOT_NULL,
DecisionMap.NOT_NULL);
map.set(new Printer("not null, null"),
DecisionMap.NOT_NULL,
DecisionMap.NULL);

map.decide(null, "hello");
map.decide(2, null);
map.decide("hello", "world");
}
}

Tutto sta nel ricondurre caratteristiche note a valori noti ed eseguire poi un calcolo dall'esito... noto :D L'arte di sapersi spiegare :D.

Non so quanto sia conveniente a livello di conti fatti dal PC. Ma se ti stanno antipatici gli if penso che l'unica alternativa sia l'hashing.

Curiosamente (ma neanche troppo), linguaggi con una sintassi piu' evoluta come haskell permettono di esprimere questo concetto in modo molto elegante in giusto quattro righe:

decide None None = bla
decide (Just x) None = blah
decide None (Just y) = blah2
decide (Just x) (Just y) = blah3

In alternativa, se il linguaggio dispone di tuple e hash che non richiedono contorsionismi per essere usati, come python, ci vuole qualche riga in piu', ma la chiarezza permane.

decide = {}
decide[(True,False)] = value1True
decide[(False,True)] = value2True
decide[(True,True)] = bothTrue
decide[(False,False)] = bothFalse

def bothFalse(a,b):
...

decide[(valueA!=None,ValueB!=None)](valueA,valueB)

anche se questo porta un po' di ripetizione per portarsi i parametri all'interno della funzione.

PGI-Bis
04-04-2007, 21:45
(sentimento?) Questo non è usare eccezioni come condizioni,
è usare eccezioni.

Parentesi: il javadoc di java.lang.Exception recita:

:D


Frase alquanto vaga... in cosa la programmazione è "quantitativa"?
E comunque la pragmatica è una parte importante della programmazione.
Se no staremmo tutti a programmare in assembler, non credi? ;)

No.

lovaz
05-04-2007, 11:03
Cosa volete che vi dica, ognuno ha le sue opinioni :rolleyes:

marco.r
05-04-2007, 14:39
Parlerei più di teoria che di opinione. "Opinione" è un esprimersi guidati dal sentimento. Considerare eccezioni e condizioni come fenomeni diversi è ciò che mi permette di motivare l'uso dell'uno e dell'altro, sfruttando i caratteri che le diversificano. Posso certamente teorizzare che siano entrambe cucchiaiate della stessa minestra ma così facendo riduco la scelta che faccio quando uso l'una o l'altra ad un immotivato vezzo personale. Che è lecito ma poco consono ad un'attività quantitativa come la programmazione.
Il fatto di poter raccogliere diversi controlli in uno unico direi che puo' essere una motivazione per l'utilizzare la gestione delle eccezioni al posto dei controlli classici, soprattutto se il risultato e' piu' chiaro e comprensibile. E' vero che in generale l'uso "distorto" di strumenti forniti dal linguaggio e' deprecabile in quanto genera confusione, ma nel caso non sia cosi', perche' non farlo ?
Non dimentichiamochi che non sempre una caratteristica di un linguaggio viene utilizzata nel modo previsto durante la sua progettazione (vedi i templates del C++ ad esempio)

lovaz
05-04-2007, 18:04
... (vedi i templates del C++ ad esempio)
Mi hai incuriosito, non sono un esperto di C++, ma mi puoi fare un esempio di
uso non previsto dei templates?

71104
05-04-2007, 20:37
più che i templates io citerei le macro. c'è una macro che definisco spesso nei miei progetti in C e/o C++ e che in realtà è una scopiazzatura da MFC (infatti la definisco io quando non ho la possibilità di usare MFC):

#ifdef _DEBUG

#define ASSERT(x) if (!(x)) { <chiamata ad una routine che stampa l'errore e ferma il programma> }
#define VERIFY ASSERT

#else

#define ASSERT(x)
#define VERIFY

#endif

notare la definizione di VERIFY nel secondo caso (cioè in versione release).

marco.r
05-04-2007, 23:40
Mi hai incuriosito, non sono un esperto di C++, ma mi puoi fare un esempio di
uso non previsto dei templates?
Ce ne sono diversi.
Il piu' famoso e' probabilmente l'esecuzione di codice a compile-time invece che a run-time. Il seguente esempio effettua il calcolo del fattoriale durante la compilazione invece che durante l'esecuzione del programma:

#include <iostream>

using namespace std;

template <int i>
struct fact
{
enum { value = i * fact<i-1>::value };
};

template<>
struct fact<0>
{
enum { value = 1 };
};

int main()
{
cout << "Il fattoriale di 9 e' " << fact<9>::value << endl;
}

Questo esempio e' idiota, ma ci sono diversi casi in un comportamento del genere puo' essere desiderabile.
Ad esempio se tu volessi implementare delle matrici multidimensionali, potresti decidere di usare i template, definendo la classe matrice di grado N in funzione della classe di grado N-1, e specializzando quella di grado 1. In teoria dovresti riuscire ad ottenere una soluzione generale (nel senso che ti permette di usare matrici con un numero arbitrario di di dimensioni) senza l'overhead di un approccio "classico". Mi sembra che nelle boost venga usato un approccio simile.
Personalmente mi piacciono fino ad un certo punto, ci vuole un sacco di lavoro affinche il codice sia umanamente leggibile.