Newsgroup: it.comp.java
Titolo: Java e C#

Salve ng,
sto studiando per necessità il linguaggio C#. Visto che sono ormai anni che 
sviluppo in Java, durante lo studio di C# mi viene naturale chiedermi che 
cosa C# offra di diverso rispetto a Java.
Beh, finora - ma non voglio scatenare polemiche - non ho trovato molto che 
in C# si possa fare e in Java no, intendo dire, ovviamente, in termini di 
linguaggio; il più delle volte si tratta di costrutti che si emulano in Java 
con il ricorso a codice intermedio e qualche pattern.
Ho trovato interessante, in C#, la presenza dei delegate, che sono, per 
farla breve, i puntatori alle funzioni o ai metodi del C++.... mi piacerebbe 
sapere da voi se una simile caratteristica non vi piacerebbe trovarvela 
nelle successive release del linguaggio.
A me, personalmente, sì. Non nego che se usata impropriamente sia un 
rischio, però la troverei comoda in certe situazioni di nicchia dove, 
invece, mi trovo a costruire interfacce per ottenere l'astrazione che 
desidero.
Saluti a tutti,
    Scorpio.

 cosa C# offra di diverso rispetto a Java.
l'overload degli operatori, le collection, la gestione degli eventi e il 
già citato delegate, il concetto di disposable. giusto per citare le 
prime cose più eclatanti che saltano all'occhio appena uno ci si trova 
davanti.
-- 
Fino all'anno scorso avevo un solo difetto. Ero presuntuoso.
http://softvalley.blogspot.com


Io mi riferivo a concetti, strutture, elementi sintattici che in C#
sono presenti e in Java no, tant'è che ho scritto:
" non ho trovato molto che in C# si possa fare e in Java no, intendo dire, 
ovviamente, in termini di
linguaggio; il più delle volte si tratta di costrutti che si emulano in Java 
con il ricorso a codice intermedio e qualche pattern."
Tutto qui. L'overload di un operatore lo si può emulare con un metodo ad hoc 
(anche se inelegante), i delegate si possono emulare tramite interfacce e 
così via....
Scorpio.

 così via....
Se la metti così tutto si può fare in assembly (o direttamente in codice 
binario), emulando linguaggi di più alto livello... ;)
Sinceramente mi sembra che tra un operatore e un metodo ci sia una bella 
differenza, stesso discorso nel passare un metodo come oggetto invece di 
passare una classe con quel metodo (e relativa interfaccia).
Ciao,
Paolo

 passare una classe con quel metodo (e relativa interfaccia).
Non sei dell'idea, allora, che Java dovrebbe dotarsi di questi strumenti ?
Scorpio.

 ?
Magari non è di prima mano, ma non si era detto che con la 1.7 dovevano  
mettere le chiusure e quindi i delgati?
-- 
http://www.hostingjava.it/-SaThot/mail/me

 così via....
beh, questo ragionamento puoi divertirti ad applicarlo a tutti i 
linguaggi (per lo meno a quelli non dinamici).
quelle che ti ho elencato sono oggettivamente delle differenze 
sostanziali, che poi si possa supplire con degli (più o meno) artifici 
non mi pare un ragionamento con molto senso.


 Scorpio.
No, proprio il contrario.
Sono funzionalità utili (molte le uso in python e devo dire che mi 
semplificano molto la vita).
Ciao,
Paolo

 passare una classe con quel metodo (e relativa interfaccia).
Gli operatori in overloading sono puro 'zucchero sintattico' ripetto a
uso di funzioni 'nuove'.
Quanto ai delegati, non sono puntatori a funzione, ma di fatto
oggetti.

 oggetti.
E io che avevo scritto?! ;)
Ciao,
Paolo

 In che senso "nuove"?
