{"id":78,"date":"2001-12-11T00:00:00","date_gmt":"2001-12-10T23:00:00","guid":{"rendered":""},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T22:00:00","slug":"78","status":"publish","type":"post","link":"https:\/\/www.vialattea.net\/content\/78\/","title":{"rendered":"Vorrei sapere a quale generazione di linguaggi un linguaggio di programmazione ad oggetti appartiene e in base a che criterio si pu\u00f2 fare questa catalogazione.\r\nIn particolare Java, C++, Visual Basic, JavaScript in quale generazione di linguaggi sono inseriti."},"content":{"rendered":"<p><font size=\"2\" face=\"Verdana, Arial, Helvetica, sans-serif\">La<br \/>\ndomanda \u00e8 interessante, e merita una attenta analisi storica dell&#8217;evoluzione<br \/>\ndei linguaggi di programmazione.<br \/>\nAgli inizi i calcolatori erano molto costosi, giganteschi e tremendamente limitati.<br \/>\nNon esistevano monitor, ne vere tastiere, la quantit\u00e0 di memoria per i<br \/>\nprogrammi e i loro dati era limitata a pochissimi kb. Ma anche quei dinosauri<br \/>\ndovevano essere programmati per fare qualcosa di utile, per cui gli scienziati<br \/>\ndell&#8217;epoca erano costretti a scrivere degli algoritmi in pseudo linguaggi, su<br \/>\ncarta che poi manualmente traducevano in istruzioni sempre pi\u00f9 semplici,<br \/>\nfino a raggiungere il livello delle istruzioni comprese direttamente dal microprocessore.<br \/>\nIn altre parole si programmava in quello che viene definito linguaggio macchina,<br \/>\ne che si pu\u00f2 senz&#8217;altro definire la prima generazione di linguaggi, molto<br \/>\nvariabili soprattutto perch\u00e9 dipendenti dalla macchina sottostante, nella<br \/>\ncompleta assenza di qualsiasi sistema operativo, in cui le istruzioni venivano<br \/>\nscritte direttamente in codici binari.<br \/>\nSuccessivamente si cerc\u00f2 di semplificare la programmazione, creando un<br \/>\nlinguaggio che introducesse, un maggiore livello di astrazione, permettendo l&#8217;uso<br \/>\ndi simboli al posto dei codici binari. Cos\u00ec nacquero i primi linguaggi<br \/>\nassembler, ancora molto rozzi, ma sicuramente pi\u00f9 semplici da usare per<br \/>\nla definizione di algoritmi, i codici delle istruzioni diventarono delle abbreviazioni<br \/>\ntestuali pi\u00f9 facili da leggere e ricordare, e le variabili acquistarono<br \/>\ndei nomi pi\u00f9 significativi, rispetto ai loro semplici indirizzi in memoria.<br \/>\nCon l&#8217;evoluzione dei sistemi, aumentarono le potenze di calcolo e le dimensioni<br \/>\ndella memoria. Inoltre iniziarono a comparire i primi dispositivi di registrazione<br \/>\ndi massa dei dati (dischi e nastri magnetici, ecc.). Di pari passo le mire dei<br \/>\nricercatori, crebbero e la necessit\u00e0 di scrivere algoritmi pi\u00f9 complessi<br \/>\ne potenti, nonch\u00e9 il bisogno di riutilizzare il codice gi\u00e0 scritto<br \/>\no condividere con altri il proprio codice, si rese pi\u00f9 importate.<br \/>\nA questo scopo vennero pensati dei linguaggi ancora pi\u00f9 astratti che ignorassero<br \/>\ndel tutto le istruzioni comprese dal processore, assumendo che alcune operazioni<br \/>\ndi base fossero disponibili ovunque o che se non altro si potessero implementare<br \/>\ncon quelle esistenti. In questo processo di astrazione tutte le variabili non<br \/>\nfurono pi\u00f9 visibili come semplici indirizzi di memoria, ma solo con i loro<br \/>\nnomi simbolici, e furono introdotti i primi concetti di codice strutturato per<br \/>\nil controllo del flusso di esecuzione delle istruzioni. I pi\u00f9 linguaggi<br \/>\nconosciuti di questo tipo sono il BASIC e il FORTRAN, in cui vediamo per la prima<br \/>\nvolta la possibilit\u00e0 di definire dei blocchi di codice che possiamo eseguire<br \/>\nripetutamente in base a condizioni definibili in modo decisamente evoluto, tramite<br \/>\nespressioni di controllo molto simili a funzioni matematiche. Queste espressioni<br \/>\npossono essere usate per decidere se eseguire un blocco di codice o no. Ma soprattutto<br \/>\nmettono in pratica uno dei primi teoremi della computer science, quello di <a target=\"_blank\" href=\"http:\/\/www.melograno.net\/talpanet\/toolbox\/pro\/ord\/jb.html\">B\u00f6hm-Jacopini<\/a>.<br \/>\nParallelamente a questi linguaggi definiti imperativi, perch\u00e9 contengono<br \/>\nsolo comandi ben precisi da eseguire in un certo ordine, nasce un&#8217;altra classe<br \/>\ndi linguaggi detti logici, in cui non esistono procedure rigide, ma solo un elenco<br \/>\ndi regole di cui non si pu\u00f2 stabilire a priori l&#8217;ordine di applicazione.<br \/>\nUno di questi linguaggi \u00e8 il Prolog, e rappresenta una vera rivoluzione<br \/>\ndel modo di pensare l&#8217;elaborazione automatica dei dati. In un programma Prolog,<br \/>\nsi definiscono tutte le regole applicabili nelle diverse situazioni che si possono<br \/>\nincontrare in un problema. Ognuna delle quali per essere applicata deve soddisfare<br \/>\nun elenco di condizioni organizzate con operatori logici (or, and, not, xor),<br \/>\ne alla cui applicazione pu\u00f2 corrispondere un cambiamento del problema di<br \/>\npartenza, che quindi si trasforma fino a raggiungere uno stato che possiamo definire<br \/>\nsoluzione.<br \/>\nNonostante queste sue caratteristiche sia il Prolog che i linguaggi della sua<br \/>\nclasse non ebbero un grande successo, per il motivo fondamentale che la maggior<br \/>\nparte dei problemi reali, come il controllo di processi industriali o l&#8217;archiviazione<br \/>\ndi dati \u00e8 gestibile in modo pi\u00f9 semplice e sicuro con linguaggi<br \/>\nimperativi.<br \/>\nI linguaggi logici fondamentalmente furono pensati per esplorare le capacit\u00e0<br \/>\ndi pensiero artificiale, e infatti furono e sono tuttora strumenti di nicchia<br \/>\nin intelligenza artificiale.<br \/>\nTornando ai linguaggi imperativi, BASIC, Fortran e simili, permisero senza dubbio<br \/>\nun passo avanti considerevole, ma soffrivano ancora di una primitiva strutturazione<br \/>\ne spingevano all&#8217;uso di un&#8217;istruzione che rendeva poco chiaro il codice e che<br \/>\nfece coniare il termine di programmazione spaghetti per via delle imprevedibili<br \/>\ndiramazioni del flusso di esecuzione. Quest&#8217;istruzione \u00e8 il GOTO, tradotto<br \/>\nletteralmente in &#8220;vai a&#8221;, ossia un salto incondizionato ad una certa<br \/>\nistruzione. I programmi che pi\u00f9 soffrivano di questa &#8220;malattia&#8221;<br \/>\nerano quelli scritti in BASIC, ma anche gli altri non ne erano immuni.<br \/>\nPer limitarne l&#8217;uso furono introdotti linguaggi sempre pi\u00f9 strutturati,<br \/>\ncome il Pascal, molto usato nella didattica, in cui rispetto ai primi BASIC, c&#8217;\u00e8<br \/>\nl&#8217;introduzione delle funzioni e procedure che permettono agevolmente di evitare<br \/>\nl&#8217;uso del GOTO, presente anche in Pascal, ma con una piccola modifica che ne permette<br \/>\nun uso pi\u00f9 disciplinato, ossia la necessit\u00e0 di definire un punto<br \/>\ndi arrivo del salto, le label(ricordo che in basic si specificava solo il numero<br \/>\ndi riga e se per qualche motivo si aggiungeva o si cancellava del codice i salti<br \/>\na numero di riga diventavano imprevedibili, portando il flusso di esecuzione in<br \/>\npunti del tutto sbagliati).<br \/>\nNonostante tutti questi sforzi per strutturare e astrarre i linguaggi di programmazione,<br \/>\nrimaneva sempre la necessit\u00e0 di poter controllare l&#8217;hardware sottostante<br \/>\nsenza limiti per sfruttarlo al meglio, ma di certo non era opportuno tornare all&#8217;assembler<br \/>\ne rinunciare ai benefici della programmazione strutturata. Per risolvere questi<br \/>\nproblemi fu inventato un linguaggio a met\u00e0 strada, ancora frequentemente<br \/>\nusato in molti tipi di applicazioni, sto parlando del C.<br \/>\nIl C nelle sue prime versioni forniva tutto quello che ci si aspettava per una<br \/>\nprogrammazione strutturata, e quindi cicli, espressioni di controllo, esecuzione<br \/>\ncondizionata di blocchi di codice, funzioni, strutture dati (presenti anche in<br \/>\npascal) ossia la possibilit\u00e0 di dare un nome ad un gruppo di variabili<br \/>\ne gestirle come oggetti compatti. Ma nonostante questo manteneva un profondo legame<br \/>\ncon l&#8217;assembler, comprendendo funzioni a bassissimo livello come lo shift dei<br \/>\nbit di una variabile, o la possibilit\u00e0 di indicare al compilatore che una<br \/>\nvariabile sarebbe stato opportuno non fosse allocata in memoria, ma fosse direttamente<br \/>\nun registro del processore. Purtroppo soffriva di una quasi totale assenza di<br \/>\ncontrollo dei tipi delle variabili, in altre parole si poteva tranquillamente<br \/>\nassegnare ad un intero il valore di una stringa, senza che venisse generato neanche<br \/>\nun messaggio di avvertimento per l&#8217;assegnazione ad una variabile di un tipo il<br \/>\nvalore di un&#8217;altra di tipo del tutto differente.<br \/>\nDopo questa generazione di linguaggi strutturati, i progetti da sviluppare nella<br \/>\nvita reale divennero sempre pi\u00f9 complessi e di grandi dimensioni, di pari<br \/>\npasso all&#8217;evoluzione delle macchine. Cos\u00ec cominci\u00f2 a farsi strada<br \/>\nun&#8217;altra rivoluzione, che porta il nome di programmazione ad oggetti.<br \/>\nL&#8217;idea di base \u00e8 che tutti i programmi non fanno altro che definire gruppi<br \/>\ndi funzioni che manipolano pacchetti di dati spesso strutturati a pi\u00f9 livelli,<br \/>\nossia strutture che contengono altre strutture e cos\u00ec via. Cos\u00ec<br \/>\nsi cominci\u00f2 a pensare che non aveva senso separare le strutture dati dalle<br \/>\nfunzioni che le manipolano, \u00e8 cos\u00ec nacque il concetto di oggetto<br \/>\nnel software.<br \/>\nUn oggetto definiva i suoi dati e tutte le funzioni che erano state progettate<br \/>\nper la loro gestione. Il tutto in un blocco unico, al punto tale che le funzioni<br \/>\nera come se non esistessero senza la creazione dell&#8217;oggetto a cui appartenevano.<br \/>\nInoltre sia le variabili che le funzioni potevano essere pubbliche o private,<br \/>\ncio\u00e8 visibili e utilizzabili dall&#8217;esterno o no, introducendo il concetto<br \/>\ndi information hiding. La rivoluzione non finisce qui, infatti ci si rese conto<br \/>\nanche, che molto spesso si utilizzavano oggetti simili in diversi progetti, ma<br \/>\nanche in uno stesso progetto. Per cui si pens\u00f2 alla possibilit\u00e0<br \/>\ndi definire oggetti che derivavano da altri, a cui aggiungevano capacit\u00e0<br \/>\n(funzioni), dati o semplicemente ridefinendone alcune funzioni. Con queste caratteristiche<br \/>\nfurono introdotti altri due concetti fondamentali della programmazione ad oggetti:<br \/>\nl&#8217;ereditariet\u00e0 e il polimorfismo.<br \/>\nForse il primo linguaggio che introdusse la vera programmazione ad oggetti fu<br \/>\nlo SmallTalk, successivamente fu esteso il linguaggio C, dando origine al C++<br \/>\nche in realt\u00e0 non sposa completamente la filosofia ad oggetti, permettendo<br \/>\nla definizione di elementi non appartenenti a nessun oggetto, cosa che lo rende<br \/>\nun poco pulito da questo punto di vista.<br \/>\nSuccessivamente nacquero linguaggi come Java, che in questo processo di astrazione<br \/>\naggiunge un ulteriore elemento.<br \/>\nDal punto di vista della sintassi \u00e8 praticamente identico al C++, semanticamente<br \/>\nha alcune differenze da tenere ben presenti per un suo corretto uso. Per prima<br \/>\ncosa in Java si tagliano completamente i ponti con l&#8217;hardware, croce e delizia<br \/>\ndel C++, e si astrae la macchina definendo un processore virtuale o per meglio<br \/>\ndire una macchina virtuale. Per fare una cosa del genere si introdusse un software<br \/>\n(necessario per far girare le applicazioni scritte in Java), che si comportava<br \/>\ncome una semplice processore hardware.<br \/>\nIn poche parole un programma viene compilato in linguaggio macchina, ma non per<br \/>\nla macchina dove si sta lavorando, ma per la macchina virtuale, questo linguaggio<br \/>\nmacchina \u00e8 molto simile a quello vero, per cui la sua esecuzione \u00e8<br \/>\nmolto veloce, essendoci una corrispondenza di quasi 1:1 (ovviamente il rapporto<br \/>\nvaria da piattaforma a piattaforma, o per meglio dire dalla complessit\u00e0<br \/>\ndel processore reale). Anche in questo modo, il fatto che ci sia un interprete<br \/>\ndelle istruzioni purtroppo ne limita le performance, ma in compenso permette una<br \/>\nsicurezza totale (se la macchina virtuale \u00e8 stata implementata correttamente),<br \/>\ne una completa indipendenza dalla macchina che comunque deve avere delle caratteristiche<br \/>\nminime, scelte in modo da abbracciare la quasi totalit\u00e0 delle macchine<br \/>\nmoderne.<br \/>\nJava a parte la sintassi molto simile al C++, porta con se delle notevoli innovazioni<br \/>\nper rendere pi\u00f9 difficile commettere errori e aumentare conseguentemente<br \/>\nla produttivit\u00e0. Per prima cosa non \u00e8 pi\u00f9 possibile vedere<br \/>\nindirizzi di memoria, tutte le variabili fanno riferimento a oggetti, ma non \u00e8<br \/>\npossibile leggerne l&#8217;indirizzo, ne spostarlo di un numero di byte a piacere. L&#8217;unica<br \/>\noperazione ammessa con le variabili(riferimenti a locazioni di memoria) \u00e8<br \/>\nla copia da una a l&#8217;altra o la cancellazione del riferimento impostandolo a null.<br \/>\nQuesto impedisce ai programmi di accedere a qualsiasi locazione di memoria, eliminando<br \/>\nla possibilit\u00e0 di provocare grossi danni al sistema. Inoltre la gestione<br \/>\ndegli errori \u00e8 completamente affidata alle eccezioni, e infine sono previsti<br \/>\nmeccanismi di sincronizzazione per i thread direttamente nel linguaggio.<br \/>\nPer finire la deallocazione della memoria \u00e8 gestita automaticamente, con<br \/>\nun processo chiamato Garbage Collector che solleva il programmatore dalla gestione<br \/>\ndella distruzione degli oggetti.<br \/>\nLa critica maggiore che si pu\u00f2 fare a Java, \u00e8 che ha spinto l&#8217;astrazione<br \/>\na livelli eccessivi a scapito della efficienza del codice, ma d&#8217;altro canto grazie<br \/>\na questo, e ai limiti nell&#8217;accesso alla macchina, permette di evitare molti errori<br \/>\ne aumenta notevolmente la produttivit\u00e0 dei programmatori, e nello stesso<br \/>\ntempo permette la creazione di applicazioni molto robuste.<br \/>\nParallelamente a questi linguaggi si posizionano gli script, come il Visual Basic<br \/>\nScript, Java Script, ecc. che in realt\u00e0 non definirei dei veri e propri<br \/>\nlinguaggi. Infatti non permettono la definizione di vere applicazioni, ma semplicemente<br \/>\ndi definire dei comportamenti particolari in software che li comprendono, come<br \/>\ni browser internet e quindi sono molto dipendenti dalla versione di questi ultimi.<br \/>\nComunque la loro utilit\u00e0 \u00e8 indubbia, infatti spesso non si ha bisogno<br \/>\ndi una vera applicazione, ma semplicemente di effettuare delle piccole procedure<br \/>\nin programmi particolari, e uno script \u00e8 di sicuro una buona soluzione,<br \/>\nse non l&#8217;unica.<br \/>\nDi linguaggi script, come \u00e8 facile immaginare, ne esistono infiniti, \u00e8<br \/>\nspesso le applicazioni professionali ne supportano uno, vedi lo scripting dei<br \/>\nprogrammi di grafica come 3D Studio, 3D Studio MAX, AutoCAD, Maya, ecc. Ognuno<br \/>\ndi questi programmi permette la definizione di procedure per gestire animazioni<br \/>\no creare superfici e curve irrealizzabili a mano con la precisione necessaria.<br \/>\nInfine esistono i meta linguaggi, usati in tools per la creazione di interpreti<br \/>\no compilatori, come Flex\/Bison o ANTLR, con cui si definiscono regole grammaticali,<br \/>\ncon procedure da eseguire quando vengono applicate, che non si possono definire<br \/>\nscript in quanto, con questi meta linguaggi vengono generati i sorgenti di vere<br \/>\ne proprie applicazioni che comprendono altri linguaggi (interpreti). Ma la cosa<br \/>\nche li rende particolarmente interessanti \u00e8 che in realt\u00e0 generano<br \/>\ni sorgenti di queste applicazioni (per esempio ANTLR permette la generazione sia<br \/>\ndi codice Java che C\/C++), cosa che permette la loro integrazione in progetti<br \/>\ndi pi\u00f9 ampio respiro (vedi le applicazioni grafiche accennate prima).<br \/>\nSpero che questa breve storia dei linguaggi permetta una visione pi\u00f9 chiara<br \/>\ndel panorama attuale, e che non sia stata troppo noiosa, ma soprattutto spero<br \/>\nche piaccia ai lettori, almeno quanto \u00e8 piaciuto a me scriverla.<\/font><\/p>\n","protected":false},"excerpt":{"rendered":"<p>[&#8230;]<\/p>\n","protected":false},"author":176,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[62],"tags":[],"class_list":["post-78","post","type-post","status-publish","format-standard","hentry","category-software"],"_links":{"self":[{"href":"https:\/\/www.vialattea.net\/content\/wp-json\/wp\/v2\/posts\/78","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.vialattea.net\/content\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.vialattea.net\/content\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.vialattea.net\/content\/wp-json\/wp\/v2\/users\/176"}],"replies":[{"embeddable":true,"href":"https:\/\/www.vialattea.net\/content\/wp-json\/wp\/v2\/comments?post=78"}],"version-history":[{"count":0,"href":"https:\/\/www.vialattea.net\/content\/wp-json\/wp\/v2\/posts\/78\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.vialattea.net\/content\/wp-json\/wp\/v2\/media?parent=78"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.vialattea.net\/content\/wp-json\/wp\/v2\/categories?post=78"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.vialattea.net\/content\/wp-json\/wp\/v2\/tags?post=78"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}