Gabriele97's Blog

i linguaggi di programmazione

Ada, Algol, APL, Basic, C, Java, Cobol, Forth, Fortran, Lisp, Logo, Modula 2, Pascal, PL/I, Prolog, Smalltalk, Snobol,… Qual’è il linguaggio di programmazione migliore? Perché esistono tanti linguaggi? Non ne bastava uno solo? Queste sono tipiche domande che si pone chi si avvicina per la prima volta al mondo della programmazione. Al giorno d’oggi esistono centinaia, forse migliaia, di linguaggi di programmazione diversi e, anche se quelli veramente diffusi sono al più qualche decina (tutti gli altri vengono utilizzati solo in una ristretta cerchia di fans, come i linguaggi creati in centri di ricerca, linguaggi orientati ad applicazioni particolari, ecc.), sono più che abbastanza per confondere le idee al povero neofita. Sono tutti utili?
Da un punto di vista teorico si è dimostrato che tutti i linguaggi non banali sono, dal punto di vista della capacità computazionale, equivalenti. In pratica un programma scritto in un certo linguaggio può sempre essere codificato in qualsiasi altro linguaggio (ovviamente la valutazione della capacità computazionale non tiene conto dei molteplici accessori, spesso dipendenti dall’hardware, presenti nelle varie implementazioni dei linguaggi, come le istruzioni grafiche, i comandi per l’accesso agli interrupt, ecc.). Allora perché questa variopinta molteplicità di linguaggi? Il fatto è che esistono molti altri fattori da prendere in considerazione, oltre alla pura teorica possibilità di poter fare qualsiasi cosa con qualsiasi linguaggio. Il linguaggio deve essere non troppo difficile (è il massimo che si può sperare!) da imparare, deve essere possibile creare applicazioni in tempi ragionevoli, deve produrre eseguibili efficienti, ecc. Allora perché non creare un unico linguaggio che ottimizzi tutti questi fattori? Perché non creare un linguaggio universale? Malgrado vi siano stati sforzi in tal senso (ad esempio il PL/I) i risultati sono stati tutt’altro che soddisfacenti. In realtà è anche vero che alcuni linguaggi, soprattutto i più anziani, sono utilizzati solo per forza di inerzia, caso esemplare è, tanto per non fare nomi, il Fortran che è stato uno dei primi linguaggi di programmazione ed è ancora oggi diffusamente utilizzato per i calcoli matematici sia per l’enorme quantità di librerie già esistenti sia per l’attaccamento, quasi affettivo, dei suoi utilizzatori. D’altra parte anche i linguaggi naturali (italiano, inglese, ecc.), proprio per la stessa forza di inerzia, non vengono sostituiti tutti in blocco da un linguaggio molto più razionalizzato come potrebbe essere (ad esempio) l’esperanto, malgrado gli enormi vantaggi che ciò comporterebbe. Nel caso dei linguaggi di programmazione tale forza è, ovviamente, di gran lunga inferiore, però vi sono altri motivi, più oggettivi, per la sopravvivenza di questa Torre di Babele.
Il fatto è che ogni linguaggio risulta più o meno adatto a secondo del tipo di applicazione. Ad esempio il Lisp che è, molto meno efficiente del C, permette con estrema facilità di effettuare manipolazioni simboliche, per cui viene molto usato nel campo dell’Intelligenza Artificiale, soprattutto nella ricerca; il Basic permette di realizzare rapidamente piccoli programmi, mentre è del tutto inadeguato per applicazioni di una certa consistenza (almeno la versione originale, oggi ci sono in giro molti Basic Pascal like, come il Visual Basic, che, avendo adottato molte caratteristiche del Pascal, presentano una maggiore flessibilità). Quindi un linguaggio di programmazione va scelto a secondo dell’area applicativa (scientifico, gestionale, elaborazione testi, simulazioni, ecc.) e delle caratteristiche del problema da risolvere. Come diceva Carlo V “Parlo spagnolo a Dio, italiano alle donne, francese agli uomini e tedesco al mio cavallo”.
Quindi è importante comprendere bene quali sono le differenze tra i vari linguaggi, non tanto rispetto alle differenze di notazione o di terminologia, quanto rispetto alla filosofia e al modello computazionale che li contraddistingue e che ne determina la personalità. Nel seguito, dopo una breve introduzione generale effettueremo una classificazione di massima dei linguaggi di programmazione mentre in un prossimo articolo cercheremo di individuare quali sono le caratteristiche da tenere presenti per poter confrontare e quindi valutare un linguaggio di programmazione rispetto alle proprie necessità.

