Final PC

Linguaggio di programmazione ?

« Older   Newer »
  Share  
xfab1994
view post Posted on 18/1/2010, 16:50




In informatica, un linguaggio di programmazione è un linguaggio formale, dotato di un lessico, una sintassi e una semantica ben definite, utilizzabile per il controllo del comportamento di una macchina formale, o di una implementazione di essa (tipicamente, un computer).

Concetti base
Tutti i linguaggi di programmazione esistenti possiedono (almeno) questi due concetti chiave:

* Variabile: un dato o un insieme di dati, noti o ignoti, già memorizzati o da memorizzare; ad una variabile corrisponde sempre, da qualche parte, un certo numero (fisso o variabile) di locazioni di memoria che vengono allocate, cioè riservate, per contenere i dati stessi. Molti linguaggi inoltre attribuiscono alle variabili un tipo, con differenti proprietà (stringhe di testo, numeri, liste, atomi ecc.).
* Istruzione: un comando, una funzione, oppure una regola descrittiva: anche il concetto di istruzione è molto variabile fra i vari linguaggi. A prescindere dal particolare linguaggio però, ogni volta che un'istruzione viene eseguita, lo stato interno del calcolatore (che sia lo stato reale della macchina oppure un ambiente virtuale, teorico, creato dal linguaggio) cambia.

Alcuni concetti sono poi presenti nella gran parte dei linguaggi:

* Espressione: una combinazione di variabili e costanti, unite da operatori; le espressioni sono state introdotte inizialmente per rappresentare le espressioni matematiche, ma in seguito la loro funzionalità si è estesa. Una espressione viene valutata per produrre un valore, e la sua valutazione può produrre "effetti collaterali" sul sistema e/o sugli oggetti che vi partecipano.
* Strutture di controllo, che permettono di governare il flusso dell'esecuzione del programma, alterandolo in base al risultato di una espressione (che può ridursi al contenuto di una variabile, o essere anche molto complessa).
* Sottoprogramma: un blocco di codice che può essere richiamato da qualsiasi altro punto del programma.
* Strutture dati, meccanismi che permettono di organizzare e gestire dati complessi.


Il codice sorgente
Programmare in un dato linguaggio di programmazione significa generalmente scrivere uno o più semplici file di testo ASCII, chiamato codice sorgente. I font, i colori e in generale l'aspetto grafico sono irrilevanti ai fini della programmazione in sé: per questo i programmatori non usano programmi di videoscrittura ma degli editor di testo (come emacs e brief) che invece offrono funzioni avanzate di trattamento testi (espressioni regolari, sostituzioni condizionali e ricerche su file multipli, possibilità di richiamare strumenti esterni ecc). Se un dato editor è in grado di lavorare a stretto contatto con gli altri strumenti di lavoro (compilatore, linker, interprete ecc.: vedi più avanti) allora più che di semplice editor si parla di IDE o ambiente di sviluppo integrato. Va notato che alcuni linguaggi di programmazione recenti consentono anche una forma mista di programmazione, in cui alla stesura di codice sorgente ASCII si associano anche operazioni di programmazione visuale, attraverso le quali il programmatore descrive alcuni aspetti del programma disegnando a video attraverso il mouse; un'applicazione tipica di quest'ultima forma di programmazione è il disegno interattivo della GUI del programma (finestre, menù, e così via).
Compilazione e interpretazione

Il codice sorgente, contenente le istruzioni da eseguire e (spesso) alcuni dati noti e costanti, può essere poi eseguito passandolo ad un interprete che eseguirà le istruzioni in esso contenute, il che è la prassi normale per i linguaggi di scripting; oppure può venire compilato, cioè tradotto in istruzioni di linguaggio macchina da un programma compilatore: il risultato è un file binario 'eseguibile' (codice eseguibile) che non ha bisogno di altri programmi per andare in esecuzione, ed è anche molto più veloce di un programma interpretato.

In passato, la compilazione è stata la norma per tutti i linguaggi di programmazione di uso generale; attualmente vi sono numerosi linguaggi interpretati e di uso generale, come il linguaggio Java o quelli della piattaforma .NET, che applicano un approccio ibrido fra le due soluzioni, utilizzando un compilatore per produrre del codice in un linguaggio intermedio (detto bytecode) che viene successivamente interpretato. La differenza di prestazioni tra i linguaggi interpretati e quelli compilati è stata ridotta con tecniche di compilazione just-in-time, sebbene si continui ad utilizzare i linguaggi compilati (se non addirittura l'assembly) per le applicazioni che richiedono le massime prestazioni possibili.
La compilazione

La compilazione è il processo per cui il programma, scritto in un linguaggio di programmazione ad alto livello, viene tradotto in un codice eseguibile per mezzo di un altro programma detto appunto compilatore.

La compilazione offre numerosi vantaggi, primo fra tutti il fatto di ottenere eseguibili velocissimi nella fase di run (esecuzione) adattando vari parametri di questa fase all'hardware a disposizione; ma ha lo svantaggio principale nel fatto che è necessario compilare un eseguibile diverso per ogni sistema operativo o hardware sul quale si desidera rendere disponibile l'esecuzione.
Il collegamento (linking)
Exquisite-kfind.png Per approfondire, vedi la voce Linking.

Se il programma, come spesso accade, usa delle librerie, o è composto da più moduli software, questi devono essere 'collegati' tra loro. Lo strumento che effettua questa operazione è detto appunto linker ("collegatore"), e si occupa principalmente di risolvere le interconnessioni tra i diversi moduli.

Esistono principalmente due tipi differenti di collegamento: dinamico e statico.
Collegamento statico

Tutti i moduli del programma e le librerie utilizzate vengono incluse nell'eseguibile, che risulta grande, ma contiene tutto quanto necessario per la sua esecuzione. Se si rende necessaria una modifica ad una delle librerie, per correggere un errore o un problema di sicurezza, tutti i programmi che le usano con collegamento statico devono essere ricollegati con le nuove versioni delle librerie.
Collegamento dinamico

Le librerie utilizzate sono caricate dal sistema operativo quando necessario (linking dinamico; le librerie esterne sono chiamate "DLL", Dynamic-link libraries nei sistemi Microsoft Windows, mentre "SO" Shared Object nei sistemi Unix-like). L'eseguibile risultante è più compatto, ma dipende dalla presenza delle librerie utilizzate nel sistema operativo per poter essere eseguito.

In questo modo, le librerie possono essere aggiornate una sola volta a livello di sistema operativo, senza necessità di ricollegare i programmi. Diventa anche possibile usare diverse versioni della stessa libreria, o usare librerie personalizzate con caratteristiche specifiche per il particolare host.

Nella realizzazione di un progetto software complesso, può succedere che alcune parti del programma vengano realizzate come librerie, per comodità di manutenzione o per poterle usare in diversi programmi che fanno parte dello stesso progetto.

La complicazione aggiunta è che quando si installa un programma con collegamento dinamico è necessario verificare la presenza delle librerie che utilizza, ed eventualmente installare anche queste. I sistemi di package management, che si occupano di installare i programmi su un sistema operativo, di solito tengono traccia automaticamente di queste dipendenze.

In genere si preferisce il collegamento dinamico, in modo da creare programmi piccoli e in generale ridurre la memoria RAM occupata, assumendo che le librerie necessarie siano già presenti nel sistema, o talvolta distribuendole insieme al programma.
L'interpretazione
Un codice python

Per cercare di eliminare il problema della portabilità (la dipendenza o meno del linguaggio dalla piattaforma) si è tentato di creare altri linguaggi che si potessero basare soltanto su librerie compilate (componenti) ad hoc per ogni piattaforma, mentre il loro codice viene interpretato, e quindi non c'è la necessità di una compilazione su ogni tipologia di macchina su cui viene eseguito.[senza fonte] Il grosso difetto di questi linguaggi è la lentezza dell'esecuzione; però hanno il grosso pregio di permettere di usare lo stesso programma senza modifica su più piattaforme. Si dice in questo caso che il programma è portabile.

La perdita di prestazioni che è alla base dei linguaggi interpretati è il doppio lavoro che è affidato alla macchina che si accinge ad elaborare tale programma. Al contrario di un programma compilato, infatti, ogni istruzione viene controllata e interpretata ad ogni esecuzione da un interprete.

Si usano linguaggi interpretati nella fase di messa a punto di un programma per evitare di effettuare numerose compilazioni o invece quando si vuole creare software che svolgono operazioni non critiche che non necessitano di ottimizzazioni riguardanti velocità o dimensioni, ma che traggono più vantaggio dalla portabilità. I linguaggi di scripting e tutti quelli orientati al Web sono quasi sempre interpretati. PHP, Perl, Tcl/Tk, Java volendo, e JavaScript, Python e molti altri sono esempi concreti di interazione non vincolata alla piattaforma.

Ci sono vari tentativi per rendere i compilatori multipiattaforma creando un livello intermedio, una sorta di semi-interpretazione, come nel caso sopra menzionato di Java; d'altro canto per i linguaggi interpretati ci sono tentativi per generare delle compilazioni (o semi-compilazioni) automatiche specifiche per la macchina su cui sono eseguiti.

Esistono anche strumenti per automatizzare per quanto possibile la compilazione di uno stesso programma su diverse piattaforme, ad esempio GNU autoconf/automake, che permette di realizzare una distribuzione del codice sorgente che può essere configurata e compilata automaticamente su diverse piattaforme, in genere almeno tutti gli Unix.
Confronto tra compilazione e interpretazione
Un esempio di codice sorgente in Python. L'evidenziazione di alcune parti di codice è uno strumento comune fra i programmatori per orientarsi fra il codice.

Questi due metodi di creazione ed esecuzione di un programma presentano entrambi vantaggi e svantaggi: il maggior vantaggio della compilazione è senz'altro l'efficienza nettamente superiore in termini di prestazioni, al prezzo del restare vincolati ad una piattaforma (combinazione di architettura hardware e sistema operativo) particolare; un linguaggio interpretato invece non ha, in linea di massima, questa dipendenza ma è più lento e richiede più memoria in fase di esecuzione.
Il Caso reale e la macchina intermedia
Le implementazioni compilative pure o interpretative pure sono in realtà solo gli estremi di una soluzione implementativa di un linguaggio di programmazione, infatti in quasi tutti i linguaggi di programmazione coesistono queste due tecniche, in modo tale da limitarne gli svantaggi e sfruttarne i vantaggi. Quindi in un caso reale i passaggio sono i seguenti: il codice sorgente viene prima compilato in un codice intermedio e poi interpretato. C'è da aggiungere che l'interprete utilizzato sfrutta un supporto run-time che in pratica consente di adattarlo alle esigenze implementative, in pratica può accadere che non è necessario realizzare interamente l'interprete, in quanto il linguaggio intermedio generato dalla compilazione non è molto diverso dal linguaggio finale (quindi la macchina intermedia e simile alla macchina ospite), basta quindi l'interprete della macchina ospite, esteso da opportuni programmi detti, appunto, supporto a run-time. Inoltre esistono vari meccanismi che tendono ad ottimizzare il codice prima della compilazione stessa, allo scopo di migliorarne l'efficienza. La Valutazione parziale è una di queste tecniche e consiste nel valutare un programma del quale sia nota una parte degli input. Conoscendo questa informazione si tende a specializzare tale programma in modo tale da risultare più efficiente con quegli input, ottenendo come risultato un programma più efficiente di quello originale.

fonte wikipedia
 
Top
0 replies since 18/1/2010, 16:50   164 views
  Share