Oggi, alla release 3.5 del .NET framework, assistiamo ad una evoluzione del linguaggio a dir poco sconvolgente! Lo dico in senso positivo da un certo punto di vista, in senso negativo da un altro:
Lati positivi dell'evoluzione del linguaggio C#
- Aggiunte features che permettono di modellare il software in maniera più flessibile, vedasi generics con constraints;
- Aggiunte features che semplificano la realizzazione di pattern comuni in maniera meno verbosa, vedasi iteratori e delegate.. anche se già dalla prima versione;
- Aggiunti strumenti per la cooperazione tra sviluppatori, vedasi classi e metodi parziali.
- Metodi estesi, non hanno ancora un corrispettivo nell'esperienza comune (pattern che li vedano come strumento da utilizzare realmente);
- Metodi partial: si tratta in fondo di metodi virtual non puri ma senza codice (solo più efficienti.. ma i compilatori d'oggi risolvono anche quel problema!);
- generics: ancora problemi con i vincoli, da aggiungere features in questo caso:
class Classe
where T: operator > {...}
5 commenti:
Diciamo che negli ultimo due o tre anni l'evoluzione di Java e C# li sta portando alla complessità che dovevano/volevano eliminare quando sono stati progettati.
La potenza semantica aumenta da un lato ed è estremamente positivo ma la complessità aumenta dall'altro... se va avanti così tanto meglio un ADA-- :)
C# (.NET), come tutti gli altri linguaggi, è uno strumento. Quello che lo strumento ti permette di fare è un conto, quello che tu decidi di fare con lo strumento è un altro. Credo che occorra sempre capire SE e COME sfruttare le nuove feature. Alcune forse è opportuno evitarle come la peste. Altre si possono sfruttare, in maniera intelligente. Si può programmare benissimo il ASP classico o malissimo il Java ;-)
Concordo, concordo pienamente sull'importanza relativa al come uno strumento venga utilizzato, non sono comunque convinto del fatto che questo renda corretta la scelta di inserire funzionalità non complete o non coerenti tra loro, ad esempio i generics in C# attualmente non permettono di imporre vincoli sugli operatori, questa è una feature "lasciata a metà"!
Vorrei aggiungere, tutte le funzionalità che non sporcano il linguaggio sono ben accette; ma se per essere aggiunte creano confusione, rendono "pericoloso" il loro utilizzo o rendono "sporca" la sintassi allora prima mi chiederei se servono veramente. Un esempio? Non credo che in Java serva la dynamic method invocation:
http://www.baptiste-wicht.com/2010/04/java-7-more-dynamics/
la reputo inutile e pericolosa, dove "inutile" significa che quello che si può fare con si può fare anche senza (tramite reflection), inoltre è "pericolosa" perché permette di creare in maniera più rapida e semplice codice bacato per mancanza di "pezzi".
Insomma C#, Java o chi che sia, a mio avviso lo strumento deve fittare le esigenze evitando di creare pericoli, in questo caso i pericoli riguardano la creazione di architetture SW non pulite e/o non estendibili, l'introduzione delle interfacce remava a favore, altre funzionalità remano contro. Ti piacerebbe avere un'auto con un tasto per l'autodistruzione? E' una funzionalità, non usarla se sei a bordo no? ;)
Assolutamente d'accordo.
Il mio commento (ero sempre io quello sopra) era un po' più generico e relativo al fatto che spesso si inorridisce (io per primo, nonostante sia molto "MS-oriented") di fronte a scelte architetturarli del linguaggio che, come rilevi, vanno un tantino contro alcuni principi/pattern/regole (...o buon senso) che ormai davamo per assodati. Se fosse un mondo perfetto, avremmo un linguaggio perfetto. Non è un mondo perfetto, abbiamo molte scelte ognuna con pro e contro. Il succo è che oggi (ma questa è la mia personale esperienza) in C# ci sono più pro che contro. Purtroppo ci sono anche i "pulsanti per l'autodistruzione". Non premiamoli e sfruttimo invece tutti i pro. E' una posizione chiaramente più pratica e meno filosofica, questo è palese ;-)
Non ho dubbi su questo, a livello pratico concordo, bisogna identificare ciò che ha senso usare e come va usato per trarre vantaggio massimo da qualunque strumento. A livello pratico, questo il modus operandi, a livello di sviluppo di linguaggi di programmazione, quindi per chi deve mettersi dietro le quinte e decidere le features del linguaggio, reputo errori (umani e non banali da comprendere a livello di design del linguaggio) gli inserimenti di features tipo "pulsante di autodistruzione". Ada è schiattato come linguaggio perché faceva troppo, non perché fosse poco potente. Le interfacce in Java hanno aggiunto a livello di design un boost tale da essere state poi scopiazzate (e migliorate) da molti altri linguaggi. L'overloading degli operatori del C++ non ha subito la stessa diffusione.. perché non aggiungono nulla ma rendono pericoloso il linguaggio, perché "a.concatenate(b)" è chiaro e "a + b" meno (nonostante in Java sporchevolmente si sia inserito questo caso particolare, viene sconsigliato da tutti per vari motivi). L'ereditarietà multipla è potente.. si ma non serve a nulla infatti la maggior parte dei linguaggi di nuova generazione non la permette. Se domani si svegliassero e decidessero di aggiungere l'ereditarietà multipla al C# (e nel CIL) farebbero una cazzata.. a mio avviso.
Posta un commento