Penso che intenda: funzioni che abbiano la stessa semantica dell'operatore: 
sovraccaricare l'operatore '*' per eseguire il prodotto tra matrici è 
equivalente a scrivere un metodo moltiplica(Matrice m) nell'oggetto matrice, 
a meno ovviamente dell'eleganza espressiva.
Scorpio. 

 a meno ovviamente dell'eleganza espressiva.
Il concetto era abbastanza chiaro, sì, non capivo il senso della parola 
"nuove" in quella frase: se la togli (e magari sostituisci il termine 
funzioni con metodi) non cambia nulla.
Ma è solo curiosità e pignoleria... ;)
Ciao,
Paolo

> interfacce e così via....
PX> Se la metti così tutto si può fare in assembly (o direttamente in
PX> codice binario), emulando linguaggi di più alto livello... ;)
PX> Sinceramente mi sembra che tra un operatore e un metodo ci sia una
PX> bella differenza,
Solo nella tua testa. Non offenderti, ma è solo una questione culturale,
sei  abituato  alla  notazione   algebrica  e  quindi  vedi  una  grande
differenza.  Io  che   oramai  mi  trovo  quasi  in   imbarazzo  con  le
calcolatrici algebriche e mi diletto con un linguaggio funzionale, trovo
che  l'overloading  degli  operatori  sia  niente di  più  che  zucchero
sintattico.
+ is a built-in function in `C source code'.
(+ &rest numbers-or-markers)
Return sum of any number of arguments, which are numbers or markers.
PX> stesso discorso nel passare un metodo come oggetto
PX> invece di passare una classe con quel metodo (e relativa
PX> interfaccia).
C'è invero una differenza di efficenza non da poco. Ma i delegate del C#
sono  come al solito  l'idea venuta  male. Molto  molto molto  meglio le
closures  (una  cosa che  puoi  emulare con  le  classi,  non certo  coi
semplici delegati)
-- 
 /\           ___                                    Ubuntu: ancient
/___/\_|_|\_|__|___Gian Uberto Lauri_____               African word
  //--\| | \|  |   Integralista GNUslamico            meaning "I can
\/                   e coltivatore diretto               not install
                               di software                   Debian"
a Cesare avrei detto di scrivermi | I would have told Caesar to write
a 
fn...@rat.vg
                    | me at 
fn...@rat.vg

 semplici delegati)
Decisamente meglio.
Cosa ancora migliore sarebbe rendere oggetti anche i metodi/funzioni, 
come fanno altri linguaggi.
Direzione in cui, IMHO, ci si sta muovendo (forse un po' lentamente...).
Ciao,
Paolo

> semplici delegati)
PX> Decisamente meglio.  Cosa ancora migliore sarebbe rendere oggetti
PX> anche i metodi/funzioni, come fanno altri linguaggi.  Direzione in
PX> cui, IMHO, ci si sta muovendo (forse un po' lentamente...).
Penso  che la closure  sia più  potente, in  quanto permette  appunto di
creare oggetti  (funzione più contesto)  che non sono altro  che oggetti
funzione parametrizzati.


 funzione parametrizzati.
Mi fai un esempio pratico?
Le closures le ho viste poco, guardandomi un po' groovy.
Tanto per citare un caso in altro linguaggio, in python per aggiungere 
un metodo farei:
class Pippo(object):
   pass
def talk(self):
   print 'Hello'
pippo = Pippo()
Pippo.speak = talk
pippo.speak() # scrive Hello
Con lo stesso criterio posso passare una funzione/metodo a un'altra, e 
poi gestirla senza preoccuparmi se, e a quale, appartiene a un oggetto.
Molto comodo nei decoratori, per esempio, o quando si generano oggetti 
dinamicamente.
Ciao,
Paolo

 mi pare un ragionamento con molto senso.
Mah, dipende poi da quanto costa questo artificio, in termini di codice e 
complessità  dello stesso... no ?
Scorpio. 

uso di funzioni 'nuove'.
Questo, però, limitatamente ai contesti C#/Java e in generale a tutti
quei linguaggi (vedi anche Delphi) che non supportano la creazione
statica di oggetti. Finora, ho visto farlo solo al C++. In C++
l'operator overloading è un po' più che zucchero sintattico, perché
esistono i template. Un template, per definizione, non può conoscere
il tipo su cui opera e quindi l'uso di un operatore può essere
fondamentale.

 funzione parametrizzati.
Sono due cose diverse: una chiusura la puoi avere anche senza
manipolazione esplicita delle funzioni. Per dire il gcc offre come
estensione le closures in C, eppure il C *non* ha modi veramente comodi
per gestire le funzioni (no, passarsi l'indirizzo è il minimo sindacale,
IMHO). 
La manipolazione esplicita delle funzione può essere fatta ovviamente
anche senza closures (basta che una funzione sia un cittadino di prima
classe del linguaggio). Confesso che non mi vengono in mente linguaggi
in cui ti passi in giro le funzioni comodamente senza closures. 
Il fatto che tutto questo si possa fare in Java con un sacco di codice
semanticamente inutile è un altro discorso, eh.
Dopo di che il punto delle closures non è solo creare funzioni
'parametrizzate'. E' IMHO proprio un modo diverso di pensare e
strutturare il codice, che rende alle funzioni la loro dignità (assieme
al fatto di poterle comodamente manipolare).
-- 
cc = callcc {|cc| cc.call cc}; cc.call cc

> funzione parametrizzati.
c6> Sono due cose diverse: una chiusura la puoi avere anche senza
c6> manipolazione esplicita delle funzioni. Per dire il gcc offre come
c6> estensione le closures in C,
Offre  le nested function  che cessano  la loro  validità non  appena la
funzione creatrice esce e il suo stack frame diventa terra di nessuno...
c6> La manipolazione esplicita delle funzione può essere fatta
c6> ovviamente anche senza closures (basta che una funzione sia un
c6> cittadino di prima classe del linguaggio). Confesso che non mi
c6> vengono in mente linguaggi in cui ti passi in giro le funzioni
c6> comodamente senza closures.
Ci sono implementazioni  "old style" del LISP (credo  che Emacs Lisp sia
l'unica sopravvissuta) che non  avendo il lexical scoping non supportano
le closures ed  in compenso permettono di passarsi  allegramente in giro
le funzioni.
Quello  che perdi  è la  possibilità di  avere una  factory  di funzioni
ciascuna delle  quali ha  un comportamento leggermente  differente dalle
altre in virtù di un diverso contesto di creazione.
c6> Il fatto che tutto questo si possa fare in Java con un sacco di
c6> codice semanticamente inutile è un altro discorso, eh.
Non  è semanticamente  inutile (questa  è una  buzzword peggiore  de "IT
Solution  Architect" che  hanno  stampato sul  mio  biglietto da  visita
aziendale :) :) :)).
È che non riesci a fare una cosa che sia al 100% una closure e che la
devi fare con una sintassi che non ha la snellezza di quella, ad
esempio, del Common Lisp.
c6> Dopo di che il punto delle closures non è solo creare funzioni
c6> 'parametrizzate'. E' IMHO proprio un modo diverso di pensare e
c6> strutturare il codice, che rende alle funzioni la loro dignità
c6> (assieme al fatto di poterle comodamente manipolare).
Vero. Permette di estendere il linguaggio e non solo la sua libreria.


 (funcall add10 3)
13
In Java per ora un comportamento simile può solo essere emulato,
i.e. 
public class Adder {
    private final n; // una volta che lo inizializzi, non lo devi più 
                     // cambiare
    public Adder(n) { this.n = n; }
    public final add(x) { return x + n; } // qui il final è solo per
    efficenza
}
e poi avresti
  Adder add2 = new Adder(2);
  Adder add10 = new Adder(10);
Il risultato cui arrivi è il medesimo, hai solo una sintassi più verbosa
per  ottenere la  medesima  semantica (credo  che  crxor 666  intendesse
questo come "semanticamente inutile").
In  alternativa  potresti fare  una  funzione  statica  che accetta  due
parametri di ingresso, ma dovresti continuare "a far viaggiare" il 10 ed
il 2.
A me piace farlo con le closures :)


No, non portarmi quell'impalcatura traballante come esempio...
"Impalcatura traballante" ?

> No, non portarmi quell'impalcatura traballante come esempio...
AL> "Impalcatura traballante" ?
Il C++ è tutto fuorché un bel linguaggio coerente ed elegante.
E, AFAIK, per certi costrutti sei laciato in balia dell'implementatore.
Vero, nemmeno Java è al 100% portabile tra i vari vendor...


 Vero, nemmeno Java è al 100% portabile tra i vari vendor...
Scusa una domanda, ma secondo te quale sarebbe l'optimum ?  Nel corso della 
discussione, sento parlare di groovy, python, lisp etc... Ma nel mondo 
enterprise si tratta di linguaggi usati su vasta scala o restano di nicchia 
?
Scorpio. 

Il C++ è tutto fuorché un bel linguaggio coerente ed elegante.
A tuo parere (fai bene sempre ad aggiungerci un "secondo me" a queste
perle). A mio parere vale l'esatto contrario. Non ti chiedo qual è per
te un "linguaggio coerente ed elegante" in it.comp.java perché non è
mia intenzione avviare l'ennesima guerra di religione. Mi limito a
dire che c'è un'enorme differenza tra C++ e Java dal punto di vista
delle implementazioni: Java è sostanzialmente proprietario, mentre C++
è ratificato da un comitato standard ISO. L'espressione corretta non è
"in balia dell'implementatore", perché lascia supporre - erroneamente
- qualcosa di negativo; il C++ ha dei costrutti definiti a livello
generale, che ne garantiscono l'assoluta portabilità, e può essere
esteso (sottolineo "esteso") dagli implementatori.

 E, AFAIK, per certi costrutti sei laciato in balia dell'implementatore.
ad esempio?


Scusa una domanda, ma secondo te quale sarebbe l'optimum ?
Se accetti una mia risposta: non esiste l'optimum. In generale, perň,
in ambito professionale conviene conoscere almeno due o tre linguaggi.
Nel mondo "enterprise" (bel parolone altisonante) i linguaggi piů
usati sono Java e C++. Java per gli ambiti che ti sono stati giŕ
detti, C++ piů che altro per lo sviluppo di applicazioni server che
necessitino di alte performance o interfacciamenti di basso livello.
La fetta di torta di Python sta pian piano crescendo, ma il suo uso č
ancora limitatissimo. LISP viene usato in certi ambiti MOLTO
particolari, ma non č un linguaggio, per cosě dire, "di mercato".

 A me piace farlo con le closures :)
Gli esempi che mi hai fatto sono molto chiari, ma quello che mi 
interessava capire č quest'ultimo punto: con le closure (ok, al momento 
non sono implementate ma dovrebbero/potrebbero esserlo a breve e si 
trova gią documentazione disponibile) come diventerebbe il codice java 
che hai citato?
Sul resto non c'erano dubbi (lisp compreso ;) ), č riguardo a Java (che 
negli ultimi tempi ho un po' lasciato da parte) che ero curioso.
Grazie, ciao,
Paolo

"Andrea Laforgia" <a.laf...@andrealaforgia.it.invalid> ha scritto nel 
messaggio news:82qer395n2uhqd6lj...@4ax.com...

Premesso che, fino a poco tempo fa, consideravo C++ come *il* linguaggio,
vorrei spezzare una lancia a favore di Lauri... probabilmente con "in balia 
dell'implementatore",
voleva proprio sottolineare il fatto che delle estensioni al linguaggio (il 
termine corretto,
c'è poco da dire, è proprio "estensione") si è IMHO forse abusato. Basti 
pensare ai vari modi
in cui il concetto di "stringa" è stato implementato...
Scorpio

> Vero, nemmeno Java è al 100% portabile tra i vari vendor...
S> Scusa una domanda, ma secondo te quale sarebbe l'optimum ?  Nel corso
S> della discussione, sento parlare di groovy, python, lisp etc... Ma
S> nel mondo enterprise si tratta di linguaggi usati su vasta scala o
S> restano di nicchia ?
L'optimum a "cuore" ? Per me il LISP, ho avuto la fortuna che non mi è
stato rifilato a scuola quindi è scevro da brutti ricordi.
In ambito  enterprise sicuramente  per le applicazioni  Java - che  è un
buon linguaggio  e mi piace - la  fa da padrone, ma  probabilmente per i
motivi sbagliati,  cosa che gli  ha guadagnato l'ingiusto  soprannome di
Cobol del terzo millennio.
groovy lo usa come linguaggio di scripting, se non erro, Spagic mentre
Jython lo usa la console di amministrazione di WebSphere.
Non so come cambierà la testa di chi dirige, quando mi assunsero nel '98
Java era considerato una caccola, oggi forse produciamo più righe di
Java che di Cobol :) :) :) :) :) ed io praticamente non uso altro.


 particolari, ma non è un linguaggio, per così dire, "di mercato".
Il discorso IMHO è che uno dovrebbe utilizzare la tecnologia che gli serve, 
al posto giusto
e nel momento giusto. Frase assolutamente ovvia e scontata, ma purtroppo non 
sempre
è così scontata soprattutto nelle alte sfere. Fino a tre mesi fa, parlare di 
.NET nella mia
azienda era tabù. Ora, per ragioni di commessa, dovremo darci da fare tutti 
su quella piattaforma,
ma è abbastanza chiaro che .NET offre il meglio laddove occorra integrarsi 
con una certa piattaforma
(Windows), mentre J2EE sarebbe una scelta più "faticosa" in certi versi.
Aggiungo anche un'altra cosa a margine. Ho seguito la discussione che ho.... 
"originato", ma non l'ho capita
fino in fondo, e qualche domanda me la sono posta....da ingegnere tendo a 
valutare un sistema informatico
dal punto di vista di scalabilità, performance, correttezza e i linguaggi / 
tecnologie di sviluppo in termini
di facilità d'uso, integrabilità, velocità e sicurezza nello sviluppo.
Sinceramente la disquisizione sulla notazione polacca diretta o inversa mi è 
sembrata un po' off topic. Sembrerò un rude smanettone, ma a me la 
possibilità di usare (cum grano salis !!!) un delegate direttamente al posto 
di passare tramite interfacce e classi ad hoc significa in primis un bel 
risparmio di tempo: mi sarebbe piaciuto sentire pareri sul suo eventuale 
impatto sulle performance, sul rischio di abusarne, sul fatto che sia o meno 
un antipattern, etc.
Resta ovvio il fatto che ognuno è libero di postare ed esprimere il proprio 
parere, e che ben vengano anche discorsi un po' più "filosofici".
Mi chiedo però se la "purezza" di un linguaggio sia davvero un fattore di 
scelta ? C++ non è certo un esempio di purezza (puoi usare OOP o un 
approccio procedurale), ma quasi mai ne sento mettere in discussione la 
potenza espressiva, e questo è il motivo per cui, dopo tanti anni, è ancora 
in auge.

 wrote:
AL> Java è
AL> sostanzialmente proprietario,
Non è  affatto vero. E per  il fatto che  oramai ci sono belle  parti di
Java che sono libere, e per il  fatto che ci sono per lo meno due vendor
che peraltro rilasciano due ambienti non compatibili al 100%.
AL> mentre C++ è ratificato da un comitato
AL> standard ISO. L'espressione corretta non è "in balia
AL> dell'implementatore"
Quale è la semantica standard ISO per l'ereditarietà a diamante ?


 writes:
S> Basti pensare ai vari modi in cui il concetto di
S> "stringa" è stato implementato...
Un  mio amico  ex-Microsoft  mi  aveva un  giorno  raccontato di  quante
implementazioni delle stringhe aveva trovato in un singolo prodotto...


 Java che di Cobol :) :) :) :) :) ed io praticamente non uso altro.
Cambierà in funzione delle prospettive di guadagno, ne sono sicuro ! :-)
Scorpio. 

> dell'implementatore.
r> ad esempio?
Ereditarietà a diamante,  se nel frattempo non hanno  risolto la cosa (è
un sacco di tempo che fortunatamente  non uso il C++, preferisco il C di
gran lunga).


 implementazioni delle stringhe aveva trovato in un singolo prodotto...
...tant'è che il CTS di .NET cerca di sistemare questa faccenda dei tipi 
ridefiniti
n volte in modo diverso!
Scorpio 

 
Come javista qui ti dai la zappa sui piedi.
Se saliamo dal linguaggio all'ambiente in cui gira, troverai ad esempio 
almeno 3-4 framework per il logggin (!), 10 e passa front-end framework 
per applicazioni web, decine di ORM diversi, application server, ecc, 
ecc...il tutto ovviamente non sempre interoperabile.

 ha scritto nel messaggio 
news:NTVtj.247818$%k.37...@twister2.libero.it...

Non è IMHO la stessa cosa. In C++ ho la possibilità di scegliere tra 3, 4 
definizioni
di stringhe. In Java, no. Esiste un solo oggetto String.
I framework sono una cosa diversa: sono librerie di classi che svolgono un 
certo compito,
sviluppate da terze parti, ma il linguaggio, cioè Java, è il medesimo. Tu ed 
io potremmo metterci
insieme per sviluppare un sistema di persistenza e rilasciarlo, se avesse 
successo aumenteremmo il numero
di framework esistenti che risolvono lo stesso problema.
Quello che anch'io critico è il fatto che esistano più framework od API che 
hanno il "sapore dell'ufficialità",
o delllo standard, se preferisci. Per me, però, JPA è *lo* standard di 
persistenza, come pure gli EJB solo *lo* standard per scrivere oggetti 
distribuiti in Java e così via. Io ho scelto di  considerare... "canonici" i 
metodi e le tecnologie che Java propone, proprio per non perdermi nel mare 
dei framework, senza voler togliere nulla alla potenza degli stessi e alla 
capacità di chi li ha scritti.
Scorpio. 

 
Allora siccome in Java risolvi scegliendo lo standard ufficiale (JPA 
ecc), in C++ risolvi scegliendo l'implementazione standard del concetto 
stringa, contenuto nella stdlib.
Corretto? (di C++ non so molto)

 Vero. Permette di estendere il linguaggio e non solo la sua libreria.
Esatto.


 di stringhe. In Java, no. Esiste un solo oggetto String.
E in C++ esiste std::string. Quella č *la* scelta. 
Se vuoi usare stringhe 'wide' pure hai il tuo tipo, assolutamente
intercambiale con std::string. In effetti sono istanziazioni dello
stesso template.


 Corretto? (di C++ non so molto)
Nei contesti in cui posso, la risposta č "sě, senz'altro"... Ma per esempio 
vi sono situazioni in cui, dovendo usare librerie *fondamentali* come MFC o 
le API Windows pre-MFC,  non c'č molto da scegliere.
Scorpio 

 stesso template.
Vero, ma - come ho scritto in risposta a pippo - ci sono casi in cui devi 
usare MFC o le WinApi e non hai std::string, ma devi ricorrere a tipi come 
LPSTR o CString.... Certo, MFC non è C++ ANSI, ma Visual C++ è *il* C++ 
principe in ambito Windows per quanto ne so. E quindi con i "dettagli 
implementativi" di cui parlava Lauri ti devi confrontare, eccome. 

 gran lunga).
premesso conosco poco il C++, ma mi pare di ricordare delle regole per 
risolvere le ambiguità nell'ereditarietà multipla.
queste regole non sono standard?


 implementativi" di cui parlava Lauri ti devi confrontare, eccome. 
Guarda che anche sotto Windows vc++ ti offre tutta la stl e in
particolare std::string. Se non le usi, è un problema completamente tuo.
Al momento per quello che vedo i programmatori c++ usano std::string e
punto chiuso. 
Per *non* avere std::string, vuole dire che stai usando
un'implementazione di C++ fuori standard (cosa che non è quella
microsoft). 


> A me piace farlo con le closures :)
PX> Gli esempi che mi hai fatto sono molto chiari, ma quello che mi
PX> interessava capire è quest'ultimo punto: con le closure (ok, al
PX> momento non sono implementate ma dovrebbero/potrebbero esserlo a
PX> breve e si trova già documentazione disponibile) come diventerebbe
PX> il codice java che hai citato?
Non so come le implementeranno in Java, c'è comunque ECMAscript che
ci assomiglia ed offre
  // Return a function that approximates the derivative of f
  // using an interval of dx, which should be appropriately small.
  function derivative(f, dx) {
    return function(x) {
      return (f(x + dx) - f(x)) / dx;
    };
  }
In questo caso f è a sua volta un oggetto funzione.
Indubbiamente  la cosa  sarà, se  attuata,  un cambiamento  non da  poco
perché  le funzioni cesseranno  di essere  solo metodi  ma diventeranno,
come già detto da crxor 666, cittadini di prima classe del linguaggio.


 writes:
S> Il discorso IMHO è che uno dovrebbe utilizzare la tecnologia che gli
S> serve, al posto giusto e nel momento giusto.
Non capita spesso che venga seguito l'antico proverbio giapponese "per
l'uomo col martello ogni problema è un chiodo", purtroppo.
S> Sinceramente la disquisizione sulla notazione polacca diretta o
S> inversa mi è sembrata un po' off topic.
Il fatto che Java non permetta l'overload degli operatori è sempre stata
una  forte critica. Una  critica che  non ha  senso, il  discorso mirava
appunto a  questo originariamente, al  fatto che certe  affermazioni non
sono basate su una questione oggettiva, ma soggettiva.
S> ma a me la possibilità di usare (cum grano salis !!!) un delegate
S> direttamente al posto di passare tramite interfacce e classi ad hoc
S> significa in primis un bel risparmio di tempo:
Sicuramente in termini di scrittura del codice, ma non così tanto.
Se poi l'invocazione di un delegate costa quanto l'invocazione di 
un metodo final piuttosto che un generico metodo virtuale, o peggio,
di un metodo definito tramite interfaccia, tanto meglio.
S> rischio di abusarne, sul fatto che sia o meno un antipattern, etc.
Cambia il modo di pensare il codice. Java al momento è oggetto-centrico,
il codice va  pensato in quel modo. Introdurre  oggetti funzione, meglio
se con  le closure,  riapre la  porta ad un  modo di  programmare tipico
della  programmazione funzionale che  richiede un  certo riaddestramento
nel pensare.
Ma  la prima  cosa di  cui ti  parla Graham  nel suo  On Lisp  è  che il
linguaggio  è  estensibile  in   quanto  tu  puoi  "costruire  un  nuovo
linguaggio adatto  a risolvere  il problema", e  grazie al fatto  che le
funzioni sono cittadini di prima classe del linguaggio stesso.
É vero che i programmi  vanno progettati scendendo nel dettaglio, ma poi
vanno costruiti  dal basso facendo unit  test, in modo  da essere quanto
più  sicuri possibile di  quanto hai  già fatto  per costruire  sopra il
nuovo.
Che quando qualcosa non va ed il sistema è complesso... Apriti o cielo.


 queste regole non sono standard?
Tecnicamente non puoi riferirti proprio a quelle cose: in presenza di
ereditarietà a diamante non è lecito riferirsi a membri e funzioni
membro non statiche. 
Il problema comunque è risolto tramite ereditarietà virtuale se uno
persiste ad usare in maniera peculiare l'ereditarietà (in un linguaggio
dotato di template 'ricchi', sarebbe semplicemente mal progettata una
gerarchia che eredita tutta da un 'Object' a-la-java). Se questo
avviene, in sede di progetto si sceglie l'ereditarietà virtuale.


> C di gran lunga).
r> premesso conosco poco il C++, ma mi pare di ricordare delle regole
r> per risolvere le ambiguità nell'ereditarietà multipla.  queste regole
r> non sono standard?
Non pare proprio.
E'  il principale  motivo per  cui  Gosling non  ha messo  l'ereditaretà
multipla in  Java, e l'ereditarietà a  diamante non mi  pare chiaro come
viene  risolta,  in  quanto  gli  esempio  che  ho  visto  (Wikipedia  -
http://en.wikipedia.org/wiki/Virtual_inheritance
)  non  mi  pare  dicano
cosa  succede  se  nel diamante  eat()  di  Animal  è astratta  e  viene
ridefinita sian in WingedAnimal che in Mammal.


 Che quando qualcosa non va ed il sistema è complesso... Apriti o cielo.
Di solito non è il cielo ad aprirsi. <g>


 ridefinita sian in WingedAnimal che in Mammal.
Quel codice *non* ha akcun problema, visto e considerato che non vengono
chiamati membri non statici di Animal. Se fossero chiamati (esempio
aggiungendo bat.eat(); ) semplicemente non sarebbe codice valido: un
compilatore *dovrebbe* rifiutarlo.
% g++ multiple.cc 
multiple.cc: In function 'int main()':
multiple.cc:28: error: request for member 'eat' is ambiguous
multiple.cc:5: error: candidates are: virtual void Animal::eat()
multiple.cc:5: error:                 virtual void Animal::eat()
La soluzione (se uno pensa di fare cose del genere se ne dovrebbe
accorgere quando progetta la gerarchia di classi) è usare appunto
l'ereditarietà virtuale.
Aggiungo poi che il tipo che ha scritto l'articolo andrebbe preso a
calci in faccia; in primo luogo butta li codice non compilabile per
nessun buon motivo (è rilevante tirare a meno un tipo 'Color'?). Più
grave ancora il fatto che dichiari funzioni virtuali e *non* metta il
distruttore virtuale. 
Aggiungo infine che codice scritto in quella maniera sembra piuttosto
vecchio come concezione; tipicamente usando bene i templates, si può
progettare di meglio.


 nel pensare.
Ma non pensi che si "corra il rischio" di far entrare nella finestra 
l'approccio procedurale
che l'OOP ha, in un certo qual senso, buttato fuori dalla porta ? Un tale mi 
disse una volta
che in Java manca la possibilità di scrivere funzioni "libere" (ossia metodi 
senza classe). Mi è
sembrata una frase alquanto assurda visto il paradigma "tutto è oggetto" che 
sta alla base di Java.
Scorpio.

> richiede un certo riaddestramento nel pensare.
S> Ma non pensi che si "corra il rischio" di far entrare nella finestra
S> l'approccio procedurale che l'OOP ha, in un certo qual senso, buttato
S> fuori dalla porta ? Un tale mi disse una volta che in Java manca la
S> possibilità di scrivere funzioni "libere" (ossia metodi senza
S> classe). Mi è sembrata una frase alquanto assurda visto il paradigma
S> "tutto è oggetto" che sta alla base di Java.
Esiste anche l'approccio funzionale, in cui la funzione è non solo
codice da eseguire, ma anche un oggetto da far viaggiare.
Quello che molti si augurano da un'eventuale introduzione delle closures
è che  queste siano non solo più  comode da scrivere ma  che, ad esempio
non pesino come  una funzione invocata "attraverso il  contratto" di una
interfaccia.