I linguaggi formali

Per chiarirci le idee vediamo brevemente quali sono le differenze tra i linguaggi formali e quelli naturali.
Quest’ultimi sono quelli che utilizziamo normalmente per comunicare tra noi esseri umani (“naturali” nel senso che non sono nati a tavolino, ma spontaneamente). Essi non sono rigorosamente definiti, sono in continua evoluzione e spesso presentano delle ambiguità; hanno però una enorme potenza espressiva. I linguaggi formali, invece, sono completamenti definiti mediante regole esplicite, per cui è sempre possibile determinare la correttezza (grammaticale) di una proposizione; inoltre il significato di ogni frase è sempre privo di ambiguità. Però hanno un potere espressivo limitato.
I linguaggi di programmazione sono un sottoinsieme di quelli formali. Essi possono essere definiti come il mezzo che ci permette di comunicare al computer la sequenza di operazione da effettuare per raggiungere un obiettivo prefissato.
Oltre ai linguaggi di programmazione vi sono anche altri linguaggi formali. Un esempio è la notazione scacchistica utilizzata per descrivere con precisione e senza ambiguità le partite del diffuso gioco di strategia. Un’altra disciplina in cui si fa largo uso dei linguaggi formali è la Logica Matematica, in cui vengono utilizzati per descrivere le teorie matematiche e i processi deduttivi in modo rigoroso. Si noti, per inciso, che i legami tra la Logica Matematica e l’Informatica stanno diventando sempre più stretti con una forte influenza reciproca. Tra l’altro due linguaggi popolari, il Lisp e il Prolog, sono scaturiti proprio da teorie studiate in Logica Matematica, e precisamente dal lambda calcolo di Church e dal calcolo dei predicati del primo ordine.

Linguaggi di basso ed alto livello

Non è possibile effettuare una rigida classificazione dei linguaggi di programmazione, ma nel seguito tenteremo comunque di individuare alcune categorie generali in cui si possono suddividere.
Una prima distinzione possiamo farla tra i linguaggi a basso e quelli ad alto livello. Ogni processore ha un proprio linguaggio che ad ogni stringa di bit fa corrispondere una operazione elementare come il caricamento di un registro interno al processore o la somma tra una cella di memoria e un registro. Questo tipo di linguaggio, detto linguaggio macchina, essendo molto vicino alla logica del processore, risulta essere molto lontano dal modo di ragionare dell’uomo, per cui utilizzarlo per la codifica di algoritmi comporta un lavoro molto lungo e difficile. Agli albori dell’informatica questo era l’unico modo di programmare un computer, per cui tale attività era riservata solo a tecnici super specializzati. Per alleviare queste difficoltà si pensò di creare dei linguaggi intermedi con cui scrivere i programmi. Un algoritmo codificato in questo modo non è più direttamente eseguibile dal processore, ma è necessario utilizzare un apposito programma traduttore che converte il programma originale (detto file sorgente) nelle corrispondenti istruzioni in linguaggio macchina (ottenendo così il file oggetto). Il primo di tali linguaggi fu il linguaggio Assembler, in cui al posto di ogni istruzione macchina viene usato un codice mnemonico ad esso associato. L’Assembler, pur permettendo una semplificazione del lavoro, costringe ancora a ragionare in un modo strettamente legato a quello del processore. Per cui in seguito si cercò di distaccarsi sempre più dalla logica dei processori arrivando così ai cosiddetti linguaggi ad alto livello orientati non più alla macchina ma alla soluzione di problemi.
Un’altro importante vantaggio dei linguaggi ad alto livello (e, storicamente, un’altra spinta al loro sviluppo) è il fatto di essere virtualmente indipendenti dal processore e dalla macchina particolare su cui si sviluppa. In questo modo è possibile utilizzare lo stesso sorgente su macchine diverse, ovvero come si dice in gergo informatico si ha una maggiore portabilità delle applicazioni (e dei programmatori che non sono costretti a imparare un nuovo linguaggio ogni volta che devono lavorare su una macchina diversa).
Al giorno d’oggi l’Assembler viene utilizzato solo in casi particolari: o quando è necessario molta efficienza (in quanto anche se i traduttori cercano di ottimizzare il codice macchina risultante, lavorare direttamente in Assembler di solito permette di avere un codice migliore) oppure quando si deve operare a livello macchina (ad esempio per interfacciarsi a delle schede hardware). Per cui normalmente un’applicazione viene scritta in gran parte in un linguaggio ad alto livello, mentre solo le parti più delicate vengono, eventualmente, codificate in Assembler.

