Newsgroup: it.comp.lang.c++
Titolo: strutturare le applicazioni (prosegue la discussione di "Re: Python")

[vedere il thread "Re: Python" per l'inizio ed il contesto di
quanto segue; ho dovuto spezzare il discorso in due, temo
per limiti di dimensione-post...].
Purtroppo, non esiste una implementazione completa, diffusa
ed efficiente di COM su piattaforme non-Windows (ci sono varie
implementazioni _parziali_, vedi ad esempio l'XCOM [di Mozilla,
su 
http://www.mozilla.org
], che e` un clone abbastanza stretto
di COM, ma ha varie mancanze, ben illustrate, in parte, su
http://www.iol.ie/~locka/mozilla/mozilla.htm
 nella sezione
"Why not just use native Gecko API calls?").  Una strategia che
sia simultaneamente per-componenti E language-independent
non e` dunque altrettanto agevolmente praticabile per lo
sviluppo di applicazioni destinate, ad esempio, a piattaforme
Unix (ovvero, applicazioni che debbano essere pienamente
portatili fra piattaforme Unix e Windows); in questi casi, la
scelta dei linguaggi diventa dunque "architetturale" (mentre
se ci si puo` limitare a Windows si riesce a mantenere maggiore
flessibilita`).  Esaminiamo dunque questo caso.
In certi casi particolari, bisogna considerare linguaggi "speciali"
di cruciale importanza per una data classe di applicazioni, come
Common LISP, Prolog, Haskell, o qualche incarnazione di ML (mi
dicono molto bene di ocaml, ma non l'ho ancora provato; si veda,
comunque, 
http://pauillac.inria.fr/ocaml/
); ovvero, il Fortran
(presumibilmente F90 e/o HPF in qualche guisa) per ragioni di
vettorializzazione e parallelizzazione.
In altri casi (applicazioni distribuite), puo` essere meglio scegliere
come nucleo architetturale un protocollo, appunto, di elaborazione
distribuita: probabilmente SOAP se si deve tenere conto delle realta`
di Internet, e soprattutto dell'esistenza dei firewall, ovvero IIOP
(quindi Corba, ILU, e/o DCOM con gli appositi "bridge") se ci si
puo` limitare ad una intranet (o extranet totalmente "tunneled")
e il coupling fra i componenti distribuiti deve essere maggiore di
quello scalabilmente supportabile da SOAP.
Nella maggior parte dei casi, queste esigenze speciali non si
pongono, o almeno possono essere "marginalizzate" senza che
si debba lasciar loro dettare l'impostazione architetturale
dell'applicazione (ad esempio, se le necessita` di elaborazione
vettoriale e/o parallela riguardano uno specifico insieme di
componenti, e ci si rivolge a una gamma di piattaforme dove
le specifiche implementazioni di F90/HPF permettono di usare
per questi componenti interfacce interoperabili con schemi piu`
generali).  In questi casi, la scelta architetturale dei linguaggi
si puo` ridurre a due strategie di fondo:
-- due linguaggi: un "linguaggio di sistema" per i componenti
    ad alte prestazioni o con necessita` di interazioni profonde
    con il sistema operativo, l'hardware, ecc; un "linguaggio ad
    alto livello" per la coordinazione generale delle operazioni
    (scripting), pilotaggio dell'interfaccia utente, e cosi` via;
-- tre linguaggi: un "linguaggio di nucleo" che consenta
    prestazioni comunque buone (ma forse sub-ottimali) con
    produttivita` maggiore di un vero "linguaggio di sistema",
    e come supplemento un "linguaggio di basso livello" per
    i casi relativamente rari di "qui dobbiamo andare proprio
    a tavoletta", e un "linguaggio ad alto livello" come nel
    caso precedente.
Classicamente, ad esempio, realizzare un'applicazione con
C e TCL e` grosso modo una strategia due-linguaggi, con
la possibilita` di divenire tre-linguaggi se l'ottimizzatore del
compilatore C usato e` cosi` scarso da richiedere l'uso
dell'assembler per certe operazioni cruciali (al giorno d'oggi,
esigenze del genere sono fortunatamente rarissime).
Oggi come oggi, secondo me, la migliore strategia a due
linguaggi e` quella composta da C++ come linguaggio di
sistema, e Python come linguaggio ad alto livello; la migliore
a tre linguaggi, invece, usa Java come linguaggio di nucleo,
C (con JNI) come linguaggio di basso livello, Python (nella
implementazione JPython, naturalmente) come linguaggio
di alto livello.
(Ho gia` illustrato in tanti altri post i trade-off fra C++ e
Java, la ragione per cui l'uno o l'altro di essi puo` essere
preferibile ad altri linguaggi -- meno portabili ovvero meno
potenti -- i vantaggi di Python rispetto ad altri linguaggi di
simile nicchia ecologia come Perl, Tcl, Scheme, Rexx, ecc).
Quanto alla scelta fra le due, dipende da quanta parte
dell'applicazione richieda effettivamente le prestazioni al
100% o l'accesso a bassissimi strati di sistema operativo
o di hardware.  Se queste necessita` riguardano parti
ragionevolmente piccole (e saranno casi frequenti), la
strategia a tre linguaggi e` probabilmente ottimale; se
le parti computazionalmente demanding, o "di sistema",
costituiscono invece una frazione molto rilevante della
applicazione, la strategia a due linguaggi puo` risultare
preferibile.
L'eccellente compatibilita` fra le implementazioni CPython
e JPython permette, fortunatamente, la totale comunanza
della scelta del linguaggio di alto livello fra queste due
strategie:-).
Alex

