View Full Version : Google executive frustrated by Java, C++ complexity
anonimizzato
09-08-2010, 11:40
http://www.javaworld.com/javaworld/jw-07-2010/100722-java-complexity.html
Sarei curioso di conoscere il vostro punto di vista.
Bye. :)
Sarei curioso di conoscere il vostro punto di vista.
Immagino volessi dire: "sarei interessato a scatenare l'ennesina flamewar" :D
anonimizzato
09-08-2010, 11:48
Immagino volessi dire: "sarei interessato a scatenare l'ennesina flamewar" :D
Ovvio, è Agosto, il forum è un mortorio, almeno lo ravviviamo un pò. :O
Scherzi a parte: ovvio che NO.
Sono curioso di sapere il vostro punto di vista su quanto espresso da Google, o meglio: da Rob Pike di Google. :)
cdimauro
09-08-2010, 12:07
Leggerò l'articolo dopo pranzo (altrimenti finisce che mi mangio la scrivania).
Ma credo che la mia opinione sia ben nota. :D
A dopo.
cdimauro
09-08-2010, 13:01
Letto e confermo. Sono cose che ripeto da tempo. Vedi avatar. :D
Comunque non sono del tutto d'accordo con Pike. Grazie al TDD, il problema della tipizzazione dinamica vs statica è praticamente risolto; i controlli non li fai a compile time, ma quando esegui la batteria di test. ;)
il solito fricchettone visionario invasato che per rimediare al mondo tira fuori un nuovo linguaggio che é una cagata assurda. :asd:
il solito fricchettone visionario invasato che per rimediare al mondo tira fuori un nuovo linguaggio che é una cagata assurda. :asd:
Forse il mio rilevatore di sarcasmo oggi non funziona bene ma... Rob Pike non è proprio l'ultimo degli stronzi. http://en.wikipedia.org/wiki/Rob_Pike
banryu79
09-08-2010, 13:42
Forse il mio rilevatore di sarcasmo oggi non funziona bene ma... Rob Pike non è proprio l'ultimo degli stronzi. http://en.wikipedia.org/wiki/Rob_Pike
Non lo è affatto, sicuramente è uno che sa bene quello che dice.
Il problema da porsi, più che altro, è: perchè dice quello che dice (in quell'articolo)?
E la mia risposta è: marketing, più che altro (il che non significa che stia dicendo 100% bufale).
Anche perchè non fanno altro che ribadire storia già sentita N volte:
- C++ non va più bene, semplifichiamolo con Java!
passa X tempo...
- Java/Altro non vanno più bene, semplifichiamoli con Python!
passa X tempo...
- Python/I cugini di campagna/ non vanno più bene, semplifichiamoli con Go!
etc...
E questo lo dicono loro, qua (cito):
...
One member of the audience, Larry Augustin, the CEO of customer relationship management software provider SugarCRM, agreed with Pike's assessment that C++ and Java have gotten too complex, although he noted that this typically happens with all languages as they grow to meet a wider range of use cases.
"The reason that these languages have grown in complexity is because the more they are used, the more errors and ambiguities we've found, and the attempts to remove those ambiguities and errors have created something more complex," said Augustin, who has a background in software engineering and programming language design.
http://www.javaworld.com/javaworld/jw-07-2010/100722-java-complexity.html
Sarei curioso di conoscere il vostro punto di vista.
Bye. :)
L'ennesimo gegno dell'informatica che si mette ad elencare difetti del C++ che si conoscono dal 1989 e poi propone un linguaggio dove ci sta tipo tutto ma che non è mai stato usato nemmeno da lui.
Avanti il prossimo :read:
PS: Google GO is the next Google Wave... ultimamente Google non ne imbrocca una.
cdimauro
10-08-2010, 05:41
Non lo è affatto, sicuramente è uno che sa bene quello che dice.
Il problema da porsi, più che altro, è: perchè dice quello che dice (in quell'articolo)?
E la mia risposta è: marketing, più che altro (il che non significa che stia dicendo 100% bufale).
Anche perchè non fanno altro che ribadire storia già sentita N volte:
- C++ non va più bene, semplifichiamolo con Java!
passa X tempo...
- Java/Altro non vanno più bene, semplifichiamoli con Python!
passa X tempo...
- Python/I cugini di campagna/ non vanno più bene, semplifichiamoli con Go!
etc...
E questo lo dicono loro, qua (cito):
Concordo su tutto, tranne per l'ultima analogia. :cool:
L'ennesimo gegno dell'informatica che si mette ad elencare difetti del C++ che si conoscono dal 1989 e poi propone un linguaggio dove ci sta tipo tutto ma che non è mai stato usato nemmeno da lui.
Avanti il prossimo :read:
PS: Google GO is the next Google Wave... ultimamente Google non ne imbrocca una.
Ma infatti, come scrivevo prima, non dice nulla di nuovo. Sono cose note e arcinote.
E' la "cura" che propone che non mi piace.
Ma poi sempre linguaggi con sintassi C-Like? Non se ne può più. La creatività a livello di mera sintassi sembra morta...
L'ennesimo gegno dell'informatica che si mette ad elencare difetti del C++ che si conoscono dal 1989 e poi propone un linguaggio dove ci sta tipo tutto ma che non è mai stato usato nemmeno da lui.
Ehm, go e' un linguaggio nuovo di zecca, mi sembra naturale che sia usato poco :D (anche se, sembra, stanno cominciando ad usarlo un po' internamente a google).
Forse il mio rilevatore di sarcasmo oggi non funziona bene ma... Rob Pike non è proprio l'ultimo degli stronzi. http://en.wikipedia.org/wiki/Rob_Pike e sti cazzi? :stordita:
tanto per rincarare la dose di scurrilitá :D
scusa la risposta ma a me dei titoli nobiliari non frega proprio niente.
tra l'altro do una letta veloce alla pagina di Wikipedia e che ti vedo? che ha partecipato alla realizzazione del linguaggio Go. vabbé, abbiamo capito va' :asd:
Credo sia perfettamente normale che persone che lavorano in questo settore abbiano opinioni, e anche se non si è d'accordo bisognerebbe comunque rispettarle.
A me ad esempio C++ fa totalmente schifo, ma non perché non sia adatto a fare quello che fa, ma perché la sua sintassi, verbosità e quant'altro mi fa schifo (basta vedere anche solo gli errori ritornati dal compilatore per rendersi conto di ciò).
E d'altro canto forse nel 2010 bisognerebbe cominciare a pensare ad un linguaggio che possa sostituire C++ quanto a caratteristiche (prestazioni degli eseguibili, duttilità e quant'altro...).
Ora è chiaro che quando parliamo di complessità bisogna specificare di cosa stiamo parlando.
Nel caso di un linguaggio la complessità può essere nell'utilizzo, nella mera leggibilità del codice, oppure nella progettazione del compilatore/interprete dello stesso.
Ci sono alcune persone che si sentono toccate nel profondo quando gli fai notare i difetti degli strumenti che utilizzano perché non accettano critiche da nessuno o si credono loro chissà chi...
Ora dato che tutte le cose hanno pregi e difetti mi sembra abbastanza sciocco rifiutare a priori qualsiasi tipo di critica.
Inoltre un po' di umiltà non guasterebbe, forse chi ha espresso quelle opinioni ha più esperienza di noi nel campo.
[...] ma perché la sua sintassi, verbosità e quant'altro [...] verbositá...? :mbe:
e sti cazzi? :stordita:
tanto per rincarare la dose di scurrilitá :D
scusa la risposta ma a me dei titoli nobiliari non frega proprio niente.
tra l'altro do una letta veloce alla pagina di Wikipedia e che ti vedo? che ha partecipato alla realizzazione del linguaggio Go. vabbé, abbiamo capito va' :asd:
No ma dai, davvero non sai chi sia Pike? Tipo quello che scritto questi due libricini qui mai letti o citati da nessuno al mondo? http://www.amazon.com/Rob-Pike/e/B001ILFKO6
Pike è un hacker storico. Ora, al di là di essere d'accordo o meno con quello che dice o scrive, definirlo "fricchettone visionario invasato" mi sembra quantomeno fuoriluogo.
E d'altro canto forse nel 2010 bisognerebbe cominciare a pensare ad un linguaggio che possa sostituire C++ quanto a caratteristiche (prestazioni degli eseguibili, duttilità e quant'altro...).
Your wish is my command: D Programming Language (http://www.digitalmars.com/d/2.0/index.html)
:D
anonimizzato
10-08-2010, 14:27
Your wish is my command: D Programming Language (http://www.digitalmars.com/d/2.0/index.html)
:D
Sembra PHP. :fagiano:
verbositá...? :mbe:
[code]
Beh, se prendi ad esempio una map che mappa stringhe a coppie (stringa,intero) non si scherza. Ti puoi ritrovare una std::map< std::string, std::pair< std::string, int> > in un header o un map<string,pair<string,int> >::const_iterator da qualche altra parte :asd:. Non a caso codice C++ idiomatico e' pieno zeppo di typedefs.
con il c++0x qualcosa cambia in meglio, ma non la sostanza.
Perseverance
10-08-2010, 15:07
Mi hanno sempre detto che i programmi interpretati (come java) girano più lenti di quelli compilati (C++). Avendo una blanda esperienza con entrambi posso affermare che è vero. Ma qui stiamo parlando del linguaggio migliore per scrivere programmi.
La sintassi:
Fino ad un livello medio di programmazione Java e C++ la sintassi è abbastanza facile per entrambi, molto simile e per alcune cose identica. Quando si iniziano a toccare le interfacce grafiche allora lì diventa più difficile programmare in C++.
Il Software Development Kit:
Penso che sia quello che conta effettivamente di più. Passando dal DevC++ a QTDevelop (per quanto riguarda la programmazione di gui) per me è stato un enorme passo in avanti. Questo per dire che l'ambiente di sviluppo (SDK) è un fattore di primaria importanza.
Noi (io e voi) non sappiano cosa significa programmare in modo complesso, non siamo in grado di giudicare se sia complesso o no il C++ rispetto al Java o al Go o al D, xkè non abbiamo esperienza. E se qui dentro qualcuno ne ha, sicuramente si sarà fatto un'idea personale sulla questione.
DanieleC88
10-08-2010, 15:12
Mi hanno sempre detto che i programmi interpretati (come java) girano più lenti di quelli compilati
Java non è proprio "interpretato"... Python era un esempio migliore.
Il Software Development Kit:
Penso che sia quello che conta effettivamente di più. Passando dal DevC++ a QTDevelop (per quanto riguarda la programmazione di gui) per me è stato un enorme passo in avanti. Questo per dire che l'ambiente di sviluppo (SDK) è un fattore di primaria importanza.
In realtà tu parli ambiente di sviluppo, quindi di IDE (Integrated Development Environment), mentre l'SDK è un'altra cosa.
Noi (io e voi) non sappiano cosa significa programmare in modo complesso, non siamo in grado di giudicare se sia complesso o no il C++ rispetto al Java o al Go o al D, xkè non abbiamo esperienza.
Io e te probabilmente no, ma alcuni di quelli che sono intervenuti ne hanno, fidati. :D
ciao ;)
Non lo è affatto, sicuramente è uno che sa bene quello che dice.
Il problema da porsi, più che altro, è: perchè dice quello che dice (in quell'articolo)?
E la mia risposta è: marketing, più che altro (il che non significa che stia dicendo 100% bufale).
Mi sembra naturale che ci sia un po' di marketing, visto che lui propone un'alternativa. Ma e' quello che fanno tutti gli autori di un nuovo linguaggio. E d'altra parte, se non ne fossero convinti, perche' si sarebbero presi la briga di scriverlo ?
Anche perchè non fanno altro che ribadire storia già sentita N volte:
- C++ non va più bene, semplifichiamolo con Java!
passa X tempo...
- Java/Altro non vanno più bene, semplifichiamoli con Python!
passa X tempo...
- Python/I cugini di campagna/ non vanno più bene, semplifichiamoli con Go!
etc...
Java e Python sono nati per ambiti diversi. Java e' nato per sostituire C++ per l'ambito di piu' alto livello dove il C++ era usato, python come linguaggio di scripting. Go e' nato per la programmazione di sistema, dove al momento le alternative sono principalmente C e C++.
E questo lo dicono loro, qua (cito):
Per fare cose complicate, ci vuole un linguaggio complicato :p (o meglio, un complicato linguaggio :asd:)
Battute a parte, spesso semplificare un linguaggio vuol dire rendere piu' complicato il codice. L'errore di linguaggi come Java e' stato, una volta riconosciuta la complessita' del C++, di risolvere il problema eliminando la parte complicata o che dava problemi, invece che di migliorarla.
A distanza di anni queste funzionalita' sono state aggiunte in modo ad hoc e col vincolo parziale della retrocompatibilita'.
Ma poi sempre linguaggi con sintassi C-Like? Non se ne può più. La creatività a livello di mera sintassi sembra morta...
A me sembra che di C-Like abbia solo le graffe e il punti e virgola. Le dichiarazioni delle variabili e delle funzioni e' decisamente diversa, visibilita' che viene definita dal fatto che l'identificatore sia minuscolo o meno... puo' piacere o meno (a me no), ma definirla c-like mi sembra un po' esagerato.
banryu79
10-08-2010, 17:06
Mi sembra naturale che ci sia un po' di marketing, visto che lui propone un'alternativa. Ma e' quello che fanno tutti gli autori di un nuovo linguaggio. E d'altra parte, se non ne fossero convinti, perche' si sarebbero presi la briga di scriverlo?
Per carità, non volevo assolutizzare; a me l'occhio era cascato più che altro su quello, ovviamente relativamente a quell'articolo e basta.
Go può anche essere un ottimo nuovo linguaggio, (e non ho motivo di dubitarne) ma non ho fatto una valutazione basandomi su di esso perchè non lo conosco e in quell'articolo non ho trovato informazioni utili in merito.
Java e Python sono nati per ambiti diversi. Java e' nato per sostituire C++ per l'ambito di piu' alto livello dove il C++ era usato, python come linguaggio di scripting. Go e' nato per la programmazione di sistema, dove al momento le alternative sono principalmente C e C++.
Ti credo sulla parola, come ho detto sopra, non lo conosco e infatti non esprimo nessun giudizio sul linguaggio, perchè non ne ho nessuno e perchè (molto più importante :D) non sono nessuno :)
In effetti non sono stato molto chiaro, e ho generato un equivoco: io parlavo solo dell'articolo e di cosa ci ho capito io.
Per fare cose complicate, ci vuole un linguaggio complicato :p (o meglio, un complicato linguaggio :asd:)
Sembra la vecchia pubblicità del pennello Cinghiale :D
Battute a parte, spesso semplificare un linguaggio vuol dire rendere piu' complicato il codice. L'errore di linguaggi come Java e' stato, una volta riconosciuta la complessita' del C++, di risolvere il problema eliminando la parte complicata o che dava problemi, invece che di migliorarla.
Questa la prendo con le pinze, la considero e ci rifletterò su, ma non ne sono convinto pienamente, anche per via della mia propria ignoranza e poca esperienza che mi permette di capire e valutare le cose solo fino ad un certo punto.
Anzi, se hai voglia & tempo di sviluppare un po' il punto sarei felice di leggere le tue considerazioni.
A distanza di anni queste funzionalita' sono state aggiunte in modo ad hoc e col vincolo parziale della retrocompatibilita'.
Questa invece la condivido in pieno.
No ma dai, davvero non sai chi sia Pike? Tipo quello che scritto questi due libricini qui mai letti o citati da nessuno al mondo? http://www.amazon.com/Rob-Pike/e/B001ILFKO6 NO?? :eek:
ammazza quant'é fico!!11
Ora, al di là di essere d'accordo o meno con quello che dice o scrive, definirlo "fricchettone visionario invasato" mi sembra quantomeno fuoriluogo. giusto, infatti é un fricchettone visionario invasato che ha scritto due libri! éh.
(di cui uno su Unix per giunta, come a dire che mi fiondo subito a leggerlo: sai quanto puó essermi utile nel 2010? sarei un pazzo a farlo mancare alla mia libreria.)
Beh, se prendi ad esempio una map che mappa stringhe a coppie (stringa,intero) non si scherza. Ti puoi ritrovare una std::map< std::string, std::pair< std::string, int> > in un header o un map<string,pair<string,int> >::const_iterator da qualche altra parte :asd:. troppo facile se lo fai apposta di esplicitare il namespace! chi é che programmando in C++ scrive decine, centinaia di migliaia di righe di codice esplicitando tutte le volte il namespace delle librerie standard? e a chi é mai capitato di avere una collisione di nomi con le librerie standard?
io per esempio gli headers standard che devo usare li includo tutti nell'header precompilato (anche quando uso il gcc (ebbene si, uso i GCH :asd: )) e li concludo con "using namespace std;" e una collisione di nomi non l'ho mai avuta perché uso una naming convention completamente diversa.
sono d'accordissimo invece per quando si tratta di fare un'iterazione su un container STL ma obietto che a cercare apposta un caso di verbositá lo si puó trovare in qualunque linguaggio della terra, anche in JavaScript (vogliamo parlare dell'ereditarietá in JavaScript? :stordita: ). parlando invece della sintassi piu comune, ora io non conosceró tutti i linguaggi di programmazione del mondo, e neanche tutti quelli piu usati, ma a occhio il C++ in quanto a sintesi (non verbositá) mi sembra che occupi un buon posto; te ne rendi immediatamente conto se fai il confronto con l'Object Pascal (asd).
con il c++0x qualcosa cambia in meglio, ma non la sostanza. be', in C++0x il problema che hai citato tipicamente scompare grazie alla keyword auto, quindi gioverebbe qualche altro esempio di verbositá eccessiva.
Ma qui stiamo parlando del linguaggio migliore per scrivere programmi. che non esiste in senso assoluto ovviamente, dipende dal programma da scrivere.
La sintassi:
Fino ad un livello medio di programmazione Java e C++ la sintassi è abbastanza facile per entrambi, molto simile e per alcune cose identica. ma quando mai... :mbe:
Quando si iniziano a toccare le interfacce grafiche allora lì diventa più difficile programmare in C++. avrei detto proprio l'opposto ma in realtá il paragone stesso non ha senso perché il C++ di per se' non offre alcuno strumento per realizzare interfacce grafiche, al contrario di Java, quindi dipende dal framework utilizzato.
Il Software Development Kit: velo pietoso sullo stravolgimento terminologico :stordita:
Noi (io e voi) non sappiano cosa significa programmare in modo complesso, dipende da cosa intendi per "complesso"
non siamo in grado di giudicare se sia complesso o no il C++ rispetto al Java o al Go o al D, xkè non abbiamo esperienza. per favore, non deturpare l'italiano.
A me sembra che di C-Like abbia solo le graffe e il punti e virgola. ormai infatti la definizione di sintassi C-like pare diventata quella, con che coraggio non lo so.
cdimauro
11-08-2010, 08:00
Mi hanno sempre detto che i programmi interpretati (come java) girano più lenti di quelli compilati (C++). Avendo una blanda esperienza con entrambi posso affermare che è vero. Ma qui stiamo parlando del linguaggio migliore per scrivere programmi.
Migliore? E chi l'ha detto? Dipende sempre dal contesto.
A me sembra che di C-Like abbia solo le graffe e il punti e virgola. Le dichiarazioni delle variabili e delle funzioni e' decisamente diversa, visibilita' che viene definita dal fatto che l'identificatore sia minuscolo o meno... puo' piacere o meno (a me no), ma definirla c-like mi sembra un po' esagerato.
Non è che ci siano soltanto le graffe e i punti e virgola (che tra l'altro non sono obbligatori). Ad esempio i puntatori, le struct, il ciclo for, ecc. sono chiaramente c-like.
Tra l'altro con C-like s'intende un linguaggio di ispirazione C, non uno che abbia la stessa sintassi base.
Che Go sia ispirato al C lo dicono anche i loro creatori...
troppo facile se lo fai apposta di esplicitare il namespace! chi é che programmando in C++ scrive decine, centinaia di migliaia di righe di codice esplicitando tutte le volte il namespace delle librerie standard? e a chi é mai capitato di avere una collisione di nomi con le librerie standard?
io per esempio gli headers standard che devo usare li includo tutti nell'header precompilato (anche quando uso il gcc (ebbene si, uso i GCH :asd: )) e li concludo con "using namespace std;" e una collisione di nomi non l'ho mai avuta perché uso una naming convention completamente diversa.
Ciò non toglie che sei costretto a ripetere il tipo di alcune espressioni, anche in "forma ridotta", quando dal contesto potresti farne tranquillamente a meno, e questo "allunga il brodo".
sono d'accordissimo invece per quando si tratta di fare un'iterazione su un container STL ma obietto che a cercare apposta un caso di verbositá lo si puó trovare in qualunque linguaggio della terra, anche in JavaScript (vogliamo parlare dell'ereditarietá in JavaScript? :stordita: ). parlando invece della sintassi piu comune, ora io non conosceró tutti i linguaggi di programmazione del mondo, e neanche tutti quelli piu usati, ma a occhio il C++ in quanto a sintesi (non verbositá) mi sembra che occupi un buon posto; te ne rendi immediatamente conto se fai il confronto con l'Object Pascal (asd).
Di questo ne abbiamo già parlato. L'Object Pascal ti obbliga a separare l'interfaccia dall'implementazione, costringendoti a essere più verboso, appunto.
Ma è anche un vantaggio non indifferente, quando parliamo di tempi di compilazione. Un programma in Delphi di un milione di righe di codice lo si compila (e linka) agevolmente in una manciata di secondi.
Tanto per confronto, ieri per compilare un modulo C++ di 71 righe di codice col GCC (e nemmeno con tutte le ottimizzazioni attive: -O2 anziché 3) impiegavo fra i 3 e i 4 secondi circa.
E scusa se è poco.
be', in C++0x il problema che hai citato tipicamente scompare grazie alla keyword auto, quindi gioverebbe qualche altro esempio di verbositá eccessiva.
Come già detto, non serve nemmeno quella keyword: è sufficiente il contesto. Come succede da una trentina d'anni a questa parte con Ada, ad esempio.
ormai infatti la definizione di sintassi C-like pare diventata quella, con che coraggio non lo so.
Alberto, dopo anni che frequenti questo forum non hai ancora imparato la cosa più importante: il rispetto per le opinioni altrui.
Antares88
12-08-2010, 09:09
NO?? :eek:
ammazza quant'é fico!!11
giusto, infatti é un fricchettone visionario invasato che ha scritto due libri! éh.
(di cui uno su Unix per giunta, come a dire che mi fiondo subito a leggerlo: sai quanto puó essermi utile nel 2010? sarei un pazzo a farlo mancare alla mia libreria.)
Pike non mi sembra così invasato, anzi.
Infatti nel 1991 ha detto: "Not only is UNIX dead, it's starting to smell really bad."
Sinceramente non vedo il senso di fare ironia su un libro che ha un quarto di secolo. Il fatto che sia vecchio non vuol dire che non sia stato un libro importante a suo tempo.
Col tuo ragionamento saresti capace di dar fuoco a una copia del Philosophiæ Naturalis Principia Mathematica di Newton solo perché è un libro vecchio di tre secoli :D
Insomma, possiamo senz'altro discutere sul fatto che determinate affermazioni siano influenzate dalla sua posizione e dal desiderio di mettere in buona luce Go, ma da qui a dire che è uno stupido...
Piuttosto, parliamo di questo linguaggio D: googlando un pò ho visto che esiste dal 99 ed è ancora in lavorazione la versione 2. Sono niubbo io che ne ho sentito parlare pochissimo finora oppure è stato un buco nell'acqua ?
Piuttosto, parliamo di questo linguaggio D: googlando un pò ho visto che esiste dal 99 ed è ancora in lavorazione la versione 2. Sono niubbo io che ne ho sentito parlare pochissimo finora oppure è stato un buco nell'acqua ?
Andremmo un pò OT, anzi ci siamo già, ma ti posso dire che a livello di linguaggio la versione 2 è stabile, mentre si sta rifinendo la libreria standard.
E' da poco uscito il libro di riferimento, The D Programming Language, scritto da Alexandrescu (si, lo stesso di Modern C++ Design, e altre cose C++-related) basato su D 2.0.
Recentissimamente lo stesso Alexandrescu ha fatto un talk in Google proprio sull'argomento, al quale ti rimanderei per evitare di andare troppo OT: http://www.youtube.com/watch?v=RlVpPstLPEc
Di questo ne abbiamo già parlato. L'Object Pascal ti obbliga a separare l'interfaccia dall'implementazione, costringendoti a essere più verboso, appunto.
Ma è anche un vantaggio non indifferente, quando parliamo di tempi di compilazione. Un programma in Delphi di un milione di righe di codice lo si compila (e linka) agevolmente in una manciata di secondi. sta benissimo che la cosa acceleri la compilazione ma questo non toglie che sia un linguaggio verboso; inoltre non é solo quello il fattore che ne costituisce la verbositá: l'Object Pascal é pieno di keyword kilometriche che in C++ equivalgono a simboli di un singolo carattere, e abbiamo giá parlato anche di questo. inoltre alla fine dei conti ci si potrebbe chiedere se valeva la pena tutta questa verbositá: secondo il tuo ragionamento praticamente il compilatore risparmia tempo togliendolo all'essere umano, che deve scrivere molto di piu. magari quel milione di righe corrispondevano alle 71 righe di C++ :asd:
Tanto per confronto, ieri per compilare un modulo C++ di 71 righe di codice col GCC (e nemmeno con tutte le ottimizzazioni attive: -O2 anziché 3) impiegavo fra i 3 e i 4 secondi circa. e quali headers hai incluso? a questo punto sarei curioso di vedere il codice se possibile (in caso contrario mi sembra un po' troppo facile argomentare in questo modo).
Come già detto, non serve nemmeno quella keyword: è sufficiente il contesto. Come succede da una trentina d'anni a questa parte con Ada, ad esempio. non lo conosco.
comunque adesso che sia rimasta ancora una keyword "auto" non mi sembra un gran problema visto che si tratta di 4 caratteri in piu e, anzi, se non ci fosse neanche quella nascerebbero sicuramente ambiguitá sulla dichiarazione della variabile, ambiguitá che non so come questo Ada risolva, se le risolve.
Alberto, ci conosciamo? :mbe:
dopo anni che frequenti questo forum veramente devi esserti fatto ingannare dalla data di iscrizione perché in realtá non é neanche un anno: l'account l'ho aperto molto prima di diventare attivo.
non hai ancora imparato la cosa più importante: il rispetto per le opinioni altrui. non é il tuo caso naturalmente, ma spesso si leggono "opinioni" che non meritano il minimo rispetto :asd:
Col tuo ragionamento saresti capace di dar fuoco a una copia del Philosophiæ Naturalis Principia Mathematica di Newton solo perché è un libro vecchio di tre secoli :D ma quello é ancora valido, al contrario di un libro su Unix.
cdimauro
12-08-2010, 13:18
sta benissimo che la cosa acceleri la compilazione ma questo non toglie che sia un linguaggio verboso; inoltre non é solo quello il fattore che ne costituisce la verbositá: l'Object Pascal é pieno di keyword kilometriche che in C++ equivalgono a simboli di un singolo carattere, e abbiamo giá parlato anche di questo.
Vero. Ma personalmente trovo orribile la scelta fatta per i costruttori e i distruttori.
Risparmiare caratteri di per sé non vuol dire nulla. Basti pensare a Python e Perl: entrambi hanno il dono della sintesi, ma il primo viene definito pseudocodice eseguibile, il secondo rumore bianco eseguibile...
inoltre alla fine dei conti ci si potrebbe chiedere se valeva la pena tutta questa verbositá: secondo il tuo ragionamento praticamente il compilatore risparmia tempo togliendolo all'essere umano, che deve scrivere molto di piu. magari quel milione di righe corrispondevano alle 71 righe di C++ :asd:
Anche quello è tempo che perdi, e incide sulla produttività, se permetti.
Inoltre in Delphi hai un'IDE eccezionale che ti evita di scrivere codice tante volte; nello specifico, definito il metodo nell'interfaccia poi con Ctrl+Shift+C (se non ricordo male) ti genera l'intero corpo dell'implementazione, inclusi il begin e end finale...
e quali headers hai incluso? a questo punto sarei curioso di vedere il codice se possibile (in caso contrario mi sembra un po' troppo facile argomentare in questo modo).
Eccolo qui:
//
// C++ Implementation: mod_PEP
//
// Description:
//
//
// Author: Cesare Di Mauro <>, (C) 2010
//
// Copyright: See COPYING file that comes with this distribution
//
//
#include "manager.h"
#include "myexception.h"
#include <sstream>
class mod_PEP : public manager{
public:
mod_PEP(pool* p, const string& n) : manager(p,n) {};
~mod_PEP() {};
virtual void doit(const icontainer& msg)
{
mysqlpp::Connection* Conn = get_con(6); // Get a connection to my DB
mysqlpp::Query Query = Conn->query();
map<string, string> Info = msg.getMap();
ostringstream StringBuf;
StringBuf << "INSERT INTO " << Info["_Entity"] << " SET ";
int i = 0;
for(map<string, string>::iterator Iter = Info.begin(); Iter != Info.end(); Iter++)
if (Iter->first != "mod" && Iter->first != "time" && Iter->first != "_Entity") {
if (i)
StringBuf << ", ";
StringBuf << Iter->first << " = %" << i++ << "q:";
//StringBuf << Iter->first << " = %" << i++ << "q:" << Iter->first;
}
string QueryTemplate = StringBuf.str();
debug("mod_PEP query: " + QueryTemplate);
Query << QueryTemplate;
Query.parse();
i = 0;
for(map<string, string>::iterator Iter = Info.begin(); Iter != Info.end(); Iter++)
if (Iter->first != "mod" && Iter->first != "time" && Iter->first != "_Entity")
Query.template_defaults[i++] = Iter->second.c_str();
//Query.template_defaults[Iter->first.c_str()] = Iter->second.c_str();
debug("mod_PEP executing query \"" + Query.str() + "\"");
Query.execute();
}
virtual void add_description(string & des)
{
des = "PEPs logs";
}
virtual void init(void){}
};
extern "C" manager* create(pool *p, const string& mod_name){
return new mod_PEP(p, mod_name);
}
extern "C" void destroy(manager* m){
delete m;
}
E' un modulo di un progetto più complesso che fa esteso uso delle BOOST e di AMQP/qpid.
non lo conosco.
Beh, non conosci nemmeno Delphi, se è per questo. :D
comunque adesso che sia rimasta ancora una keyword "auto" non mi sembra un gran problema visto che si tratta di 4 caratteri in piu e, anzi, se non ci fosse neanche quella nascerebbero sicuramente ambiguitá sulla dichiarazione della variabile, ambiguitá che non so come questo Ada risolva, se le risolve.
Non vedo perché dovrebbero esserci. Ada, tra l'altro, fornisce anche un tipo "opaco".
ci conosciamo? :mbe:
veramente devi esserti fatto ingannare dalla data di iscrizione perché in realtá non é neanche un anno: l'account l'ho aperto molto prima di diventare attivo.
Assomigli moltissimo a un utente del forum che era stato bannato giusto qualche tempo tempo prima della tua iscrizione, soprattutto nell'irruenza e nelle competenze che dimostri, oltre al fatto che entrambi siete di Roma.
Ma magari mi sbaglio...
troppo facile se lo fai apposta di esplicitare il namespace! chi é che programmando in C++ scrive decine, centinaia di migliaia di righe di codice esplicitando tutte le volte il namespace delle librerie standard? e a chi é mai capitato di avere una collisione di nomi con le librerie standard?
io per esempio gli headers standard che devo usare li includo tutti nell'header precompilato (anche quando uso il gcc (ebbene si, uso i GCH :asd: )) e li concludo con "using namespace std;" e una collisione di nomi non l'ho mai avuta perché uso una naming convention completamente diversa.
Funziona finche' sei da solo o comunque in un gruppo molto ristretto. Se invece devi scrivere una libreria che devono usare altri e' una pratica rischiosa.
sono d'accordissimo invece per quando si tratta di fare un'iterazione su un container STL ma obietto che a cercare apposta un caso di verbositá lo si puó trovare in qualunque linguaggio della terra, anche in JavaScript (vogliamo parlare dell'ereditarietá in JavaScript? :stordita: ). parlando invece della sintassi piu comune, ora io non conosceró tutti i linguaggi di programmazione del mondo, e neanche tutti quelli piu usati, ma a occhio il C++ in quanto a sintesi (non verbositá) mi sembra che occupi un buon posto; te ne rendi immediatamente conto se fai il confronto con l'Object Pascal (asd).
be', in C++0x il problema che hai citato tipicamente scompare grazie alla keyword auto, quindi gioverebbe qualche altro esempio di verbositá eccessiva.
Non mi sembrava un caso molto particolare, anzi fino all'introduzione delle lambda, avevi l'alternativa di una sintassi simile o di usare oggetti funzione. Se hai mai provato a fare programmazione generica in C++ il problema esplode abbastanza in fretta, anche perche' quando hai a che fare con classi derivate non sempre riesci a sfruttare la nuova keyword auto o il far riconoscere automaticamente i tipi con una chiamata di funziona (esempio idiota, non puoi usare make_pair per fare una coppia quando uno degli argomenti e' una classe derivata di quella che vuori ritornare).
Altro esempio e' il fatto che gli iteratori di inizio e fine debbano essere sempre espliciti. Ad esempio la somma di tutti gli elementi di un container sarebbe
std::vector<int> some_list;
int total = 0;
std::for_each(some_list.begin(), some_list.end(), [&total](int x) {
total += x;
});
Nel linguaggio D che shinya citava prima, questo sarebbe un piu' semplice
auto result = reduce!("a+b")(0,values);
questo al di la' del fatto che gli iteratori "spaiati" presentano maggiori rischi di errore.
In generale la metaprogrammazione in C++ e' molto verbosa, poi provo a farti un paio di esempi
Infine, ci metto anche la diagnostica, perche' fa parte della vita del programmatore. Il seguente e' un warning che mi e' apparso mentre stavo compilando un gioco scritto in C++ (battle for wesnoth):
In file included from config.hpp:43,
from gamestatus.cpp:21:
/usr/local/include/boost/aligned_storage.hpp: In instantiation of 'boost::aligned_storage<8u, 4u>':
/usr/local/include/boost/multi_index/detail/index_node_base.hpp:42: instantiated from 'boost::multi_index::detail::pod_value_holder<shared_node<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >'
/usr/local/include/boost/multi_index/detail/index_node_base.hpp:47: instantiated from 'boost::multi_index::detail::index_node_base<shared_node<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<shared_node<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >'
/usr/local/include/boost/multi_index/detail/hash_index_node.hpp:117: instantiated from 'boost::multi_index::detail::hashed_index_node<boost::multi_index::detail::index_node_base<shared_node<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<shared_node<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >'
/usr/local/include/boost/multi_index/hashed_index.hpp:106: instantiated from 'boost::multi_index::detail::hashed_index<boost::multi_index::member<shared_node<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, &shared_node<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >::val>, boost::hash<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::multi_index::detail::nth_layer<1, shared_node<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::multi_index::indexed_by<boost::multi_index::hashed_unique<boost::multi_index::member<shared_node<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, &shared_node<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >::val>, mpl_::na, mpl_::na, mpl_::na>, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, std::allocator<shared_node<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, boost::mpl::vector0<mpl_::na>, boost::multi_index::detail::hashed_unique_tag>'
/usr/local/include/boost/multi_index_container.hpp:89: instantiated from 'boost::multi_index::multi_index_container<shared_node<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::multi_index::indexed_by<boost::multi_index::hashed_unique<boost::multi_index::member<shared_node<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, &shared_node<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >::val>, mpl_::na, mpl_::na, mpl_::na>, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, std::allocator<shared_node<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >'
shared_object.hpp:102: instantiated from 'shared_object<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, shared_node<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >'
shared_string.hpp:20: instantiated from here
/usr/local/include/boost/aligned_storage.hpp:90: warning: enumeral and non-enumeral type in conditional expression
Direi quasi cristallino :eek: :asd:
Con questo non voglio dire che sia piu' verboso di linguaggi tipo Java (tutt'altro), diciamo che non e' l'esempio di linguaggio terso.
insane74
13-08-2010, 10:48
e mentre si lamentano di java Oracle gli fa causa...
http://arstechnica.com/tech-policy/news/2010/08/oracle-sues-google-over-use-of-java-in-android-sdk.ars
banryu79
13-08-2010, 11:24
e mentre si lamentano di java Oracle gli fa causa...
http://arstechnica.com/tech-policy/news/2010/08/oracle-sues-google-over-use-of-java-in-android-sdk.ars
Oracle ha cominciato a "mungere la vacca", a quanto pare :doh:
Vero. Ma personalmente trovo orribile la scelta fatta per i costruttori e i distruttori. gusti, a me basta che sia sintetico e allo stesso tempo inequivocabile.
Risparmiare caratteri di per sé non vuol dire nulla. Basti pensare a Python e Perl: entrambi hanno il dono della sintesi, ma il primo viene definito pseudocodice eseguibile, il secondo rumore bianco eseguibile... risparmiare caratteri vuol dire giá qualcosa, peró non c'é solo quello. Perl avrá un pregio e un miliardo di difetti.
Anche quello è tempo che perdi, e incide sulla produttività, se permetti. vogliamo fare il confronto tra 2 o 3 secondi di troppo in una compilazione ed il tempo speso a scrivere un codice lungo il doppio? naturalmente stiamo parlando di aria fritta perché non abbiamo numeri in mano ma di certo il confronto non é cosi immediato come lo fai tu.
Inoltre in Delphi hai un'IDE eccezionale che ti evita di scrivere codice tante volte; nello specifico, definito il metodo nell'interfaccia poi con Ctrl+Shift+C (se non ricordo male) ti genera l'intero corpo dell'implementazione, inclusi il begin e end finale... é una feature sicuramente molto simpatica ma é qualcosa che pertiene l'IDE, non il linguaggio di per se'.
Eccolo qui: [...]
E' un modulo di un progetto più complesso che fa esteso uso delle BOOST e di AMQP/qpid. posso avere anche gli headers? vorrei provare a compilarlo :D
Beh, non conosci nemmeno Delphi, se è per questo. :D che ne sai?
Non vedo perché dovrebbero esserci. Ada, tra l'altro, fornisce anche un tipo "opaco". magari in Ada é tutto completamente diverso, ma in C++ se prendi questo:
auto pippo = /* ... */ ;
e ci togli "auto", la dichiarazione diventa un'assegnazione e allora ci sono due casi:
1) la variabile non é dichiarata quindi in un ipotetico "C++ senza auto" potrei considerare quella riga una dichiarazione con inizializzazione;
2) la variabile é dichiarata in uno scope esterno e allora nell'ipotetico "C++ senza auto" sorge l'ambiguitá: il programmatore voleva dichiararne una omonima nello scope interno o voleva fare riferimento a quella esterna?
Assomigli moltissimo a un utente del forum si vede che era alto, bello, muscoloso e molto intelligente :asd:
che era stato bannato giusto qualche tempo tempo prima della tua iscrizione, in tal caso stai chiaramente sbagliando persona, questo é il mio primo account su Hardware Upgrade. prima avevo creduto che mi conoscessi visto che mi hai chiamato per nome :mbe:
soprattutto nell'irruenza e nelle competenze che dimostri, oltre al fatto che entrambi siete di Roma. ah, io e quel tipo siamo gli unici due utenti di Roma e con conoscenze sul C++ e su Java? :stordita:
Funziona finche' sei da solo o comunque in un gruppo molto ristretto. Se invece devi scrivere una libreria che devono usare altri e' una pratica rischiosa. dipende se i simboli delle librerie standard li devi usare solo all'interno della libreria o se li devi anche scambiare con chi usa la libreria. nel primo caso non c'é problema, puoi usare implicitamente tutti i namespaces che vuoi, nel secondo invece é meglio che cambi idea a prescindere perché avrai tipicamente problemi di ABI mismatch.
Non mi sembrava un caso molto particolare, mi spiego meglio: d'accordo che capita spesso di iterare su un container STL, ma ci sono linguaggi (senza far nomi :asd: ) che usano "begin" al posto di "{", "end" al posto di "}" e che addirittura hanno un operatore "div" per fare le divisioni intere (diverso da quello per le divisioni in virgola mobile)!! :stordita:
anzi fino all'introduzione delle lambda, avevi l'alternativa di una sintassi simile o di usare oggetti funzione. i funtori sono elementi molto ingombranti dal punto di vista della sintassi; dal punto di vista della programmazione funzionale il C++ non era per niente terso. la sintassi simile quale sarebbe?
Altro esempio e' il fatto che gli iteratori di inizio e fine debbano essere sempre espliciti. Ad esempio la somma di tutti gli elementi di un container sarebbe
std::vector<int> some_list;
int total = 0;
std::for_each(some_list.begin(), some_list.end(), [&total](int x) {
total += x;
});
ma capisci bene che non é un problema del linguaggio, é la funzione for_each che é fatta cosi; si puó rimediare molto in fretta. inoltre, anche se non é stato implementato in Visual C++ 2010, il C++0x prevede un "for each" statement che funziona automaticamente sia sugli array sia sulle classi che hanno un metodo di nome "begin" e uno di nome "end" (vedi Wikipedia: http://en.wikipedia.org/wiki/C%2B%2B0x#Range-based_for-loop ).
questo al di la' del fatto che gli iteratori "spaiati" presentano maggiori rischi di errore. ma anche lá si puó rimediare perché non é un problema intrinseco del linguaggio: i container STL sono fatti cosi (e secondo me sono fatti male perché io li farei diversamente) ma tu puoi scriverti le tue collection classes. naturalmente non lo fai, ma il massimo che puoi dire é che il C++ non fornisce collection classes decenti, non che sia verboso o error-prone.
Infine, ci metto anche la diagnostica, perche' fa parte della vita del programmatore. Il seguente e' un warning che mi e' apparso mentre stavo compilando un gioco scritto in C++ (battle for wesnoth): [...]
Direi quasi cristallino :eek: :asd: e questo é un bel tuscé :stordita:
ma un programmatore puó sicuramente rimediare con l'esperienza (conoscendo il processo di compilazione puoi capire meglio i problemi) e con l'uso di un compilatore che non parli aramaico :D
Oracle ha cominciato a "mungere la vacca", a quanto pare :doh: se non altro stavolta si sono tenuti parzialmente in linea con la filosofia della Sun:
Prior to its acquisition by Oracle, Sun proved hostile to the Harmony Project, the Apache Software Foundation's attempt to build an Apache-licensed Java SE implementation. In addition to Dalvik, Google also uses Harmony's class libraries in Android, which has apparently aroused the ire of Oracle.
:D
sono molto d'accordo con quella che era la filosofia della Sun, neanche a me piacciono i fork idioti e la mania del clone open source a tutti i costi.
cdimauro
15-08-2010, 04:45
gusti, a me basta che sia sintetico e allo stesso tempo inequivocabile.
Che debba essere inequivocabile è il minimo.
vogliamo fare il confronto tra 2 o 3 secondi di troppo in una compilazione ed il tempo speso a scrivere un codice lungo il doppio? naturalmente stiamo parlando di aria fritta perché non abbiamo numeri in mano ma di certo il confronto non é cosi immediato come lo fai tu.
Il codice lo scrivo una volta. La compilazione mi capita di rifarla diverse volte.
é una feature sicuramente molto simpatica ma é qualcosa che pertiene l'IDE, non il linguaggio di per se'.
Delphi è un tutt'uno col suo IDE/RAD.
posso avere anche gli headers? vorrei provare a compilarlo :D
Posso fornirti soltanto gli include e gli using namespace degli altri due file include:
#include <exception>
#include <list>
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
#include <map>
#include <mysql++.h>
#include <db_cxx.h>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/cast.hpp>
#include <boost/program_options.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/list.hpp>
#include <boost/serialization/map.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/xtime.hpp>
using namespace std;
using namespace boost::program_options;
Dovrebbe essere sufficiente per capire il lavoro che fa il compilatore.
che ne sai?
Da quel che ho letto finora non mi sembri un programmatore Delphi.
Io ho lavorato per anni con Delphi (e col Turbo Pascal prima), per cui conosco il "peso" del linguaggio, ma anche quanto comodo sia l'IDE nella vita di tutti i giorni.
magari in Ada é tutto completamente diverso,
La dichiarazione è esplicita.
ma in C++ se prendi questo:
auto pippo = /* ... */ ;
e ci togli "auto", la dichiarazione diventa un'assegnazione e allora ci sono due casi:
1) la variabile non é dichiarata quindi in un ipotetico "C++ senza auto" potrei considerare quella riga una dichiarazione con inizializzazione;
2) la variabile é dichiarata in uno scope esterno e allora nell'ipotetico "C++ senza auto" sorge l'ambiguitá: il programmatore voleva dichiararne una omonima nello scope interno o voleva fare riferimento a quella esterna?
In tal caso usi auto esclusivamente per il secondo caso.
in tal caso stai chiaramente sbagliando persona, questo é il mio primo account su Hardware Upgrade. prima avevo creduto che mi conoscessi visto che mi hai chiamato per nome :mbe:
Ti chiami Alberto?
ah, io e quel tipo siamo gli unici due utenti di Roma e con conoscenze sul C++ e su Java? :stordita:
Non credo, ma qui è anche una questione di carattere, come avevo detto prima.
mi spiego meglio: d'accordo che capita spesso di iterare su un container STL, ma ci sono linguaggi (senza far nomi :asd: ) che usano "begin" al posto di "{", "end" al posto di "}" e che addirittura hanno un operatore "div" per fare le divisioni intere (diverso da quello per le divisioni in virgola mobile)!! :stordita:
E qual è il problema? La semantica è ben definita: / restituisce sempre un real, mentre se vuoi un intero devi usare div.
Quanto a begin e end sono veloci da scrivere quanto le graffe. Ovviamente per chi ha un po' di dimestichezza con la tastiera.
ma capisci bene che non é un problema del linguaggio, é la funzione for_each che é fatta cosi; si puó rimediare molto in fretta. inoltre, anche se non é stato implementato in Visual C++ 2010, il C++0x prevede un "for each" statement che funziona automaticamente sia sugli array sia sulle classi che hanno un metodo di nome "begin" e uno di nome "end" (vedi Wikipedia: http://en.wikipedia.org/wiki/C%2B%2B0x#Range-based_for-loop ).
Il C++0X non c'è ancora: lo standard non è stato definito.
Rimane il C++ con tutti i suoi limiti attuali.
e questo é un bel tuscé :stordita:
ma un programmatore puó sicuramente rimediare con l'esperienza (conoscendo il processo di compilazione puoi capire meglio i problemi) e con l'uso di un compilatore che non parli aramaico :D
GCC è un incubo. E purtroppo quando capita utilizzarlo, non puoi dire "ah, scusa, LLVM mi fornisce degli errori più umani, perché non usiamo questo?". O, peggio ancora, chiedere di usare Visual Studio...
Ovviamente non è un problema del linguaggio, mi dirai tu, ma nella vita di tutti i giorni se sono costretto a usare il GCC non posso fare a meno di sbatterci la testa, compresi i lunghi tempi di compilazione.
Alla fine devi comunque usare degli strumenti reali, c'è poco da tirare in ballo il solo linguaggio.
Il codice lo scrivo una volta. La compilazione mi capita di rifarla diverse volte. d'accordo, ma comunque stiamo ancora parlando di aria fritta (leggi: senza i numeri).
Delphi è un tutt'uno col suo IDE/RAD. é molto bello che esista un software con cui l'Object Pascal é cosi bene integrato ma l'Object Pascal resta comunque un linguaggio verboso.
Posso fornirti soltanto gli include e gli using namespace degli altri due file include:
#include <exception>
#include <list>
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
#include <map>
#include <mysql++.h>
#include <db_cxx.h>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/cast.hpp>
#include <boost/program_options.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/list.hpp>
#include <boost/serialization/map.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/xtime.hpp>
using namespace std;
using namespace boost::program_options;
Dovrebbe essere sufficiente per capire il lavoro che fa il compilatore. ma tu, naturalmente, per compilare questo mostro stai usando degli headers precompilati, giusto...? :mbe:
Da quel che ho letto finora non mi sembri un programmatore Delphi. se é per questo neanche tu visto che sembri molto di piu un programmatore Python ma a quanto pare é solo un'apparenza, per entrambi :)
Io ho lavorato per anni con Delphi (e col Turbo Pascal prima), per cui conosco il "peso" del linguaggio, ma anche quanto comodo sia l'IDE nella vita di tutti i giorni. ho avuto esperienze anche io con Delphi e sono assolutamente d'accordo sulla qualitá dell'IDE, infatti i miei discorsi erano limitati al linguaggio (pur sapendo che Delphi é probabilmente l'unico software che permette di programmare in tale linguaggio).
La dichiarazione è esplicita. e immagino che una dichiarazione esplicita in Ada non sia costituita dal solo nome della variabile dichiarat, no? in C++0x la keyword "auto" non la devi mica specificare ad ogni assegnazione, serve solo nella dichiarazione come "placeholder" per il tipo e indica al compilatore che il tipo della variabile deve essere inferito dall'espressione di inizializzazione.
Ti chiami Alberto? si :stordita:
Non credo, ma qui è anche una questione di carattere, come avevo detto prima. avrai trovato una mezza congiunzione astrale :D
Quanto a begin e end sono veloci da scrivere quanto le graffe. Ovviamente per chi ha un po' di dimestichezza con la tastiera. assolutamente no: io ho la tastiera con layout UK e le parentesi graffe le faccio con Shift+parentesi quadra :Prrr:
(il layout della mia tastiera é anche il motivo per cui su questo forum non riesco a scrivere alcuni caratteri accentati, non so se qualcuno se ne é mai accorto :D)
Il C++0X non c'è ancora: lo standard non è stato definito.
Rimane il C++ con tutti i suoi limiti attuali. e sta benissimo, ma questo risponde solo a una parte di quello che quoti. ripeto, se la funzione for_each ti sembra scomoda ci vuole poco a scriverne una piu comoda.
anonimizzato
15-08-2010, 19:31
Ragazzi tutto quello che dite è molto interessante ed istruttivo (per me) ma forse stiamo andando leggermente OT. :fagiano:
ma quindi in definitiva è C++ o C†† ?
e Java ce lo ricorderemo come Jaceva ?
goldorak
16-08-2010, 09:07
Credo sia perfettamente normale che persone che lavorano in questo settore abbiano opinioni, e anche se non si è d'accordo bisognerebbe comunque rispettarle.
A me ad esempio C++ fa totalmente schifo, ma non perché non sia adatto a fare quello che fa, ma perché la sua sintassi, verbosità e quant'altro mi fa schifo (basta vedere anche solo gli errori ritornati dal compilatore per rendersi conto di ciò).
C++ fa schifo perche' e' un linguaggio bastardo. Ha tutti i difetti del C e nessuno dei suoi vantaggi. La necessita' di farlo "retrocompatibile" con il suo illustre progenitore l'ha reso un abominio. E tale e' restato in questi decenni.
Anzi la situazione continua a peggiorare con il C+x0.
Solo perche' e' il meno peggio che ci sia in giro (per una certa tipologia di progetti) non lo rende affatto un buon linguaggio.
E d'altro canto forse nel 2010 bisognerebbe cominciare a pensare ad un linguaggio che possa sostituire C++ quanto a caratteristiche (prestazioni degli eseguibili, duttilità e quant'altro...).
Oh i linguaggi ci sono, ma come in tutte le cose l'inerzia del popolino (e con questo intendo l'industria, gli sviluppatori etc...) e' molto forte. L'hardware ha subito una rivoluzione epocale passando da una architettura singole core a multicore, andiamo verso soluzioni hardware eterogenee e la maggior parte dei linguaggi usati tradizonalmente sono ancora del tipo imperativo. Nelle universita' invece di fare il lavaggio del cervello con Java, dovrebbero iniziare a spiegare e usare linguaggio funzionali che si adattano come guanti ai nuovi ambienti multicore. Dovrebbero insegnare paradigmi che vanno oltre il solito paradigma imperativo.
Ora è chiaro che quando parliamo di complessità bisogna specificare di cosa stiamo parlando.
Nel caso di un linguaggio la complessità può essere nell'utilizzo, nella mera leggibilità del codice, oppure nella progettazione del compilatore/interprete dello stesso.
Ci sono alcune persone che si sentono toccate nel profondo quando gli fai notare i difetti degli strumenti che utilizzano perché non accettano critiche da nessuno o si credono loro chissà chi...
Certamente, la complessita' di un linguaggio e' presente a piu' livelli. A livello sintattico (ma questo con un po' di pratica si supera). Poi ce' la complessita' a livello semantico. Ce' anche il problema di che tipo e con quale facilita' il linguaggio mette a disposizione del programmatore meccanismi di astrazioni adatti ai tipi di problemi che deve risolvere.
Ora dato che tutte le cose hanno pregi e difetti mi sembra abbastanza sciocco rifiutare a priori qualsiasi tipo di critica.
Inoltre un po' di umiltà non guasterebbe, forse chi ha espresso quelle opinioni ha più esperienza di noi nel campo.
Beh se le critiche provengono da persone percui i linguaggi di programmazione si riducono tutti a Java e C++ la cosa fa sorridire.
Tristemente sorridire, li ignori a vai per la tua strada.
goldorak
16-08-2010, 09:19
ma quindi in definitiva è C++ o C†† ?
e Java ce lo ricorderemo come Jaceva ?
C doppio morto.
E per Java, si fossilezzera' (sempre che Oracle non riesca intenzionalemente o meno ad ucciderlo del tutto) e fare la stessa fine del COBOL.
Un incubo sempre presente a terrorizzare le future generazioni di sviluppatori. :p
DanieleC88
16-08-2010, 09:27
C++ fa schifo perche' e' un linguaggio bastardo. Ha tutti i difetti del C e nessuno dei suoi vantaggi.
È un "sovrainsieme" del C, non può avere... meno vantaggi del linguaggio di cui rappresenta un'evoluzione.
Nelle universita' invece di fare il lavaggio del cervello con Java, dovrebbero iniziare a spiegare e usare linguaggio funzionali che si adattano come guanti ai nuovi ambienti multicore. Dovrebbero insegnare paradigmi che vanno oltre il solito paradigma imperativo.
C'è chi lo fa. :)
Beh se le critiche provengono da persone percui i linguaggi di programmazione si riducono tutti a Java e C++ la cosa fa sorridire.
Tristemente sorridire, li ignori a vai per la tua strada.
:wtf:
anonimizzato
16-08-2010, 09:41
Ora che la palla è passata in mano ad Oracle quale pensate possa essere il futuro di Java?
goldorak
16-08-2010, 09:43
È un "sovrainsieme" del C, non può avere... meno vantaggi del linguaggio di cui rappresenta un'evoluzione.
Beh insomma, la retrocompatibilita' si e' resa necessaria per non spaventare all'epoca gli sviluppatori C. Altrimenti chi avrebbe usato il C++ ?
Questa decisione sebbene all'epoca fosse corretta, ha reso nondimeno il C++ un obrobbio di linguaggio. E questo non si puo' negare.
C'è chi lo fa. :)
Ma sono sempre in pochi.
:wtf:
Intendo dire che e' ridicolo sentire persone pontificare su quale linguaggio sia il migliore (rispetto a che metrica poi ?) se le loro esperienze si riducono sempre a due linguaggi (Java e C++).
goldorak
16-08-2010, 09:44
Ora che la palla è passata in mano ad Oracle quale pensate possa essere il futuro di Java?
http://blogs.citypages.com/food/RIP-500-square.jpg :sofico:
anonimizzato
16-08-2010, 09:47
Quindi dovremmo passare tutti al lato oscuro? (C#) http://forums.keeptouch.net/images/newsmilies/721_darth_vader_fighting_luke_skywalker.gif
goldorak
16-08-2010, 11:01
Quindi dovremmo passare tutti al lato oscuro? (C#) http://forums.keeptouch.net/images/newsmilies/721_darth_vader_fighting_luke_skywalker.gif
Secondo me da un punto di vista dell'evoluzione del linguaggio Java e' bello che morto. Quindi da questo punto di vista non credo che ci saranno novita' di rilievo Oracle o non Oracle.
Sviluppi piu' interessanti verranno da c# (per chi sviluppa su windows), da QT e Vala per chi progetta su linux.
tu sorridisci ma io lo previsi ...
Poi per il bulk di sostanza e contenuto, si deve sempre ricorrere all'immortale Highlander a quattro ruote motrici parallele con nuova carenatura pininfarina : HPF :cool:
Intendo dire che e' ridicolo sentire persone pontificare su quale linguaggio sia il migliore (rispetto a che metrica poi ?) se le loro esperienze si riducono sempre a due linguaggi (Java e C++). mi sa che non hai capito :asd:
Secondo me da un punto di vista dell'evoluzione del linguaggio Java e' bello che morto. Quindi da questo punto di vista non credo che ci saranno novita' di rilievo Oracle o non Oracle. in Java 7 da un punto di vista dell'evoluzione del linguaggio, Oracle o non Oracle, ci saranno le lambda expressions.
goldorak
16-08-2010, 14:27
in Java 7 da un punto di vista dell'evoluzione del linguaggio, Oracle o non Oracle, ci saranno le lambda expressions.
Capirai, e quando uscira' Java 7 ?
E poi dovremo aspettare altri 10 anni per avere anche le closures ? :fagiano:
Java come linguaggio ormai e' fossilizzato.
Tutte le novita' e sviluppi interessanti si trovano nei linguaggi (Scala, Clojure, etc...) che predono di mira la JVM.
goldorak
16-08-2010, 14:30
mi sa che non hai capito :asd:
Gli errori grammaticali capitano a tutti di tanto in tanto.
Non ho avuto voglia di correggere. :O
Questa la prendo con le pinze, la considero e ci rifletterò su, ma non ne sono convinto pienamente, anche per via della mia propria ignoranza e poca esperienza che mi permette di capire e valutare le cose solo fino ad un certo punto.
Anzi, se hai voglia & tempo di sviluppare un po' il punto sarei felice di leggere le tue considerazioni.
Cerco di rispondere intanto a grandi linee (anche perche' se no non ne vado fuori :asd:) poi magari entriamo nei dettagli che piu' ti interessano.
Approssimativamente diciamo che quando Java e' stato progettato, gli autori si sono chiesti: "quali sono i maggiori motivi che rendono difficile imparare e programmare in C++ ? quali quelli che piu' spesso causano bug nei programmi scritti ?".
Da qui la scelta di single inheritance, controlli sui bound degli array, niente espressioni costanti, mancanza (inizialmente) di template/generics, enums...
Alcune di queste scelte sono ampiamente condivisibili, soprattutto quelle riguardandi una maggiore "sicurezza" del linguaggio. Quelle rivolte alla semplificazione del linguaggio un po' meno.
Idealmente un buon linguaggio dovrebbe avere un numero limitato di costrutti, ma tutti ortogonali tra loro, dando la possibilita' all'utente di costruirsi sopra quel che gli serve. In questo senso la semplificazione e' buona. Lo e' meno quando porta a dover scrivere piu' codice per fare le stesse cose, perche' in realta' invece che semplificare sposta la complessita' dal lato utente (e in generale sarebbe preferibile fare il contrario).
Faccio un paio di esempi che forse mi spiego meglio
Nelle prime versioni di Java mancavano gli enum. Una funzionalita' inutile del linguaggio dato che si potevano usare costanti intere. Al costo di diversi problemi. Non lo dico io, lo dice(va) la Sun, ovviamente dopo aver introdotto la funzionalita' nel linguaggio (apparente risolvendo alcuni problemi della controparte C++, perlomeno a sentire gli autori)
http://download.oracle.com/javase/1.5.0/docs/guide/language/enums.html
Piu' problematica e' stata la questione dei templates/generics.
I generics di Java (per una serie di motivi, in parte legati a vincoli esistenti, in parte per scelta progettuale) fondamentalmente sono un metodo pratico per evitare un sacco di downcast
(per un confronto tra i template di C++ e i generics di Java, puoi vedere delle slide qui (http://docs.google.com/viewer?a=v&q=cache:0H0yhB1VFF4J:www.cs.binghamton.edu/~mike/presentations/java-generics-cs580c-fall-2007.pdf+java+generics+vs+c%2B%2B+templates&hl=it&gl=it&pid=bl&srcid=ADGEESg6cpRjwXtm-T6GcTsOFWxaMIpaiTzpdDc2JfJmI0tZVU-xh94TNdw4qCzeTK_Pp1OTegJJV1a5XSIuP1ULre3KAS3kWnbVaV795Xr54C71R8ACtdq47eToiQzjXkcJCXrrA70d&sig=AHIEtbQxNgDs45yrBIJs7jA6cE91DgYnMg) ).
Rispetto ai template del C++ sono piu' semplici da usare (relativamente, sotto altri aspetti sono piu' complicati) ma si sono persi molti degli usi intelligenti che possono essere fatti come ad esempio
* Compile time assertions, ovvero la possibilita' di effettuare durante la compilazione verifiche non previste dal linguaggio per garantire una maggiore correttezza del programma
* Precalcolare durante la compilazione parti di codice, in modo da velocizzare lo startup del programma.
* Parametrizzare delle classi con delle policy. Se voglio implementare un contenitore (una mappa diciamo), posso decidere di farla nativamente multithread-safe (piu' chiamate da diversi thread non mi corrompono la struttura dati) o piu' efficace,ma utilizzabile da un solo thread alla volta. Con un parametro template posso specificare una classe che mi da a seconda di necessita' le performance o la sicurezza. E' vero che una cosa analoga lo posso fare con le classi e le interfacce, ma va detto che oltre a dover scrivere far scrivere piu' codice all'utente (non fosse altro che per istanziare esplicitamente la classe di policy) perdo la differenziazione a livello di tipi, mentre un contenitore thread-safe e uno no sono secondo me due cose ben differenti (e che vorrei magari poter distinguere).
Sono stato un po' piu' prolisso di quel che speravo :p, spero che almeno possa essere un buono spunto per discutere.
Andremmo un pò OT, anzi ci siamo già, ma ti posso dire che a livello di linguaggio la versione 2 è stabile, mentre si sta rifinendo la libreria standard.
E' da poco uscito il libro di riferimento, The D Programming Language, scritto da Alexandrescu (si, lo stesso di Modern C++ Design, e altre cose C++-related) basato su D 2.0.
Recentissimamente lo stesso Alexandrescu ha fatto un talk in Google proprio sull'argomento, al quale ti rimanderei per evitare di andare troppo OT: http://www.youtube.com/watch?v=RlVpPstLPEc
Parlando di D e Go, sul newsgroup di Go c'e' una interessante discussione in cui si paragonano i due:
http://groups.google.com/group/golang-nuts/browse_thread/thread/f24e7d46091e27ab?pli=1
assolutamente no: io ho la tastiera con layout UK e le parentesi graffe le faccio con Shift+parentesi quadra :Prrr:
(il layout della mia tastiera é anche il motivo per cui su questo forum non riesco a scrivere alcuni caratteri accentati, non so se qualcuno se ne é mai accorto :D)
Piccolo OT: sotto windows seleziona tastiera US (o UK) e lingua Italiana. In tal modo puoi scrivere tutte le lettere accentate che vuoi semplicemente preponendo il modificatore alla lettera (puoi usare non solo ` e ' per gli accenti aperti e chiusi, ma anche ~ " ^ ad esempio per aggiungere la dieresi ad una vocale. Funziona anche con le maiuscole). Dovrebbe funzionare anche in Gnome sotto linux. Un po' scomodo per programmare, ma allora basta passare rapidamente tra le due configurazione con alt-shift.
C++ fa schifo perche' e' un linguaggio bastardo. Ha tutti i difetti del C e nessuno dei suoi vantaggi. La necessita' di farlo "retrocompatibile" con il suo illustre progenitore l'ha reso un abominio. E tale e' restato in questi decenni.
Anzi la situazione continua a peggiorare con il C+x0.
Solo perche' e' il meno peggio che ci sia in giro (per una certa tipologia di progetti) non lo rende affatto un buon linguaggio.
Non sarei cosi' categorico. Il C++ ha molti vantaggi che il C non ha, e riesce ad eliminare molti dei suoi difetti (pur tenendone tanti altri).
Quali sarebbero questi vantaggi che il C ha e il C++ no ?
Oh i linguaggi ci sono, ma come in tutte le cose l'inerzia del popolino (e con questo intendo l'industria, gli sviluppatori etc...) e' molto forte. L'hardware ha subito una rivoluzione epocale passando da una architettura singole core a multicore, andiamo verso soluzioni hardware eterogenee e la maggior parte dei linguaggi usati tradizonalmente sono ancora del tipo imperativo. Nelle universita' invece di fare il lavaggio del cervello con Java, dovrebbero iniziare a spiegare e usare linguaggio funzionali che si adattano come guanti ai nuovi ambienti multicore. Dovrebbero insegnare paradigmi che vanno oltre il solito paradigma imperativo.
Vedo i linguaggi funzionali in grado di sostituire piu' i linguaggi come Java e C# che il C++ o il C, perlomeno nel medio termine. I linguaggi funzionali che piu' sono avanti nell'ambito della programmazione parallela "assistita" (tipo Haskell) di solito sacrifinano la predicibilita' dell'esecuzione, vuoi per il garbage collector che entra quando vuole, vuoi per la laziness del linguaggio che neanche se una data funzione viene mai calcolata, e questo e' decisamente contro i requisiti di molti ambiti della programmazione di sistema.
Ci sono altri linguaggi funzionali piu' adatti a questo compito (sto pensando in particolare ai dialetti Scheme pensati all'interfacciamento col C), tanto che ci fanno pure i giochi, ma allora ti trovi in una situazione analoga a quella dei linguaggi piu' tradizionali per quel che riguarda l'uso dei multicore (anche se costruirsi le astrazioni da se' dovrebbe risultare piu' semplice).
Beh se le critiche provengono da persone percui i linguaggi di programmazione si riducono tutti a Java e C++ la cosa fa sorridire.
Tristemente sorridire, li ignori a vai per la tua strada.
Se ti riferisci a Pike, tieni presente che la maggior parte del codice scritto in Google e' Java, Python o C++, per cui il focus su quei linguaggi ha un senso (senza contare che Pike ha gia' scritto un suo linguaggio, Limbo, ai tempi di Plan9).
pabloski
16-08-2010, 18:10
La morte di java non è vicina, troppo diffuso, troppo usato, troppa gente che ha buttato sangue per studiarlo.
Ellison è un .... lasciamo perdere .... e vedendo il successo di Android si è chiesto: "oh, ma non è che posso spillare qualche miliardo di dollari a Google?"
Oracle spera in un accordo extra giudiziale, visto che in un processo serio verrebbe fuori che Dalvik e Java di Oracle divergono su parecchi punti e difficilmente Google ha violato i loro brevetti ( quando sviluppò Dalvik fu prestata molta attenzione proprio a raggirare i brevetti di Sun ).
Ovviamente Ellison procederà in questo modo ogni volta che trova qualche gallina dalle uova d'oro e questo spingerà alcuni ad abbandonare Java e migrare ad altri linguaggi.
Personalmente preferisco un mondo dominato da Python.
anonimizzato
16-08-2010, 19:05
Ellison è un .... lasciamo perdere ....
In effetti non lo conosco ma a guardarlo in faccia sembra uno che pur di fare anche 1 solo dollaro in più sacrificherebbe qualsiasi progresso tecnologico senza problemi.
http://tintuc.etieudung.com/res/7e998e7d97fee96dcf76780da0ad375c2dc3c415.jpg
pabloski
16-08-2010, 19:17
E pensa che in un'università italiania c'è un professore di sistemi operativi identico e preciso ad Ellison :D
E' noto per la severità del suo esame, tipo 1 studente su 30 passa :sofico:
banryu79
16-08-2010, 22:09
E pensa che in un'università italiania c'è un professore di sistemi operativi identico e preciso ad Ellison :D
E' noto per la severità del suo esame, tipo 1 studente su 30 passa :sofico:
Quello col milione di dollari? :D
banryu79
16-08-2010, 22:16
Cerco di rispondere intanto a grandi linee (anche perche' se no non ne vado fuori :asd:) poi magari entriamo nei dettagli che piu' ti interessano.
...
[megacut]
Ti ringrazio; purtroppo sono di fretta (lavoretti extra), e visto che ti sei preso la briga di spendere del tempo per questo aspetto della discussione, voglio poterti rispondere senza liquidare il tutto in due parole.
Appena posso, torno e rispondo, intanto grazie :)
RaouL_BennetH
17-08-2010, 09:04
In effetti non lo conosco ma a guardarlo in faccia sembra uno che pur di fare anche 1 solo dollaro in più sacrificherebbe qualsiasi progresso tecnologico senza problemi.
http://tintuc.etieudung.com/res/7e998e7d97fee96dcf76780da0ad375c2dc3c415.jpg
{OT}
E' inquietante.... la somiglianza che ha con chuck norris :eek: :eek:
{/OT}
banryu79
07-09-2010, 14:52
Approssimativamente diciamo che quando Java e' stato progettato, gli autori si sono chiesti: "quali sono i maggiori motivi che rendono difficile imparare e programmare in C++ ? quali quelli che piu' spesso causano bug nei programmi scritti ?".
Ciao, ho trovato un po' di tempo per riflettere sulla questione.
Per quanto riguarda gli aspetti relativi al non esporre nel linguaggio Java alcuni dei "pitfall" più rognosi del C++ qualcosa già sapevo, perchè anni fa, quando approdai a Java, una delle prime letture introduttive su questo linguaggio che feci fu proprio relativa a questo aspetto.
Idealmente un buon linguaggio dovrebbe avere un numero limitato di costrutti, ma tutti ortogonali tra loro, dando la possibilita' all'utente di costruirsi sopra quel che gli serve. In questo senso la semplificazione e' buona.
Interessante; guarda, io sono completamente ignorante sul fronte della teoria relativa al design di un linguaggio di programmazione: mi piacerebbe capire meglio con un esempio, se mi fai la cortesia, questa faccenda dell'ortogonalità dei costrutti; avevi qualche caso specifico in mente mentre scrivevi la porzione che ho quotato?
Lo e' meno quando porta a dover scrivere piu' codice per fare le stesse cose, perche' in realta' invece che semplificare sposta la complessita' dal lato utente (e in generale sarebbe preferibile fare il contrario).
Mancandomi l'esperienza in termini di altri linguaggi (fin'ora ho usato solo C, C++ e Java, e giusto "assaggiato" qualcosa di SmallTalk e Python) forse con qualche tuo esempio posso capire meglio e individuare dei punti in Java in cui succede questo.
Comunque non sono sicuro del fatto che scrivere più codice per fare una cosa in un linguaggio ripetto ad un altro sia sempre più complesso (cioè aumenti la complessità lato utente).
Penso che lo sia la maggior parte delle volte ma non sempre, penso che la sola quantità di codice (caratteri) di per se non sia un parametro assoluto per giudicare la complessità.
Faccio un paio di esempi che forse mi spiego meglio
Nelle prime versioni di Java mancavano gli enum. Una funzionalita' inutile del linguaggio dato che si potevano usare costanti intere. Al costo di diversi problemi. Non lo dico io, lo dice(va) la Sun, ovviamente dopo aver introdotto la funzionalita' nel linguaggio (apparente risolvendo alcuni problemi della controparte C++, perlomeno a sentire gli autori)
http://download.oracle.com/javase/1.5.0/docs/guide/language/enums.html
Grazie, ho approfondito un po' e ho visto diverse tecniche, tipo l'uso di costanti intere, il "Typesafe enum patter" che di fatto sfrutta le classi, per finire con il costrutto apposito presente dalla versione 1.5 del linguaggio.
Piu' problematica e' stata la questione dei templates/generics.
I generics di Java (per una serie di motivi, in parte legati a vincoli esistenti, in parte per scelta progettuale) fondamentalmente sono un metodo pratico per evitare un sacco di downcast
(per un confronto tra i template di C++ e i generics di Java, puoi vedere delle slide qui (http://docs.google.com/viewer?a=v&q=cache:0H0yhB1VFF4J:www.cs.binghamton.edu/~mike/presentations/java-generics-cs580c-fall-2007.pdf+java+generics+vs+c%2B%2B+templates&hl=it&gl=it&pid=bl&srcid=ADGEESg6cpRjwXtm-T6GcTsOFWxaMIpaiTzpdDc2JfJmI0tZVU-xh94TNdw4qCzeTK_Pp1OTegJJV1a5XSIuP1ULre3KAS3kWnbVaV795Xr54C71R8ACtdq47eToiQzjXkcJCXrrA70d&sig=AHIEtbQxNgDs45yrBIJs7jA6cE91DgYnMg) ).
Ho letto con interesse le slide, più che altro per capire le differenze con i Template di C++ (visto che nella mia limitata esperienza con questo linguaggio, all'epoca, i Template li ho incontrati solo come "cliente").
Ti dirò, a me par di capire che a guardar bene le cose, in profondità, i Generics di Java e i Template di C++ sia due strumenti molto diversi, creati per motivi e con scopi in mente diversi.
In Java, in pratica, servono solo per evitare i cast: io personalmente trovo utile questa feature non tanto per i caratteri in meno da scrivere del cast, ma per la compile-time safety che invece senza non hai.
Inoltre, sebbe si possano portare esempi spaventosi d'uso dei Generics, nella mia esperienza in alcune situazioni li ho trovati utili per chiarire il codice, ad esempio, in questo caso:
public class FacciaElemento
{
protected boolean completa;
// Indica se la faccia e usata (es.: deflettori disabilitati)
protected boolean utilizzata = true;
// MODELLO 3D
protected List contorno3D;
protected List superfice3D;
protected List extra3D;
protected List quote3D;
// MODELLO METADSCRIZIONE 2D
protected List trattiFaccia;
protected List trattiMarcatura;
protected List trattiEntita;
protected List trattiFori;
...
con questo, dove la presenza del tipo parametrizzato nelle collezioni aumenta la chiarezza (almeno per me, che conosco il dominio del problema):
public class FacciaElemento
{
protected boolean completa;
// Indica se la faccia e usata (es.: deflettori disabilitati)
protected boolean utilizzata = true;
// MODELLO 3D
protected List<Vertice> contorno;
protected List<ElementoGL> superfice;
protected List<ArrayList<Vertice>> extra;
protected List<Quota3D> quote3D;
// MODELLO METADSCRIZIONE 2D
protected List<List<Tratto>> profilo;
protected List<List<Tratto>> marcature;
protected List<List<Tratto>> entita;
protected List<List<Tratto>> fori;
...
Rispetto ai template del C++ sono piu' semplici da usare (relativamente, sotto altri aspetti sono piu' complicati) ma si sono persi molti degli usi intelligenti che possono essere fatti come ad esempio
* Compile time assertions, ovvero la possibilita' di effettuare durante la compilazione verifiche non previste dal linguaggio per garantire una maggiore correttezza del programma
* Precalcolare durante la compilazione parti di codice, in modo da velocizzare lo startup del programma.
* Parametrizzare delle classi con delle policy. Se voglio implementare un contenitore (una mappa diciamo), posso decidere di farla nativamente multithread-safe (piu' chiamate da diversi thread non mi corrompono la struttura dati) o piu' efficace,ma utilizzabile da un solo thread alla volta. Con un parametro template posso specificare una classe che mi da a seconda di necessita' le performance o la sicurezza. E' vero che una cosa analoga lo posso fare con le classi e le interfacce, ma va detto che oltre a dover scrivere far scrivere piu' codice all'utente (non fosse altro che per istanziare esplicitamente la classe di policy) perdo la differenziazione a livello di tipi, mentre un contenitore thread-safe e uno no sono secondo me due cose ben differenti (e che vorrei magari poter distinguere).
Ripeto, per me i Generics di Java sono uno strumento diverso dai Template di C++. I template sono di un ordine di grandezza (e anche) più potenti, ma che Java (come linguaggio) sacrificasse la potenza in nome della safeness, si è sempre saputo. A ciò che il linguaggio "rinuncia" (per riprendere il tuo esempio, collezioni normali e collezioni thread-safe) la piattaforma poi sopperisce (JDK con varie salse).
Che poi a voler usare bene i Template mi pare che appunto ci voglia una grande esperienza, per evitare i pitfall (e facendo una ricerca se ne trovano parecchi) cosa che di per se non è un male, anzi, ma appunto questo aumenta la (passami il termine) complessità lato-utente.
In Java ho un linguaggio più semplice ma più sicuro e devo smazzarmi a imparare bene la piattaforma per fare certe cose e/o oppure scrivere più codice? Se vogliamo possimao considerare anche questo come un tipo di aumento della complessità.
Sono stato un po' piu' prolisso di quel che speravo :p, spero che almeno possa essere un buono spunto per discutere.
Ottimo spunto, mi interessa molto sentire il pensiero di persone esperte perchè è un grande stimolo per imparare cose nuove o vedere le vecchie da altre prospettive. Il problema è solo la mia limitata esperienza nel campo (considera che il software più complesso su cui abbia mai lavorato era un'applicazione desktop in Java e nell'ordine delle 50K loc), dunque mi rendo conto di non avere mai neanche sentito certe esigenze perchè immagino che certe cose "cominciano a farsi sentire" veramente quando si superano certe dimensioni critiche...
Ciao :)
pabloski
07-09-2010, 15:11
Da questa diatriba Google-Oracle spero solo che Scala guadagni consensi. Molti degli aspetti descritti da marco.r sono stati affrontati e brillantemente risolti da questo linguaggio.
Scala mi è stato consigliato la settimana scorsa da un mio collega ( che ne è particolarmente entusiasta ). Ho guardato un pò in rete e c'erano commenti negativi circa la complessità del modello funzionale supportato da Scala. La programmazione funzionale non è complessa è solo molto diversa ( in termini di mentalità da adottare ) rispetto a quella imperativa.
Però dopo 4 giorni di studio e alcuni esperimenti effettuati con questo linguaggio, devo dire che è un linguaggio che può fare la differenza.
Go è il linguaggio che google vuole promuovere ed è un linguaggio che affronta e risolve alcune problematiche, ma Scala fa di più ( soprattutto per la gestione del multithreading l'approccio usato mi è piaciuto non poco ). L'unica somiglianza tra i due è che sono entrambi linguaggi a tipizzazione statica :D
Molti diranno che la tipizzazione dinamica è meglio, ecc... ecc... e che le unit test aiutano ad eliminare bug dovuti alla dinamicità dei tipi, ma come diceva Edsger Dijkstra "i test provano solo l'esistenza di errori, non l'assenza" :D
banryu79
07-09-2010, 16:54
Da questa diatriba Google-Oracle spero solo che Scala guadagni consensi. Molti degli aspetti descritti da marco.r sono stati affrontati e brillantemente risolti da questo linguaggio.
Scala mi è stato consigliato la settimana scorsa da un mio collega ( che ne è particolarmente entusiasta ). Ho guardato un pò in rete e c'erano commenti negativi circa la complessità del modello funzionale supportato da Scala. La programmazione funzionale non è complessa è solo molto diversa ( in termini di mentalità da adottare ) rispetto a quella imperativa.
Uhm, Scala sta cominciando a interessarmi :)
Devo proprio mettermi d'impegno, e provarlo seriamente.
Sarà un po' una sfida ma sarà anche molto divertente imparare a programmare con una nuova prospettiva.
Però dopo 4 giorni di studio e alcuni esperimenti effettuati con questo linguaggio, devo dire che è un linguaggio che può fare la differenza.
Dove hai notato la differenza maggiore?
Go è il linguaggio che google vuole promuovere ed è un linguaggio che affronta e risolve alcune problematiche, ma Scala fa di più ( soprattutto per la gestione del multithreading l'approccio usato mi è piaciuto non poco ). L'unica somiglianza tra i due è che sono entrambi linguaggi a tipizzazione statica :D
Molti diranno che la tipizzazione dinamica è meglio, ecc... ecc... e che le unit test aiutano ad eliminare bug dovuti alla dinamicità dei tipi, ma come diceva Edsger Dijkstra "i test provano solo l'esistenza di errori, non l'assenza" :D
Anche io preferisco la tipizzazione statica.
pabloski
07-09-2010, 18:26
Dove hai notato la differenza maggiore?
l'espressività, la gestione del multithreading e la programmazione funzionale ( che a dire il vero non avevo mai studiato :D )
con Scala, almeno nel mio caso, riesco a non arrotolarmi tra i thread, le race conditions e variabili che svolazzano e perdono pezzi
cdimauro
08-09-2010, 00:33
Go è il linguaggio che google vuole promuovere ed è un linguaggio che affronta e risolve alcune problematiche, ma Scala fa di più ( soprattutto per la gestione del multithreading l'approccio usato mi è piaciuto non poco ). L'unica somiglianza tra i due è che sono entrambi linguaggi a tipizzazione statica :D
Molti diranno che la tipizzazione dinamica è meglio, ecc... ecc... e che le unit test aiutano ad eliminare bug dovuti alla dinamicità dei tipi, ma come diceva Edsger Dijkstra "i test provano solo l'esistenza di errori, non l'assenza" :D
Su questo non ci sono dubbi, ma di fatto con un approccio allo sviluppo TDD / BDD la differenza fra linguaggi a tipizzazione statica e dinamica viene meno.
Col vantaggio che con uno a tipizzazione dinamica i tempi di sviluppo sono generalmente più corti, e non di poco...
Dijkstra può dire quello che vuole, ma sono al secondo progetto sviluppato con queste metodologie (il primo TDD, il secondo molto simile al BDD), e con 124 e 148 test rispettivamente io dormo sonni tranquilli, mentre i miei colleghi si arrabattano a caccia dei bug e a rifare i test end-to-end.
Giusto per essere chiari, finora ho scovato un solo bug sul secondo progetto, nemmeno grave (riguardava la reportistica), ed era dovuto a un test che non avevo aggiornato correttamente a seguito della solita modifica in corso d'opera (avevo test e codice entrambi non aggiornati allo stesso modo).
Tra l'altro mi posso permettere il lusso di stravolgere anche il codice, sicuro del fatto che dietro ho una batteria di test che mi consente di verificare in ogni momento che la logica sia consistente e i requisiti rispettati. ;)
Su questo non ci sono dubbi, ma di fatto con un approccio allo sviluppo TDD / BDD la differenza fra linguaggi a tipizzazione statica e dinamica viene meno.
Col vantaggio che con uno a tipizzazione dinamica i tempi di sviluppo sono generalmente più corti, e non di poco...
Dijkstra può dire quello che vuole, ma sono al secondo progetto sviluppato con queste metodologie (il primo TDD, il secondo molto simile al BDD), e con 124 e 148 test rispettivamente io dormo sonni tranquilli, mentre i miei colleghi si arrabattano a caccia dei bug e a rifare i test end-to-end.
Giusto per essere chiari, finora ho scovato un solo bug sul secondo progetto, nemmeno grave (riguardava la reportistica), ed era dovuto a un test che non avevo aggiornato correttamente a seguito della solita modifica in corso d'opera (avevo test e codice entrambi non aggiornati allo stesso modo).
Tra l'altro mi posso permettere il lusso di stravolgere anche il codice, sicuro del fatto che dietro ho una batteria di test che mi consente di verificare in ogni momento che la logica sia consistente e i requisiti rispettati. ;)
Maestro http://www.indievault.it/forum/images/smilies/smiley_hail.gif
Io sto provando a convertirmi al TDD nei miei progetti in sviluppo dopo il disastro di un bug in release, proprio non si può andare avanti così.
Però per un gioco, che mi testo?
Per ora ho zeppato il codice di Assert, e già è qualcosa... hai consigli su come testare una roba arbitraria e "spaghettosa" come del codice di gameplay in C++?
cdimauro
08-09-2010, 01:58
Infatti te ne rendi conto quando hai a che fare con bug rognosi che ti fanno perdere un mare di tempo. Al che realizzi che il tempo è meglio spenderlo scrivendo del codice che testi per te il tuo codice. :D
Sul testing del codice di un gioco non saprei di preciso, visto che è da un pezzo che non scrivo roba del genere, però so che fek ha importato il TDD alla Crytek, e adesso lavorano con questo modello di sviluppo (anche Federico, se non ricordo male, lavora con lui adesso e si diverte col TDD). Quindi è sicuramente possibile anche in quest'ambito.
Nello specifico, non vedo comunque particolari difficoltà, e provo a spiegarmi. Per testare un certo "comportamento", inizializzi l'ambiente (magari usando dei mock per simulare oggetti concreti, come i dispositivi di input, per esempio) opportunamente, fai eseguire il codice e controlli che l'output sia quello che ti aspetti.
Sì, lo so che sembra semplice, ma... E' semplice. :D Per lo meno faccio così coi miei progetti. :p
tomminno
08-09-2010, 07:40
Però per un gioco, che mi testo?
Per ora ho zeppato il codice di Assert, e già è qualcosa... hai consigli su come testare una roba arbitraria e "spaghettosa" come del codice di gameplay in C++?
Posso consigliarti CppUnit e VoodooMock.
Su questo non ci sono dubbi, ma di fatto con un approccio allo sviluppo TDD / BDD la differenza fra linguaggi a tipizzazione statica e dinamica viene meno.
Col vantaggio che con uno a tipizzazione dinamica i tempi di sviluppo sono generalmente più corti, e non di poco...
Su TDD & Co. sono d'accordo con te quindi non aggiungo niente.
Su questa affermazione, beh... IMHO dipende dal linguaggio. Io di solito sono un static-typing-kind-of-guy, perchè concetti come il duck typing mi fanno sentire come nudo in una pianura sotto la pioggia battente e senza ripari. Ma forse sono solo io che sono una persona insicura :D
Se mi prendi come esempi Java vs Python o C++ vs Python hai sicuramente ragione, ma ci sono linguaggi con un type system più evoluto che grazie ad una buona dose di type inference ti permettono di scrivere codice "alla python" mantenendo una tipizzazione statica (haskell, D, ML, ecc...ok haskell e ML sono alieni ma D è sullo stesso stile).
Poi ci sono cose fuori dal mondo tipo ATS ( http://www.ats-lang.org/ ), che porta una ventata di concetti innovativi e sicuramente interessanti sull'argomento type system, anche se con una sintassi IMHO orribile :D
Nello specifico, non vedo comunque particolari difficoltà, e provo a spiegarmi. Per testare un certo "comportamento", inizializzi l'ambiente (magari usando dei mock per simulare oggetti concreti, come i dispositivi di input, per esempio) opportunamente, fai eseguire il codice e controlli che l'output sia quello che ti aspetti.
E invece ce ne sono, e sono date dalla natura contorta dell'input e dell'output:
-l'input è imprevedibile in quanto un flusso incrementale in ogni sim che si rispetti ogni frame dipende dal precedente + gli input del mondo esterno.
Chiaramente se c'è un errore nei frames precedenti diventa difficilissimo estrarlo a monte di qualche migliaio di frames già calcolate.
E non basterebbe testare individualmente ogni frame, perchè il bug potrebbe essere proprio in come si evolve la simulazione (cosa tipica).
Inoltre fare un mock di un oggetto complesso come è il giocatore è un'impresa decisamente ardua, si tratta di prevedere ogni singola combinazione di azioni che potrebbe fare una persona vera.
Tutti questi problemi sono estranei ad un programma non-realtime, visto che la procedura inizia cliccando una roba e muore quando decide lei.
-l'output ha forme complesse e spesso non è verificabile.
Ad esempio i dati spediti alla GPU "spariscono" dal sistema verificabile, per riapparire come immagini a schermo. Difficile testare immagini!
In un sistema a shader testare solo il lato CPU è insignificante per garantire la correttezza del risultato, vista la complessità del software lato GPU.
Stesso dicasi dell'output di un codice di gameplay: spesso ha risultati assolutamente arbitrari, e solitamente anche loro sparsi su più frame.
Tipo, se ha una collisione rimbalza, se prende un'arma inizia l'animazione, se clicchi una cosa esce fuori il menù...
Sicuramente si può testare una buona parte del codice, soprattutto quello di basso livello... ma non si potrà mai dire "passo i test, quindi sono in una botte di ferro".
Il che alla fine rende l'intero sforzo pressochè inutile, visto che i test manuali li devi fare uguale.
:stordita:
cdimauro
08-09-2010, 13:25
Su TDD & Co. sono d'accordo con te quindi non aggiungo niente.
Su questa affermazione, beh... IMHO dipende dal linguaggio. Io di solito sono un static-typing-kind-of-guy, perchè concetti come il duck typing mi fanno sentire come nudo in una pianura sotto la pioggia battente e senza ripari. Ma forse sono solo io che sono una persona insicura :D
Io sono di matrice pascaliana, per cui ti posso capire. Ma col tempo ho imparato ad apprezzare la tipizzazione dinamica, e roba come il duck typing (che trovo fantastico). :fagiano:
Se mi prendi come esempi Java vs Python o C++ vs Python hai sicuramente ragione, ma ci sono linguaggi con un type system più evoluto che grazie ad una buona dose di type inference ti permettono di scrivere codice "alla python" mantenendo una tipizzazione statica (haskell, D, ML, ecc...ok haskell e ML sono alieni ma D è sullo stesso stile).
Purtroppo la sintassi non riesco a farmela digerire.
Poi ci sono cose fuori dal mondo tipo ATS ( http://www.ats-lang.org/ ), che porta una ventata di concetti innovativi e sicuramente interessanti sull'argomento type system, anche se con una sintassi IMHO orribile :D
Ti dirò: già il fatto che non abbia le graffe e i punti e virgola, e roba come begin, end, then, mi ha messo a mio agio. :p
E invece ce ne sono, e sono date dalla natura contorta dell'input e dell'output:
-l'input è imprevedibile in quanto un flusso incrementale in ogni sim che si rispetti ogni frame dipende dal precedente + gli input del mondo esterno.
Chiaramente se c'è un errore nei frames precedenti diventa difficilissimo estrarlo a monte di qualche migliaio di frames già calcolate.
E non basterebbe testare individualmente ogni frame, perchè il bug potrebbe essere proprio in come si evolve la simulazione (cosa tipica).
Inoltre fare un mock di un oggetto complesso come è il giocatore è un'impresa decisamente ardua, si tratta di prevedere ogni singola combinazione di azioni che potrebbe fare una persona vera.
Tutti questi problemi sono estranei ad un programma non-realtime, visto che la procedura inizia cliccando una roba e muore quando decide lei.
Però è anche vero che a un gioco devi conferire una certa meccanica, per cui delle regole le devi pur decidere. Ed è quello che devi testare, appunto.
Poi la TDD non ti garantisce automaticamente un sistema a prova di bug. Puoi sbagliare a scrivere i test, oppure non ne hai scritto qualcuno per degli scenari che fanno parte dei requisiti.
I requisiti sono, però, il punto di partenza per tirare fuori la test suite.
-l'output ha forme complesse e spesso non è verificabile.
Ad esempio i dati spediti alla GPU "spariscono" dal sistema verificabile, per riapparire come immagini a schermo. Difficile testare immagini!
Lo puoi fare con delle immagini di riferimento. Ovviamente non è così comodo come una assertEquals, perché devi crearti delle funzioni che eseguono dei confronti con una certa approssimazione, ma penso sia fattibile.
In un sistema a shader testare solo il lato CPU è insignificante per garantire la correttezza del risultato, vista la complessità del software lato GPU.
Puoi testare anche quello. :) Dato un certo input X, cosa ti aspetti dall'esecuzione dello shader F? ;)
Stesso dicasi dell'output di un codice di gameplay: spesso ha risultati assolutamente arbitrari, e solitamente anche loro sparsi su più frame.
Tipo, se ha una collisione rimbalza, se prende un'arma inizia l'animazione, se clicchi una cosa esce fuori il menù...
Ma sono tutti scenari che puoi definire e implementare. Alla meccanica di gioco dovrai pur dare una certa forma, come dicevo prima, e l'elenco dei requisiti a cui deve sottostare rappresenta il punto di partenza per stilare la test list.
Sicuramente si può testare una buona parte del codice, soprattutto quello di basso livello... ma non si potrà mai dire "passo i test, quindi sono in una botte di ferro".
Su questo concordo.
Il che alla fine rende l'intero sforzo pressochè inutile, visto che i test manuali li devi fare uguale.
:stordita:
Quelli lasciali alla sezione di Q&A. ;)
Per me il test manuale è sostanzialmente morto, perché se per simularlo devo eseguire n passi, preferisco scrivere un pezzo di codice in cui formalizzo il tutto ed eseguo quelle n determinate azioni, verificando di aver ottenuto quello che mi aspettavo.
Interessante; guarda, io sono completamente ignorante sul fronte della teoria relativa al design di un linguaggio di programmazione: mi piacerebbe capire meglio con un esempio, se mi fai la cortesia, questa faccenda dell'ortogonalità dei costrutti; avevi qualche caso specifico in mente mentre scrivevi la porzione che ho quotato?
Ah guarda che io ragionavo in termini decisamente pragmatici. Penso sia condivisibile che in generale più complesso è un linguaggio di programmazione più è difficile da "dominare". Quindi l'idea sarebbe averne uno relativamente semplice in cui ho un numero limitato di costrutti, che permettano però di essere combinati in modo da poter rappresentare le varie astrazioni di cui il programmatore ha bisogno.
Si scontrano quindi due necessità, da un lato quella di lasciare semplice il linguaggio, dall'altro renderlo espressivo a sufficienza. In un certo senso è come dover coprire una superficie con delle toppe; voglio coprire il più possibile usando meno stoffa che posso. Un linguaggio ortogonale ha costrutti che non si sovrappongono per cui con meno complessità ottengo di più.
All'atto pratico bisogna però accettare dei compromessi, soprattutto per le funzionalità più importanti e usate, per cui una soluzione è quello di avere un core del linguaggio che sia compatto ed espressivo, ed eventualmente aggiungere dello zucchero sintattico per le funzionalità più usate.
Per fare un esempio: in un linguaggio ad oggetti non è indispensabile far sì che funzioni e metodi siano elementi di prima classe (e.g. li si possa passare come argomenti ad altri metodi). In fondo, è sufficiente creare un oggetto con un metodo specifico che istanzierò e passerò come argomento: se conosco come funziona un oggetto sono a posto, senza dover imparare e ricordarmi cosa sono le closure. Non è però una soluzione idilliaca, perchè ad esempio se voglio passare una funzione di confronto tra due valori vuol dire che devo definire un oggetto, crearne una istanza etc., è più pesante di una semplice funzione sia dal punto di vista concettuale, che di tasti da premere.
È più il vantaggio di aggiungere le closure o di avere un linguaggio più semplice ? Non troverai tra i programmatori una risposta uguale ad un'altra :asd:, se avessi sottomano un buon linguaggio dovresti riuscire a simularle in modo più intuitivo grazie ad altre funzionalità (ad esempio un sistema di macro).
Mancandomi l'esperienza in termini di altri linguaggi (fin'ora ho usato solo C, C++ e Java, e giusto "assaggiato" qualcosa di SmallTalk e Python) forse con qualche tuo esempio posso capire meglio e individuare dei punti in Java in cui succede questo.
Beh un esempio (almeno fino a Java 7) è il discorso delle closure ; trovi un paio di confronti qui.
http://blog.html.it/08/03/2010/verso-java-7-lambda-expressions-e-closures/
Ci sono aspetti legati al type-system, ma che sono difficili da ricondurre a brevi esempi, cercherò di svilupparli in un post a parte.
Comunque non sono sicuro del fatto che scrivere più codice per fare una cosa in un linguaggio ripetto ad un altro sia sempre più complesso (cioè aumenti la complessità lato utente).
Penso che lo sia la maggior parte delle volte ma non sempre, penso che la sola quantità di codice (caratteri) di per se non sia un parametro assoluto per giudicare la complessità.
Sì, sicuramente non è sempre vero; tieni presente che io non mi riferivo alla quantità di caratteri in sè (altrimenti staremmo tutti a programmare in APL :asd:), è più la complessità che spesso è sottointesa al codice in più .Per tornare all'esempio delle closure prima, non è il fatto di dover scrivere qualche riga in più per una callback, ma il fatto che in un caso devo pensare ad una semplice funzione (che magari fa riferimento a qualche variabile locale), e nell'altro devo pensare ad una classe, ad una sua istanza che devo creare, al suo stato interno, che devo inizializzare e poi coordinare con l'ambiente in cui è stato creato.
Ripeto, per me i Generics di Java sono uno strumento diverso dai Template di C++. I template sono di un ordine di grandezza (e anche) più potenti, ma che Java (come linguaggio) sacrificasse la potenza in nome della safeness, si è sempre saputo. A ciò che il linguaggio "rinuncia" (per riprendere il tuo esempio, collezioni normali e collezioni thread-safe) la piattaforma poi sopperisce (JDK con varie salse).
Che poi a voler usare bene i Template mi pare che appunto ci voglia una grande esperienza, per evitare i pitfall (e facendo una ricerca se ne trovano parecchi) cosa che di per se non è un male, anzi, ma appunto questo aumenta la (passami il termine) complessità lato-utente.
Li considero anche io strumenti diversi, ma tieni presenti che sono nati da necessità analoghe. I template del c++ sono diventati così potenti quasi "per sbaglio", ci si è accorti solo dopo un po' di tempo di quel che si poteva fare. Anche per questo sono complessi da usare più del dovuto. Il fatto che lo siano in C++ non vuol dire che non si possa disegnare qualcosa di analogo ma più usabile e meno error-prone. Java era nella condizione di poter valutare questo e imparare dagli errori del C++. Si è preferito più un approccio del tipo "templates are hard, let's go shopping" :D.
Il fatto che poi alcune funzionalità siano fortnite dalla piattaforma è un bene ma ha le sue controindicazioni. Su tutte il fatto che devi aspettare che chi te la fornisce ce le aggiunga. Se è lento o non lo vuole fare ti attacchi e aspetti (vedi di nuovo l'esempio delle closure in Java).
In Java ho un linguaggio più semplice ma più sicuro e devo smazzarmi a imparare bene la piattaforma per fare certe cose e/o oppure scrivere più codice? Se vogliamo possimao considerare anche questo come un tipo di aumento della complessità.
Su questo nulla da obiettare.
Forse il mio rilevatore di sarcasmo oggi non funziona bene ma... Rob Pike non è proprio l'ultimo degli stronzi. http://en.wikipedia.org/wiki/Rob_Pike
Lassà sta ;)
"template are hard, let's go shopping" :D.
LOL :D Barbie-Consulente ha sempre la soluzione giusta!
banryu79
09-09-2010, 10:15
Ah guarda che io ragionavo in termini decisamente pragmatici. Penso sia condivisibile che in generale più complesso è un linguaggio di programmazione più è difficile da "dominare". Quindi l'idea sarebbe averne uno relativamente semplice in cui ho un numero limitato di costrutti, che permettano però di essere combinati in modo da poter rappresentare le varie astrazioni di cui il programmatore ha bisogno.
Si scontrano quindi due necessità, da un lato quella di lasciare semplice il linguaggio, dall'altro renderlo espressivo a sufficienza. In un certo senso è come dover coprire una superficie con delle toppe; voglio coprire il più possibile usando meno stoffa che posso. Un linguaggio ortogonale ha costrutti che non si sovrappongono per cui con meno complessità ottengo di più.
All'atto pratico bisogna però accettare dei compromessi, soprattutto per le funzionalità più importanti e usate, per cui una soluzione è quello di avere un core del linguaggio che sia compatto ed espressivo, ed eventualmente aggiungere dello zucchero sintattico per le funzionalità più usate.
Grazie della risposta articolata, mi hai fatto capire cosa si intende per ortogonalità tra i costrutti di un linguaggio di programmazione.
Per fare un esempio: in un linguaggio ad oggetti non è indispensabile far sì che funzioni e metodi siano elementi di prima classe (e.g. li si possa passare come argomenti ad altri metodi). In fondo, è sufficiente creare un oggetto con un metodo specifico che istanzierò e passerò come argomento: se conosco come funziona un oggetto sono a posto, senza dover imparare e ricordarmi cosa sono le closure. Non è però una soluzione idilliaca, perchè ad esempio se voglio passare una funzione di confronto tra due valori vuol dire che devo definire un oggetto, crearne una istanza etc., è più pesante di una semplice funzione sia dal punto di vista concettuale, che di tasti da premere.
È più il vantaggio di aggiungere le closure o di avere un linguaggio più semplice ? Non troverai tra i programmatori una risposta uguale ad un'altra :asd:, se avessi sottomano un buon linguaggio dovresti riuscire a simularle in modo più intuitivo grazie ad altre funzionalità (ad esempio un sistema di macro).
e
Beh un esempio (almeno fino a Java 7) è il discorso delle closure ; trovi un paio di confronti qui.
http://blog.html.it/08/03/2010/verso-java-7-lambda-expressions-e-closures/
Ci sono aspetti legati al type-system, ma che sono difficili da ricondurre a brevi esempi, cercherò di svilupparli in un post a parte.
Grazie, sei stato chiaro, e per gli esempi puoi anche lasciare stare: ho seguito il link e ho letto dell'altra roba in merito, pian piano ho cominciato a capire e a ricondurre alcuni casi a esperienze che ho avuto negli ultimi mesi.
Visto che hai citato Java 7 (sperando che i tempi di rilascio non siano come quelli di Duke Nuke'em Forever :D) ho trovato un articolo interessante su una implementazione "ParallelArray" per parallelizzare in modo trasparente all'utente programmatore operazioni di ricerca e ordinameto sulle strutture dati in memoria.
C'è una considerazione (con esempio) interessante su come verrebbe semplificato il tutto con l'adozione delle closure, se interessa eccolo: link (http://www.ibm.com/developerworks/java/library/j-jtp03048.html?S_TACT=105AGX01&S_CMP=LP#listing2).
...
Li considero anche io strumenti diversi, ma tieni presenti che sono nati da necessità analoghe. I template del c++ sono diventati così potenti quasi "per sbaglio", ci si è accorti solo dopo un po' di tempo di quel che si poteva fare. Anche per questo sono complessi da usare più del dovuto. Il fatto che lo siano in C++ non vuol dire che non si possa disegnare qualcosa di analogo ma più usabile e meno error-prone. Java era nella condizione di poter valutare questo e imparare dagli errori del C++. Si è preferito più un approccio del tipo "templates are hard, let's go shopping" :D.
Sei sicuro che l'approccio, all'epoca, sia stato quello e non uno tipo: "Fuck, we have a damned deadline, ship it now, as it is!"?
Lo chiedo perchè pochi giorni fa ho letto il motivo per cui Java non supporta il DBC. Ho letto che Gosling all'epoca aveva intenzione di implementato in Oak, ma per motivi di deadline è una delle cose rimaste fuori.
A questa pagina (http://www.cs.nuim.ie/~jpower/Courses/Previous/CS407/dbc/oak-p21.html) (estratta dalle specifiche preliminari di Oak) si può leggere quale era la fuanzione e l'implementazione pensata per il costrutto assert.
Sei sicuro che l'approccio, all'epoca, sia stato quello e non uno tipo: "Fuck, we have a damned deadline, ship it now, as it is!"?
Lo chiedo perchè pochi giorni fa ho letto il motivo per cui Java non supporta il DBC. Ho letto che Gosling all'epoca aveva intenzione di implementato in Oak, ma per motivi di deadline è una delle cose rimaste fuori.
A questa pagina (http://www.cs.nuim.ie/~jpower/Courses/Previous/CS407/dbc/oak-p21.html) (estratta dalle specifiche preliminari di Oak) si può leggere quale era la fuanzione e l'implementazione pensata per il costrutto assert.
Grazie per il link, in effetti da quel che riporti sembra piu' corretta la tua versione. Pardon, io riportavo quanto narrato dalla storigrafia ufficiale (il marketing sun :D).
banryu79
10-09-2010, 09:38
Grazie per il link, in effetti da quel che riporti sembra piu' corretta la tua versione. Pardon, io riportavo quanto narrato dalla storigrafia ufficiale (il marketing sun :D).
Era solo una considerazione circoscritta alla mancaza di una feature che doveva esserci (era stata prevista e voluta nel design del linguaggio).
Invece per quanto riguarda i template del C++, dopo aver letto le specifiche preliminari di Oak (a questa pagina (http://en.wikipedia.org/wiki/Oak_%28programming_language%29), in fondo, si può scaricare il pdf) deduco che proprio non erano previsti fin dal'inizio.
Un piccolo paragrafo da leggere (http://en.wikipedia.org/wiki/Java_%28software_platform%29#History) che sfiora i motivi per cui è stato scelto di creare un nuovo linguaggio invece che usare direttamente C++.
-l'input è imprevedibile in quanto un flusso incrementale in ogni sim che si rispetti ogni frame dipende dal precedente + gli input del mondo esterno.
Chiaramente se c'è un errore nei frames precedenti diventa difficilissimo estrarlo a monte di qualche migliaio di frames già calcolate.
Per come l'hai definito l'input è prevedibilissimo, il problema è semmai come interpretarlo :D :P. Concordo con the che un sistema dinamico (simulato o reale che sia) è ben difficile da valutare passo per passo nella sua interezza. Ci sono pero' degli accorgimenti che possono aiutare.
È molto importante avere un modello matematico di come funzionano le varie parti, perchè da questo puoi ricavare proprietà ed invarianti che devono valere durante la simulazione. Supponi ad esempio che il tuo problema è che l'algoritmo di path planning non funziona e gli omini del tuo gioco vanno dappertutto fuorche' dove serve, cerca di guardare l'evoluzione di alcune proprietà notevoli dell'algoritmo. Magri in teoria una cerca stima delle distanza dovrebbe sempre calare man mano che l'oggetto procede. Se non è cosi'evidentemente l'oggetto non si muove verso la direzione prevista, in caso contrario magari è proprio l'algoritmo che non si adatta al tipo di ambiente. Se fai tu la gestione della fisica puo' essere difficile verificare che l'evoluzione sia corretta, ma monitorando l'energia totale del sistema puoi magari accorgerti che per qualche motivo ogni tanto aumenta mentre dovrebbe sempre diminuire (modulo gli input dati ovviamente, ma quelli li puoi monitorare).
In altri casi può essere utile estrarre proprietà o eventi discreti dal sistema continuo che ti possono fornire utili indicazioni o meglio ancora magari riesci a monitorare automaticamente; puoi utilizzarli per verificare sequenze di eventi inconsistenti, oppure per verificare post-mortem se gli eventi tra due snapshot dello stato del sistema hanno senso.
Poi (ma questo e'un consiglio generale, ma troppe volte sottovalutato), usa il type system a tuo favore per impedire già in fase di compilazione di fare errori :P.
È un bel lavoro, ma spesso ripaga e la maggior parte di lavoro resta anche quando cambiano le specifiche.
-l'output ha forme complesse e spesso non è verificabile.
Ad esempio i dati spediti alla GPU "spariscono" dal sistema verificabile, per riapparire come immagini a schermo. Difficile testare immagini!
Puoi rimandare indietro la schermata alla cpu e confrontarla con l'immagine prevista. Se vai a guardare i browser come Webkit hanno una batteria di immagini di riferimento con le quali i test fanno il confronto in modo automatico.
Il problema grosso ovviamente è che si tratta di una mole notevole di lavoro; bisogna trovare il compromesso tra generare i test off-line (con i quali riesci a individuare più facilmente l'errore una volta che un test fallisce) e quelli online (precondizioni, invarianti etc) che danno spesso una indicazione più approssimativa, ma più facile da rilevare.
Per come l'hai definito l'input è prevedibilissimo, il problema è semmai come interpretarlo :D :P. Concordo con the che un sistema dinamico (simulato o reale che sia) è ben difficile da valutare passo per passo nella sua interezza. Ci sono pero' degli accorgimenti che possono aiutare.
È molto importante avere un modello matematico di come funzionano le varie parti, perchè da questo puoi ricavare proprietà ed invarianti che devono valere durante la simulazione. Supponi ad esempio che il tuo problema è che l'algoritmo di path planning non funziona e gli omini del tuo gioco vanno dappertutto fuorche' dove serve, cerca di guardare l'evoluzione di alcune proprietà notevoli dell'algoritmo. Magri in teoria una cerca stima delle distanza dovrebbe sempre calare man mano che l'oggetto procede. Se non è cosi'evidentemente l'oggetto non si muove verso la direzione prevista, in caso contrario magari è proprio l'algoritmo che non si adatta al tipo di ambiente. Se fai tu la gestione della fisica puo' essere difficile verificare che l'evoluzione sia corretta, ma monitorando l'energia totale del sistema puoi magari accorgerti che per qualche motivo ogni tanto aumenta mentre dovrebbe sempre diminuire (modulo gli input dati ovviamente, ma quelli li puoi monitorare).
In altri casi può essere utile estrarre proprietà o eventi discreti dal sistema continuo che ti possono fornire utili indicazioni o meglio ancora magari riesci a monitorare automaticamente; puoi utilizzarli per verificare sequenze di eventi inconsistenti, oppure per verificare post-mortem se gli eventi tra due snapshot dello stato del sistema hanno senso.
Poi (ma questo e'un consiglio generale, ma troppe volte sottovalutato), usa il type system a tuo favore per impedire già in fase di compilazione di fare errori :P.
È un bel lavoro, ma spesso ripaga e la maggior parte di lavoro resta anche quando cambiano le specifiche.
E' che detto a parole è tanto bello... quando invece prendi in mano la tastiera e provi a tradurlo in test veri... non so dove mettere mano!
Già nei tuoi esempi c'è una falla che riduce l'utilità del tutto:
verificare i soli bounds coi test non verifica che l'algoritmo sia corretto, ma solo che non sia del tutto sbagliato.
E c'è una grossissima differenza.
Potrei avere per esempio un bug che fa oscillare continuamente l'energia della simulazione, mantenendola nei bounds ma creando quell'effetto di stuttering tipico delle simulazioni fisiche fatte male.
Oppure il bug potrebbe essere proprio che gli omini stanno fermi dove nascono; o che si muovono lentamente; o...
Il fatto è che alla base del divertimento in un gioco, c'è un sistema di regole che si evolve nei modi più disparati.
E proprio per questo, valutare la correttezza delle regole dalle loro evoluzioni risulta molto spinoso, il che riduce l'efficacia del TDD:
un test è tanto più efficace quanto più si trova a valle dei risultati dell'algoritmo.
mentre in un VG solo elencare tutte le condizioni corrette spesso non è un compito banale, e nei più banali equivale a programmare il gioco stesso.
Facciamo un esempio, su un gioco stupido come Bejeweled; che batteria di test metteresti su per controllare che la situazione della griglia di gioco è coerente ad ogni mossa?
Puoi rimandare indietro la schermata alla cpu e confrontarla con l'immagine prevista. Se vai a guardare i browser come Webkit hanno una batteria di immagini di riferimento con le quali i test fanno il confronto in modo automatico.
Il problema grosso ovviamente è che si tratta di una mole notevole di lavoro; bisogna trovare il compromesso tra generare i test off-line (con i quali riesci a individuare più facilmente l'errore una volta che un test fallisce) e quelli online (precondizioni, invarianti etc) che danno spesso una indicazione più approssimativa, ma più facile da rilevare.
Si in effetti questa è la soluzione più attuabile di tutte... per ogni feature del motore grafico o fisico metto su una reference image, che viene pesata contro il frame corrente.
Ma anche qua abbiamo dei problemi:
-qual'è il range accettabile di "glitches" per cui l'immagine è scorretta?
L'offset di un solo pixel sulla telecamera crea un errore su tutti i pixel della scena...
mentre moltissime tecniche grafiche creano un risultato non deterministico, corretto solo "a occhio" e non al pixel.
-come faccio a generare la reference, se il sistema non funziona?
Per scene complesse, sarebbe possibile usare questi test solo a posteriori, per la manutenzione; usarli come obiettivo da raggiungere non si può.
Pessimismo a palate :D
cdimauro
11-09-2010, 05:29
Le generi a mano? :fagiano:
Comunque nel tuo caso sarebbe interessante conoscere da fek o Ufo13 in che modo utilizzano la TDD per lo sviluppo di Crysis 2.
Le generi a mano? :fagiano:
In effetti per un gioco "a stati finiti" si potrebbe fare... ho fatto l'esempio peggio :asd:
Comunque nel tuo caso sarebbe interessante conoscere da fek o Ufo13 in che modo utilizzano la TDD per lo sviluppo di Crysis 2.
Penso ci sia sopra un NDA clamoroso... difficile che succeda.
Comunque sarei curiosissimo anche io.
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.