Le categorie

La letteratura informatica normalmente suddivide i linguaggi ad alto livello in quattro categorie (imperativi, funzionali, dichiarativi ed orientati ad oggetto). Noi utilizzeremo una classificazione più ampia esaminando anche alcune categorie meno consuete. Sottolineiamo comunque che le classi considerate non sono mutuamente esclusive, per cui un linguaggio può appartenere anche a più di una categoria. Analizziamo ora le loro caratteristiche.
•    Imperativi: il programma è costituito da una sequenza di istruzioni il cui effetto è quello di modificare il contenuto della memoria dell’elaboratore o di determinare le modalità di esecuzione di altre istruzioni; in questo modello assume un ruolo fondamentale l’istruzione di assegnazione. Sono imperativi la maggior parte dei linguaggi più diffusi (Pascal, Basic, Fortran, C, Cobol, ecc.).
•    Funzionali: il programma è considerato come il calcolo del valore di una funzione; in un linguaggio funzionale puro l’assegnazione esplicita risulta addirittura completamente assente (si utilizza soltanto il passaggio dei parametri). In tale modello rivestono particolare importanza la ricorsione, in pratica l’utilizzo di funzioni che richiamano se stesse e, come struttura dati, la lista (sequenza ordinata di elementi). Il più importante rappresentante di questa categoria è senz’altro il Lisp (LISt Processing).
•    Dichiarativi (o logici): il programma è considerato come la dimostrazione della verità di una asserzione; il sorgente è costituito da una sequenza di asserzioni di fatti e regole. Non è necessario indicare esplicitamente il flusso di esecuzione, ma dato un obiettivo di partenza (il goal) è il sistema che cerca di individuare i fatti e le regole rilevanti. In tale ricerca assumono importanza meccanismi quali il pattern matching (in italiano potremo tradurre in combaciamento di forme) e il backtracking (in pratica se il sistema durante la ricerca entra in un vicolo cieco, ritorna alla scelta fatta più recentemente e prova ad applicare la regola o il fatto seguente).
    Il fatto che vi sia una netta separazione tra la parte dichiarativa (il cosa fare) e la parte procedurale (il come) rende un programma scritto in un linguaggio logico particolarmente leggibile.
    I linguaggi logici risultano particolarmente adatti a risolvere problemi che riguardano entità e le loro relazioni. Mentre nelle normali applicazioni risultano essere di difficile utilizzo, anche perché, ma non solo, comportano un modo di programmare completamente diverso dal solito.
    L’esemplare più noto di questa famiglia è il Prolog (PROgramming in LOGic).
•    Strutturati: man mano che l’ars programmandi si sviluppava si sono individuate delle metodologie appropriate. Le più importanti sono la programmazione strutturata e la programmazione ad oggetti. La programmazione strutturata è una tecnica il cui scopo è di semplificare la struttura dei programmi, limitando l’uso delle strutture di controllo a pochi casi semplici, tutti con un solo ingresso e una sola uscita. Tali metodologie sono state in seguito immerse in nuovi (e in già esistenti) linguaggi, dandone un esplicito supporto. Ad esempio per evitare l’uso indiscriminato del malefico GOTO (salto incondizionato) sono state introdotte istruzioni di controllo del flusso più strutturate come il WHILE, FOR e l’UNTIL.
    La maggior parte dei linguaggi oggi diffusi sono strutturati, anche se spesso permettono comunque l’uso di strutture di controllo non strutturate in quanto la pratica ha dimostrato che, anche se raramente, vi sono dei casi in cui, ad esempio, con un GOTO si ottiene una maggiore leggibilità del codice. Ciò avviene soprattutto nella gestione delle eccezioni (ad esempio nel trattamento delle situazione di errore).