Colgo spunto da una discussione di Alex Martelli per fare una considerazione.
Ultimamente si è parlato molto in questo NG di strutturazione del codice, non
solo in termini del layout di indentazione, ma anche di altri aspetti più o meno
legati, come l'impatto di un lingguaggio piuttosto che un altro, oppure la
neccesità di ricompilazione dei moduli di un kernel anziché la distribuzione di
software per mezzo di DLL e le ripercussioni in termini di sicurezza e
robustezza che queste decisioni implicano.
L'aspetto decisivo e di fondo, come sempre, si  annida a livello architetturale.
Ma architettura di cosa? Del programma che uno sviluppa, si dirà. Su questo non
v'è alcun dubbio, per cui non mi soffermo neppure. Tuttavia, spesso si perde di
vista il _contensto globale_ in cui un'applicazione si va ad inserire. Un
esempio lo possiamo avere proprio dal paragone tra Linux/Unix ed NT. Che
ricompilare un kernel sia un compito alla portata di ogni buon utente unix e che
possa comportare dei vantaggi in determinate circostanze può essere accettabile,
ma non lo si faccia passare per una situazione ideale. Dal mio punto di vista è
una tecnica di integrazione del codice abbastanza rudimentale. E non mascheriamo
affatto le questioni di sicurezza e di robustezza con la ricompilazione:
centrano come i cavoli a merenda! (o, ridetto in altri termini, la robustezza
del sistema operativo non è il risultato della decisione di forzare la
ricompilazione del sistema).
Unix *non è stato pensato* in termini di interoperabilità così come lo è COM.
Volendo spingersi oltre, direi che non c'è nulla di simile a COM, da questo
punto di vista. COM è innanzitutto uno stile di organizzazione delle
applicazioni e più di ogni altro incoraggia il programmatore ad occuparsi
innanzitutto dell'interfaccia di un modulo (o componente). Si lavora molto in
fase di progettazione a quella che dovrebbe essere la parte più stabile
dell'oggetto. Sono pienamente d'accordo anche sull'uso di COM nell'ambito dello
sviluppo di software esplorativo, come accennava Alex. Ma vorrei spingermi oltre
e includerlo pure come seria alternativa architetturale per l'integrazione di
componenti. Avere la possibilità di scrivere un componente e integrarlo in un
sistema pre-esistente attraverso un binding dinamico, indipendentemente dal
linguaggio, è davvero una succosa possibilità. Non solo: cambiarne
l'implementazione (dopotutto, il sw si evolve!) per qualsivoglia ragione e non
essere costretti a ricompilare neppure i vecchi client, perché l'oggetto
continuerà a rispettare il "contratto" stipulato con loro ed _inoltre_
permetterà ai nuovi programmi di supportare le funzionalità aggiunte è _davvero_
un modo PULITO di progettare e scrivere codice.
Progettare in questo modo costituisce, sempre a mio parere, un modo meno
"bovino" di produrre software, sia da un punto di vista dell'architettura (dov'è
il riuso se sono costretto a portarmi dietro dei legami implementativi che mi
vincolano alla ricompilazione?), sia da quello della qualità. Ciò non toglie che
COM abbia i suoi limiti, però lo ritengo un passo in avanti sulla strada di
pensare e strutturare il software.
--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Andrea Baruzzo
Via Circonvallazione, 26
Muzzana del Turgnano (UD) - Italy
e-mail: 
andrea....@ud.nettuno.it
~~~~~~~~~~~~~~~~~~~~~~~~~~~~