•    Orientati ad oggetti: il programma è considerato l’effetto dell’interazione di un insieme di oggetti (insiemi di dati e algoritmi che manipolano questi dati) che comunicano con l’esterno mediante messaggi. Assumono rilevanza concetti quali incapsulamento, ereditarietà [si possono costruire oggetti che ereditano le caratteristiche di un’altro] e polimorfismo.
    Oltre a linguaggi specializzati che implementano i principi di tale metodologia (Smalltalk), sono nate delle estensioni dei linguaggi già esistenti, che li integrano (ad es. C++ per il C, CLOS per il Lisp).
•    Equazionali: il programma è considerato come la risoluzione di equazioni.
•    Paralleli: in tali linguaggi vi sono dei meccanismi espliciti per indicare compiti che possono essere effettuati in parallelo. Il più diffuso è senz’altro l’Occam.
•    Event driven: una delle cause della difficoltà di programmare in Windows è che si lavora in un ambiente event driven (orientato agli eventi) con linguaggi che non supportano direttamente tale paradigma. In un ambiente event driven non esiste più una sequenza determinata di comandi da eseguire ma una serie di reazioni che il sistema ha rispondendo a determinati stimoli esterni o interni.
    Questo è il segreto dell’enorme successo che ha riscosso il Visual Basic della Microsoft, permettendo di creare facilmente applicazioni sotto Windows, proprio perché supporta direttamente il flusso event driven.
•    Atipici: ad esempio, anche i fogli elettronici possono essere considerati linguaggi di programmazione in cui, in una certa misura, le relazioni temporali sono sostituite da relazioni spaziali (il valore di una cella dipende dal valore di altre).
•    Linguaggi visivi: in cui si utilizzano costrutti e grammatiche di tipo grafico o iconico.

9 commenti »

  1. The best information i have found exactly here. Keep going Thank you

    Commento di buy_vigrxplus — luglio 17, 2009 @ 2:45 am

  2. blog davvero molto bello, specialmente per le guide

    Commento di LnddMiles — luglio 24, 2009 @ 11:40 am

  3. questo è il blog più completo che ho mai visto

    Commento di buyvigrx — ottobre 5, 2009 @ 9:10 am

  4. Thank you for your help!

    Commento di vigrx — ottobre 23, 2009 @ 5:57 pm

  5. BRAVO

    Commento di MCBRIDE ONOFFBRIDE — novembre 18, 2011 @ 5:41 pm

  6. Sempre bravo,come al solito,non avevamo dubbi,ma ti vorrei,fare una richiesta,tu sai io uso ubuntu,non riesco a capire e a trovare sul web,come formattare una chiavetta in NTFS(file-sistem riconosciuto da linux e
    windows)sia da ubuntu che da windows,poi funzionerà,leggerò i file da entrambi,scusami,se ho qualche dubbio,ti dispiace,creare,una pagina al riguardo?peppino.

    Commento di Battagliese Giuseppe — aprile 8, 2012 @ 5:02 am

    • farò sicuramente una guida. comunque non ho mai provato, ma su Ubuntu c’è un programma già installato che gestisce le varie partizioni, solo che non ricordo come si chiama!

      Commento di Gabriele97 — aprile 8, 2012 @ 9:47 am

  7. Gabriele,grazie di cuore,se l’arcangelo gabriele con la spada di DIO squarcia le tenebre,tu come l’arcangelo squarci l’informatica,scusami , ma questo pensiero mi è venuto dal cuore.

    Commento di Battagliese Giuseppe — aprile 8, 2012 @ 8:09 pm

  8. Ciao Gabriele, grazie per le informazioni davvero complete ed espresse in modo chiaro ed esaustivo. Ho una domanda per te che sei un “addetto ai lavori”: hai sentito del nuovo linguaggio di programmazione Human Language Code? Dicono che smau punta tantissimo su questo. Qui qualche dettaglio http://niktorthenat.forumfree.it/?t=63244309 ma non so molto altro, se non il sito ufficiale che non è chiarissimo http://www.leonardo-hlc.it/. Bocche cucite ovviamente, a smau non manca moltissimo e presumo vorrranno fare il “grande lancio!”😀

    Commento di matteo — settembre 27, 2012 @ 12:00 pm


RSS feed for comments on this post. TrackBack URI

Lascia un commento

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...

Crea un sito o un blog gratuitamente presso WordPress.com.

%d blogger cliccano Mi Piace per questo: